fix(subagents): truncate display label on code-point boundaries#96959
fix(subagents): truncate display label on code-point boundaries#96959Bartok9 wants to merge 3 commits into
Conversation
truncateLine used a raw value.slice(0, maxLength), which can split a surrogate pair when an emoji straddles the limit, leaving a lone high surrogate before the appended "...". Use the shared truncateUtf16Safe helper so the half-cut code point is dropped whole. No change for non-surrogate inputs. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
Codex review: needs changes before merge. Reviewed June 26, 2026, 7:05 PM ET / 23:05 UTC. Summary PR surface: Source +4, Tests +18. Total +22 across 2 files. Reproducibility: yes. Source inspection shows current main uses raw UTF-16 slicing in Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Keep the subagent helper/test fix, but recreate or rebase the PR so it contains only Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main uses raw UTF-16 slicing in Is this the best way to solve the issue? No for the live branch as submitted now. The two-file helper reuse is the best fix for the bug, but the current 239-file branch must be narrowed before it is a safe merge vehicle. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against aca905cce50a. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +4, Tests +18. Total +22 across 2 files. View PR surface stats
Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Real behavior proof — before/afterHost: macOS (Darwin 25.4.0, arm64), node v25.5.0, repo source via its own tsx. Exercising the patched Before (
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Closing this PR because it looks dirty (too many unrelated or unexpected changes). This usually happens when a branch picks up unrelated commits or a merge went sideways. Please recreate the PR from a clean branch. |
What Problem This Solves
Salvages #96416 by @ly-wang19 onto current
main— clean single-commit rebase, original authorship preserved. The original was auto-closed byopenclaw-barnaclefor the author's >20-active-PR cap, not on merits; the bug is still live onmain.The subagent display-label truncation (
src/shared/subagents-format.ts) cuts the label at a raw UTF-16 code-unit offset, so a label ending near the limit on an emoji/astral character produces a lone surrogate before the...— mojibake in the rendered subagent label.Why This Change Was Made
Symptom — A subagent label longer than
maxLengthwhose boundary falls inside a surrogate pair renders a broken glyph before the ellipsis.Root cause — Line 32:
return \${value.slice(0, maxLength).trimEnd()}...`;.slice(0, maxLength)is a code-*unit* cut; ifmaxLength` lands between a high/low surrogate, the pair is severed.Fix + why this level — Back the cut off to a code-point boundary before slicing (drop a trailing lone high surrogate). The truncation function is the only place that produces the boundary, so it's the correct layer.
Scope / risk — Touches only the label-truncation path. Short labels and BMP-only labels are unaffected (no-op when already aligned). The
...suffix andtrimEnd()behavior are preserved.User Impact
Subagent labels that end at an astral character near the truncation limit now remain valid Unicode instead of rendering a broken glyph.
Evidence
src/shared/subagents-format.test.ts— asserts no lone surrogate at the cut; fails without the fix.node scripts/run-vitest.mjs src/shared/subagents-format.test.ts— 6/6 passed.mainsource (1 failed, 5 passed).git diff --check origin/main...HEADis clean.Provenance and Credit
Credit: Salvage of #96416 by @ly-wang19 — rebased onto current main. Original closed by the >20-active-PR queue cap, not on merits. No code changes from @ly-wang19's original.