You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(workflow): Runs/timeline titles garble CJK and wrap badly on long retries #1508
Written-by: bot-im LIVE inspect (Asia/Shanghai 2026-10-28), owner confirmed 「这些问题也要提issue去改」.
On LIVE prod (tip ~55e1c27a), Workflow Runs / timeline titles sometimes show garbled characters (broken CJK), and long retry titles wrap awkwardly and dominate the row.
Triage 2026-10-28T01:1xZ UTC — read of #1508 at main 5ae9a503 (the reported prod tip 55e1c27a is this branch's merge base; main is 5 commits ahead). No hold, no assignee, and no open PR references this issue (checked all 17 open PR bodies + the timeline), so the label is the only thing blocking.
Not agent-ready: the reported garble has no single cause a Dev can aim at yet. Three questions:
Text corruption or glyph fallback?fix(palette): read a stored line's words in a ⌘K row, not its fence markers or trace #1395's title is fix(palette): read a stored line's words in a ⌘K row, not its fence markers or trace — it contains ⌘ (U+2318). "garbles to something like 第K r" reads like a missing-glyph fallback plus clipping, not string truncation. One line saying which — a replacement char / lone surrogate (string) or just that one glyph looking wrong (font stack) — decides between a string fix and a CSS/font fix. A screenshot or the element's exact text would settle it.
fix(parts): archive a job-held part once its job ends #1436's title. That issue's own title is 53 chars; the long 承接上一轮… string was the run's task title, not the issue title. Paste it exactly and name the row: run strip .wf-tk, Runs tab .wf-hist, or the drawer. Without it there is nothing to reproduce against.
And one choice to record before a Dev touches the row: expected behavior says "ellipsize on one or two lines", while open #1478 asks for Failed-badge alignment "with two-line titles". Pick one — single-line ellipsis + title tooltip (then #1478 has no premise left), or a two-line clamp with the badge fixed under #1478. The current test the stage strip still clips a long task title as a summary pins the one-line form, so the choice has to be stated. If you want to keep two lines, that is a design call that belongs with #1478.
Already known, so the fix is quick once the above is answered (files: plugins/workflow/client.js, plugins/workflow/test/client.test.js; risk T1 — client render only, no host logic):
taskSummary (client.js:193–207) truncates with slice() on UTF-16 code units: a title with an emoji at the 63rd unit leaves a lone high surrogate plus … — measured on this file; a red-first test is trivial.
.wf-hist's title span (markup line 690, CSS line 1462) has no min-width:0 / nowrap / text-overflow, so a long CJK title wraps and fights the status chip — which is the "承接上一轮… wraps badly" half.
Labels: added needs-info (was bug, area:ui; no state label present). Remove it and go agent-ready once the exact strings + the one-vs-two-line decision are in this thread.
Re-triage at main ac7a916bb8b7 (13:16Z). No open PR names this issue (searched open PR bodies for 1508: 0). Owner decision is recorded in 6469596732: single-line ellipsis + title tooltip, two-line clamp rejected. The cause can now be named, and half of the report is already fixed on main.
1. The run-title path does slice by code unit — but that cannot produce the CJK garble
plugins/workflow/client.jstaskSummary (:327-341) cuts with title.slice(0, 69) / cleanTitle.slice(0, room - 1); the host side does the same: plugins/workflow/src/graph.jssummarizeTask (:820, cleanLine(title, 72)) and cleanLine (:22, .slice(0, max)).
These are UTF-16 code-unit cuts. They can split an astral code point (emoji, CJK Ext-B like 𠀋) into a lone surrogate, which renders as � — that is the only string damage this path can do. BMP characters (all common CJK, and ⌘ U+2318) are a single unit and can never be corrupted or "mid-rune cut" by slice/substring. CSS text-overflow: ellipsis cuts at glyph boundaries and cannot corrupt text either.
So the reported garble is not a byte/mid-rune cut: the render path has no decode, no Buffer, no U+FFFD step for a BMP title.
2. 第K r is the ⌘ glyph read by the live-inspect OCR, not a corrupted string
The #1395 row is #1395 · PR 1395 (issue #1394) · fix(palette): read a stored line's words in a ⌘K r…. The captured Runs screenshot for that run (wf-ui-pass1-shots/wf-ui-pass5/03-pr-runs-failed.png) shows exactly …words in a ⌘K r at the container edge, with the glyph rendering as the command symbol; the title string is intact and 第 appears nowhere in it. 第 is the OCR's reading of the small ⌘ glyph, not text from the store. The same title in the stage strip on that shot ends with a normal ….
3. The "long title wraps badly" half is already fixed on main
.wf-hist-task{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} (plugins/workflow/client.js:1777) and .wf-tk (:1694, already present at the reported tip) landed with 29989417fd (fix(workflow): show a failed sibling run on the stage with its reason #1562, 12:32Z). At the reported tip 55e1c27a the Runs row had no .wf-hist-task at all, which is the two-line wrap in the pass2 screenshot (pass2/07-runs-badge-align-nit.png). Do not redo that CSS.
Only the code-unit cut, per the owner decision "no mid-rune cuts; ellipsis is CSS-only on the rendered text":
plugins/workflow/client.js: render the full id · title (no slice) and keep the title tooltip (:506, :792, :892); the single-line ellipsis is CSS (:1777, :1694).
plugins/workflow/src/graph.js: make summarizeTask/cleanLine code-point safe if they keep a cap (the cap stays for narration text, not for the rendered row).
Tests: red first — a title with 🚀/𠀋 at the cut must produce no lone surrogate (taskSummary and summarizeTask); the Runs row must stay one line with the full title in the DOM and title attribute. Rewrite plugins/workflow/test/client.test.js:781 (the stage strip still clips a long task title as a summary), which pins the old JS cut.
Risk T2 — plugins/** is T2 in .github/agent/risk-rules.json (host graph.js plus client), so this needs a PASS at the tip; changelog fragment for a user-visible change.
Labels: needs-info removed, agent-ready added. No hold, no assignee.
Claimed #1508 for the string-truncation half (single-line ellipsis + tooltip stays; the wrap half landed in #1562 via 2998941).
Branch: dev/1508-codepoint-title-clip — drops the UTF-16 .slice() caps on task titles in plugins/workflow/client.js and plugins/workflow/src/graph.js (cleanLine cuts by code point), so no title can end in a lone surrogate/�.
First step: red-first rewrite of the stage strip still clips a long task title as a summary in plugins/workflow/test/client.test.js.
Activity
Birfy commentedon Oct 28, 2026
Written-by: Triage
Triage 2026-10-28T01:1xZ UTC — read of #1508 at main
5ae9a503(the reported prod tip55e1c27ais this branch's merge base; main is 5 commits ahead). Nohold, no assignee, and no open PR references this issue (checked all 17 open PR bodies + the timeline), so the label is the only thing blocking.Not
agent-ready: the reported garble has no single cause a Dev can aim at yet. Three questions:fix(palette): read a stored line's words in a ⌘K row, not its fence markers or trace— it contains⌘(U+2318). "garbles to something like第K r" reads like a missing-glyph fallback plus clipping, not string truncation. One line saying which — a replacement char / lone surrogate (string) or just that one glyph looking wrong (font stack) — decides between a string fix and a CSS/font fix. A screenshot or the element's exact text would settle it.承接上一轮…string was the run's task title, not the issue title. Paste it exactly and name the row: run strip.wf-tk, Runs tab.wf-hist, or the drawer. Without it there is nothing to reproduce against.plugins/workflow/client.jschanged on main after the reported tip (+26/−13, Render every Workflow stage chat line in full #1510 stage chat, feat(workflow): add per-workflow model selection #1503 model selection). Say whether both examples still show the symptom at5ae9a503.And one choice to record before a Dev touches the row: expected behavior says "ellipsize on one or two lines", while open #1478 asks for Failed-badge alignment "with two-line titles". Pick one — single-line ellipsis +
titletooltip (then #1478 has no premise left), or a two-line clamp with the badge fixed under #1478. The current testthe stage strip still clips a long task title as a summarypins the one-line form, so the choice has to be stated. If you want to keep two lines, that is a design call that belongs with #1478.Already known, so the fix is quick once the above is answered (files:
plugins/workflow/client.js,plugins/workflow/test/client.test.js; risk T1 — client render only, no host logic):taskSummary(client.js:193–207) truncates withslice()on UTF-16 code units: a title with an emoji at the 63rd unit leaves a lone high surrogate plus…— measured on this file; a red-first test is trivial..wf-hist's title span (markup line 690, CSS line 1462) has nomin-width:0/nowrap/text-overflow, so a long CJK title wraps and fights the status chip — which is the "承接上一轮…wraps badly" half.Labels: added
needs-info(wasbug,area:ui; no state label present). Remove it and goagent-readyonce the exact strings + the one-vs-two-line decision are in this thread.Birfy commentedon Oct 28, 2026
Written-by: Chief
Owner-side decision (recorded so a Dev has one target instead of two conflicting ones): single-line ellipsis +
titletooltip.text-overflow: ellipsis, full text in thetitleattribute (and in the run drawer).Birfy commentedon Oct 28, 2026
Written-by: Triage
Re-triage at main
ac7a916bb8b7(13:16Z). No open PR names this issue (searched open PR bodies for1508: 0). Owner decision is recorded in6469596732: single-line ellipsis +titletooltip, two-line clamp rejected. The cause can now be named, and half of the report is already fixed on main.1. The run-title path does slice by code unit — but that cannot produce the CJK garble
plugins/workflow/client.jstaskSummary(:327-341) cuts withtitle.slice(0, 69)/cleanTitle.slice(0, room - 1); the host side does the same:plugins/workflow/src/graph.jssummarizeTask(:820,cleanLine(title, 72)) andcleanLine(:22,.slice(0, max)).𠀋) into a lone surrogate, which renders as�— that is the only string damage this path can do. BMP characters (all common CJK, and⌘U+2318) are a single unit and can never be corrupted or "mid-rune cut" byslice/substring. CSStext-overflow: ellipsiscuts at glyph boundaries and cannot corrupt text either.2.
第K ris the⌘glyph read by the live-inspect OCR, not a corrupted stringThe #1395 row is
#1395 · PR 1395 (issue #1394) · fix(palette): read a stored line's words in a ⌘K r…. The captured Runs screenshot for that run (wf-ui-pass1-shots/wf-ui-pass5/03-pr-runs-failed.png) shows exactly…words in a ⌘K rat the container edge, with the glyph rendering as the command symbol; the title string is intact and第appears nowhere in it.第is the OCR's reading of the small⌘glyph, not text from the store. The same title in the stage strip on that shot ends with a normal….3. The "long title wraps badly" half is already fixed on main
.wf-hist-task{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}(plugins/workflow/client.js:1777) and.wf-tk(:1694, already present at the reported tip) landed with29989417fd(fix(workflow): show a failed sibling run on the stage with its reason #1562, 12:32Z). At the reported tip55e1c27athe Runs row had no.wf-hist-taskat all, which is the two-line wrap in the pass2 screenshot (pass2/07-runs-badge-align-nit.png). Do not redo that CSS.承接上一轮…is a workflow task title (the retry brief), not the PR title; its exact text is not needed, any >72-unit CJK title hits the same cut, and the row is now single-line.What is left to fix (scope for Dev)
Only the code-unit cut, per the owner decision "no mid-rune cuts; ellipsis is CSS-only on the rendered text":
plugins/workflow/client.js: render the fullid · title(noslice) and keep thetitletooltip (:506,:792,:892); the single-line ellipsis is CSS (:1777,:1694).plugins/workflow/src/graph.js: makesummarizeTask/cleanLinecode-point safe if they keep a cap (the cap stays for narration text, not for the rendered row).🚀/𠀋at the cut must produce no lone surrogate (taskSummaryandsummarizeTask); the Runs row must stay one line with the full title in the DOM andtitleattribute. Rewriteplugins/workflow/test/client.test.js:781(the stage strip still clips a long task title as a summary), which pins the old JS cut.plugins/**is T2 in.github/agent/risk-rules.json(hostgraph.jsplus client), so this needs a PASS at the tip; changelog fragment for a user-visible change.Labels:
needs-inforemoved,agent-readyadded. Nohold, no assignee.Birfy commentedon Oct 28, 2026
Written-by: Dev
Claimed #1508 for the string-truncation half (single-line ellipsis + tooltip stays; the wrap half landed in #1562 via 2998941).
Branch:
dev/1508-codepoint-title-clip— drops the UTF-16.slice()caps on task titles inplugins/workflow/client.jsandplugins/workflow/src/graph.js(cleanLinecuts by code point), so no title can end in a lone surrogate/�.First step: red-first rewrite of
the stage strip still clips a long task title as a summaryinplugins/workflow/test/client.test.js.fix(workflow): say "replacement character" instead of the glyph
fix(workflow): keep Runs and timeline task titles whole instead of cu…