Skip to content

Light-theme slabs: painted surfaces leak onto mismatched terminal grounds #29

Description

@santhreal

Summary

The TUI's surface-painting themes render unreadable, misaligned background blocks ("slabs") on terminals whose ground does not match the theme. The composer rule — no painted boxes, text on the terminal's own background — was never extended to the transcript, and the painting that exists has geometry bugs. Until this is reworked, every built-in theme except alabaster is hidden from the settings picker (VISIBLE_BUILTIN_THEMES in packages/coding-agent/src/modes/theme/theme.ts), and tui.paintGround defaults to always so alabaster stays coherent on any terminal.

The bug class (three independent sources)

  1. Gutter outside the paint. In user-message.ts, the prompt gutter is prepended outside the Markdown-painted area: the userMessageBg fill starts at the gutter width while the glyph sits in the unpainted prefix. Markdown's paddingY blank rows are also painted full-width above and below the text. Result: a half-filled, misaligned block that bleeds into neighbouring rows. Same class in tool frames (toolPendingBg / toolSuccessBg).

  2. Surface paints on mismatched grounds. Light themes paint near-white surfaces (#f5f4f5 family); the dark theme paints explicit #000000. tui.paintGround: auto only paints the theme ground when the terminal's reported background is already within tolerance 32, so on any mismatched terminal the surfaces become foreign blocks: black slabs on a #1e2127-class grey terminal, white slabs on a dark one.

  3. OSC 133 prompt-zone markers. user-message.ts emitted ESC ] 133 ; A/B around prompts for multiplexer prompt grouping. Terminals that paint prompt zones (Ghostty class) drew an uncontrolled background block over the message whose geometry veyyon does not own. Removed in the de-slab pass; covered by absence tests in user-message-gutter.test.ts / user-message-working-glow.test.ts / user-message-keywords.test.ts.

What a real fix looks like

  • Extend the composer rule to the transcript: no painted boxes anywhere — text on the terminal's own background, structure carried by glyphs, rails, and hairlines. This is the operator's stated preference and the cheapest coherent outcome.
  • If any paint survives, its geometry must be exact: gutter inside the painted area, no full-width painted padding rows, and the ground must be coherent (tui.paintGround: always or ground-relative tints that provably stay within a seam-free delta on both grey and black grounds).
  • Every fix must ship real-render proofs: off-screen rasterization on BOTH a #1e2127-class grey ground and a black ground, before/after. tmux captures are not evidence (they hide exactly this bug class).

Re-enabling the hidden themes

The 59 hidden built-ins (packages/coding-agent/src/modes/theme/defaults/) stay embedded and renderable via the gallery maintainer tool: getAvailableThemes({ includeHidden: true }) (see packages/coding-agent/src/cli/gallery-cli.ts). Unhide by widening VISIBLE_BUILTIN_THEMES once a theme provably passes the two-ground render proof.

References

  • Operator screenshots 2026-07-22 / 2026-07-23 (slack-black slabs on grey ground, white slabs on dark ground, OSC 133 zone tint on titanium).
  • docs/internal/tui-design-language.md and the composer-chrome "no painted composer box" note in packages/coding-agent/src/modes/components/composer-chrome.ts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions