Skip to content

Terminal UI: streaming performance, auto-theme, and per-section visibility - #69

Merged
ApiliumDevTeam merged 4 commits into
devfrom
chore/tui-p2-streaming-theme-sections
Jul 13, 2026
Merged

ApiliumDevTeam merged 4 commits into
devfrom
chore/tui-p2-streaming-theme-sections

Conversation

@ApiliumDevTeam

Copy link
Copy Markdown
Collaborator

Summary

Second pass of the terminal UI redesign (P2 items from the audit roadmap). Improves streaming render performance, theme detection at startup, and user control over what is displayed. No changes to the rendering engine or the gateway protocol.

Streaming performance

  • Split streaming markdown at the last stable block boundary (a blank line outside any open code fence). The stable prefix reuses the Markdown component render cache; only the active suffix is re-parsed per delta. Turns the per-delta cost from O(n²) into O(n) on long responses.
  • New stream-boundary.ts with a pure, unit-tested findStableBoundary function.

Auto-theme detection

  • When config.ui.theme is unset or "auto", query the terminal for its dark/light preference before the first render. Uses the DSR color-scheme report (CSI ? 996 n) and OSC 11 background-color query concurrently with a 150 ms timeout each; the fastest signal wins, falling back to dark on unresponsive terminals.
  • New "auto" value in the ui.theme config type.

Per-section detail visibility

  • Replace the binary tools/thinking toggle with a three-state model: hidden, collapsed, expanded. Ctrl+O (tools) and Ctrl+T (thinking) cycle each section independently. Tools hidden renders only the header line; collapsed shows a 12-line preview; expanded shows everything.

Paste and caret

  • No-regression coverage for the grapheme-aware caret (Intl.Segmenter) and paste-collapse markers inherited from the terminal UI dependency. Welcome-screen hint updated to reflect that Ctrl+C now aborts the active run.

Test plan

  • pnpm tsgo — 0 errors
  • pnpm lint — 0 errors, 353 warnings
  • pnpm exec vitest run src/tui/ — 536 passed, 1 skipped (Windows symlink), 0 failed
  • New tests: stream-boundary (10), section-visibility (5), paste-grapheme (9), color-scheme detection (9)

When config.ui.theme is unset or set to "auto", query the terminal for
its color-scheme preference before the first render. The detection uses
two concurrent queries with a 150 ms timeout each: the DSR color-scheme
report (CSI ? 996 n, a direct dark/light answer) and the OSC 11
background-color query (parsed to RGB and classified via Rec. 709
relative luminance). The fastest signal wins; an unresponsive terminal
falls back to the default dark preset without blocking startup.

Add "auto" to the ui.theme config type so users can opt in explicitly,
and document the query ladder in term-capabilities.ts. The manual /theme
command continues to override the detected preset for the session.
Add no-regression coverage for the two input features inherited from the
terminal UI dependency: grapheme-aware caret movement (Intl.Segmenter)
and paste-collapse markers. Both are implemented in the Editor class the
TUI extends, so the tests pin the environment contract rather than the
Editor internals.

The grapheme tests verify that emoji with skin-tone modifiers, flag
emoji, and CJK characters each count as a single grapheme — the
invariant the caret relies on. The paste-marker tests verify the marker
shape ([paste #N +M lines], [paste #N M chars], [paste #N]) so that
cursor movement and submission expansion keep working if the format
changes upstream.

Also update the welcome-screen quick-start hint to reflect that Ctrl+C
now aborts the active run (Esc remains a secondary path).
Re-parsing the full markdown on every streaming delta is O(n²) over a
response. Split the assistant message text at the last stable block
boundary (a blank line outside any open code fence) into a stable prefix
and an active suffix. Only the suffix is re-parsed per delta; the prefix
reuses the Markdown component's internal render cache, which turns the
per-delta cost into O(n).

Add stream-boundary.ts with a pure, unit-tested findStableBoundary
function that walks backwards through blank lines and skips any that
sit inside an open code fence. Refactor AssistantMessageComponent to
hold two Markdown instances (prefix + suffix) and only update the
prefix when its text actually grows.
Replace the binary expanded/collapsed toggle with a three-state model:
hidden, collapsed, and expanded. Each section cycles independently via
its keyboard shortcut.

- Tools (Ctrl+O): hidden renders only the header line, collapsed shows a
  12-line preview, expanded shows the full output.
- Thinking (Ctrl+T): hidden suppresses thinking text, collapsed and
  expanded both show it (a truncated thinking mode is deferred to a
  follow-up that restructures the composer).

The section state is the new source of truth in TuiStateAccess; the
existing toolsExpanded and showThinking fields are kept as compatibility
shims. Add a nextSectionState helper and unit tests for the cycle.
@ApiliumDevTeam
ApiliumDevTeam merged commit 4e7527d into dev Jul 13, 2026
4 checks passed
@ApiliumDevTeam
ApiliumDevTeam deleted the chore/tui-p2-streaming-theme-sections branch July 13, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant