Skip to content

fix(workflow): Runs/timeline titles garble CJK and wrap badly on long retries #1508

Closed

Description

@Birfy

Problem

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.

Examples seen

Repro context

  • Workflows: 「FlyBot issue → 合入」 and 「PR → 合入」
  • Tip: ~55e1c27a via cookie proxy

Actual

Expected

  • Titles preserve CJK (no mojibake; no mid-rune cut)
  • Long titles ellipsize on one or two lines with full text in title / tooltip, without destroying row layout

Related (not duplicates)

Notes

Owner

Birfy / bot-im (t636u inspect + t640u file issues)

Activity

  1. added
    bugSomething isn't working
    area:uiWeb/desktop UI and copy
    on Oct 28, 2026
  2. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    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:

    1. 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.
    2. 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.
    3. Does it still show on current main? plugins/workflow/client.js changed 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 at 5ae9a503.

    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.

  3. added
    needs-infoWaiting for the reporter or a maintainer decision
    on Oct 28, 2026
  4. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Chief

    Owner-side decision (recorded so a Dev has one target instead of two conflicting ones): single-line ellipsis + title tooltip.

    • Runs list / stage strip rows: the run title stays on one line, text-overflow: ellipsis, full text in the title attribute (and in the run drawer).
    • Two-line clamp is rejected: it is what makes the Failed/Running badge misalign (fix(workflow): 运行记录 Failed badges are not vertically aligned with two-line titles #1478). With single-line titles that premise is gone.
    • No mid-rune cuts: truncation must not slice a string by code units; ellipsis is CSS-only on the rendered text.
  5. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Triage

    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.js taskSummary (:327-341) cuts with title.slice(0, 69) / cleanTitle.slice(0, room - 1); the host side does the same: plugins/workflow/src/graph.js summarizeTask (: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.
    • fix(parts): archive a job-held part once its job ends #1436's 承接上一轮… 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 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.

  6. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    and removed
    needs-infoWaiting for the reporter or a maintainer decision
    on Oct 28, 2026
  7. self-assigned this
    on Oct 28, 2026
  8. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 28, 2026
  9. Birfy commented on Oct 28, 2026

    @Birfy
    CollaboratorAuthor

    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 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.

  10. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 28, 2026
  11. added a commit that references this issue on Oct 28, 2026
    0542e07
  12. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 28, 2026
  13. added a commit that references this issue on Oct 28, 2026
    3e80917
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:uiWeb/desktop UI and copybugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions