Repository navigation
Description
What I hit
Running OpenCode with the oh-my-opencode plugin installed, four core agent labels render with letters missing from the visible output. The labels that should read Sisyphus: Ultraworker, Hephaestus: Deep Agent, Prometheus: Plan Builder, and Atlas: Plan Executor instead render as:
Sisyphus: ltraworkerHephaestus: Deep entPrometheus: Plan iderAtlas: Plan utor
The count of missing characters matches the agent's position in the plugin's sort order (one for Sisyphus, two for Hephaestus, three for Prometheus, four for Atlas).
How I confirmed it
I captured the raw bytes of the rendered agent line with od. The line started with:
3e 20 e2 80 8b 53 69 73 79 70 68 75 73 20 2d 20
That decodes to > space U+200B space S i s y p h u s space : space. The three bytes e2 80 8b are the UTF 8 encoding of U+200B (zero width space). The prefix is present in the string that reaches the renderer. This is not ANSI, not a color code, not cursor movement. It is an invisible codepoint, emitted as data, that OpenCode's TUI then tries to measure and truncate.
Where it reproduces
Affected labels (4 total): Sisyphus (Ultraworker), Hephaestus (Deep Agent), Prometheus (Plan Builder), Atlas (Plan Executor).
Reproduced on:
- Windows Terminal
- macOS Terminal
- The HolyCode/OpenCode browser terminal presentation
That rules out local terminal settings as the cause.
Root cause
oh-my-opencode prepends U+200B characters to the name field of each core agent. That is deliberate on OMO's side: the prefixes force a stable sort order for core agents in Agent.list(). Upstream OMO documents the contract in src/plugin-handlers/AGENTS.md and explicitly forbids removing the prefixes, because localeCompare on name is what drives list ordering.
So the string reaching the renderer is legitimate input. The problem is how the TUI measures and truncates that string. The renderer counts each U+200B as one column, even though the glyph is invisible. Width math ends up off by one, two, three, or four depending on which core agent. When the renderer then truncates to fit, it chops visible letters from the end (or start, depending on the codepath) instead of the invisible prefix.
Why I think this is a renderer concern
Per the Unicode standard, zero width codepoints like U+200B, U+200C, U+200D, and U+FEFF contribute zero columns to rendered width. Any TUI width function that treats them as one column will miscount any string that contains them. That is a general correctness issue, not OMO specific. Once the renderer handles invisible codepoints correctly, every downstream plugin that ships such characters (for sorting, for tagging, for whatever else) gets safe rendering automatically.
Related context
I have read:
#23049: Agent names displayed incorrectly with ZWSP characters in TUI. Same symptom, assigned torekram1-node.#21642: Plugin registered agent names with zero width space prefixes leak into system prompt. Related surface, different concern (prompt leak vs TUI width).#22131: [BUG] Agent label renders incorrectly with OMO: 'Deep agent' becomes 'Deep ent'. Labeledopentui.- PR
#22343:feat(opencode): add order field to agent config for explicit list sorting. Complementary architectural work on ordering. If that PR lands, OMO can migrate off ZWSP for ordering, but the renderer fix is still worth having as defense in depth for any other consumer that ships invisible codepoints.
I am opening this issue separately so I can own the fix end to end and keep framing focused on the renderer.
What I am working on
I am locating the exact renderer path in packages/opencode/src/cli/cmd/tui/ (and opentui from sst if that is where width is measured) and preparing a PR. The plan:
- Sanitize invisible codepoints at the width measurement boundary, or correct the width function itself, whichever fits the existing code best.
- Add tests that cover
U+200B,U+200C,U+200D, andU+FEFFin rendered labels. - Link the PR to this issue with
Closes #N.
I will comment with the PR number once it is open.
Activity
github-actions commentedon Apr 19, 2026
This issue might be a duplicate of existing issues. Please check:
Both issues describe the same rendering/width-measurement bug with zero-width space prefixes. Consider whether this issue adds anything beyond what's tracked there, or if it would be better to continue discussion in one of the existing threads.
github-actions commentedon Jul 3, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.