Skip to content

FE-1115: Refine Pi TUI component DX: preview harness, component refinements, and new components#301

Merged
lunelson merged 16 commits into
nextfrom
ln/fe-1115-tui-refinements-1
Jul 8, 2026
Merged

FE-1115: Refine Pi TUI component DX: preview harness, component refinements, and new components#301
lunelson merged 16 commits into
nextfrom
ln/fe-1115-tui-refinements-1

Conversation

@lunelson

@lunelson lunelson commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

The TUI-refinement lane of FE-1115: makes the component preview harness a real theme-iteration loop, fixes kitty-protocol input handling across production components, and lands the reworked Brunch theme pair.

  • Live dark/light theme toggle (ctrl+t) in dev:components, including while an entry is open — a delegating SwitchableComponentPreviewTheme, with OSC 10/11 page fg/bg painting (OSC 110/111 restore) and an SGR-level fallback terminal wrapper for OSC-ignoring terminals (Zed)
  • Theme-JSON hot reload (fs.watch, last-good palette on invalid JSON) plus a theme-testbed entry rendering pi's assistant markdown surface, brunch's exchange markdown surface, and a fg/bg contrast strip
  • matchesKey sweep: all handleInput raw-byte comparisons in src/.pi/components/ (and the harness) now match through pi-tui's matchesKey, fixing frozen pickers under the kitty keyboard protocol (Ghostty); regression tests added, convention recorded in the components TOPOLOGY
  • Scrollback-safe working indicator: static ≤1-frame ● Working… glyph (no spinner interval, no scroll-snap) with liveness moved to OSC 9;4 terminal progress
  • Theme value rework: fuchsia accent / apricot-burntOrange secondary, text: "" terminal-default convention with concrete ink moved to the ink var, neutral reference page anchors (export.pageBg/pageFg), and a final contrast pass — all fg text tokens ≥ 4.5:1 against their reference page (faint-by-design borderMuted/thinkingOff excepted)

Also carried on this branch: planning for the follow-on FE-1164 (SPEC D116-L one-shot ask terminal, PLAN admission, scope card) — implementation stacks on the child branch.

Verification

  • Full npm run verify green at tip (1517 passed / 2 skipped)
  • Outer manual checks done 2026-07-07 (Ghostty): gallery + deep-link ctrl+t, testbed contrast read, live-session static indicator with scrollback hold

@lunelson lunelson changed the base branch from ln/fe-1159-alpha-release to graphite-base/301 July 7, 2026 15:57
@lunelson lunelson force-pushed the ln/fe-1115-tui-refinements-1 branch from f299553 to 0e5820f Compare July 7, 2026 15:59
@lunelson lunelson changed the base branch from graphite-base/301 to ln/fe-1159-alpha-release July 7, 2026 15:59
@lunelson lunelson changed the base branch from ln/fe-1159-alpha-release to graphite-base/301 July 7, 2026 16:01
@lunelson lunelson force-pushed the ln/fe-1115-tui-refinements-1 branch from 0e5820f to 7a30b1f Compare July 7, 2026 16:03
@lunelson lunelson changed the base branch from graphite-base/301 to ln/fe-1159-alpha-release July 7, 2026 16:03
@lunelson lunelson changed the base branch from ln/fe-1159-alpha-release to graphite-base/301 July 7, 2026 16:36
@lunelson lunelson changed the title FE-1115: Add live dark/light theme toggle to component preview harness FE-1115: Refine Pi TUI component DX: preview harness, component refinements, and new components Jul 7, 2026
@lunelson lunelson marked this pull request as ready for review July 8, 2026 09:04
Copilot AI review requested due to automatic review settings July 8, 2026 09:04
@cursor

cursor Bot commented Jul 8, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
User-facing TUI input, working-indicator behavior, and default terminal progress settings affect every interactive session; changes are localized to presentation/settings with broad test coverage but warrant manual terminal smoke (already noted in PR).

Overview
TUI refinement (FE-1115): The component preview harness now loads shipped brunch-{dark,light}.json, supports ctrl+t dark/light toggle while any entry is open, hot-reloads theme JSON (last-good palette on bad saves), and adds a theme-testbed entry (pi assistant vs exchange markdown + contrast strip). Terminal painting uses OSC 10/11 with an SGR fallback wrapper for OSC-ignoring terminals.

Production input: All .pi/components (and harness) handleInput paths switch from raw byte checks to pi-tui matchesKey/Key, with kitty-encoding regression tests—fixes pickers that froze in Ghostty/kitty.

Live session chrome: Working indicator becomes a single static frame on session_start (no spinner interval → scrollback stays put); showTerminalProgress is enabled in sealed Pi settings for OSC 9;4 liveness instead.

Themes: Reworked dark/light palettes (fuchsia accent, text: "" + ink, neutral export.pageBg/pageFg, contrast-oriented syntax tokens).

Docs-only on branch: PLAN/SPEC updates and the exchange-ask-refinement scope card (D116-L / FE-1164); removal of the completed orchestrator-tool-port card file; trivial package-lock.json bin path tweak.

Reviewed by Cursor Bugbot for commit fcbd45b. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines Brunch’s Pi TUI developer experience and production keyboard handling by making the component preview harness a live theme-iteration loop (toggle + hot reload + testbed), standardizing key handling via matchesKey to fix kitty-protocol regressions, and improving long-session UX with a scrollback-safe working indicator plus terminal progress.

Changes:

  • Add a switchable component-preview theme with live ctrl+t toggle, OSC 10/11 painting + SGR fallback, and fs.watch hot reload of src/.pi/themes/*.json.
  • Sweep .pi/components handleInput implementations to use matchesKey/Key (with regression tests) to avoid kitty keyboard protocol freezes.
  • Make working indication scrollback-safe (static glyph) and enable OSC 9;4 terminal-native progress by default.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/dev/TOPOLOGY.md Updates dev harness topology docs for switchable theme, hot reload, and testbed entry
src/dev/component-preview/theme.ts Implements switchable preview theme, OSC painting, SGR fallback terminal wrapper, and theme JSON watcher
src/dev/component-preview/theme-testbed.ts Adds markdown/syntax/contrast “theme testbed” component for preview harness iteration
src/dev/component-preview/registry.ts Registers the new theme-testbed preview entry
src/dev/component-preview/gallery-component.ts Switches gallery input handling to matchesKey and displays current theme variant hint
src/dev/component-preview/tests/theme.test.ts Adds tests for switchable theme, toggle consumption, and SGR fallback painting
src/dev/component-preview/tests/theme-testbed.test.ts Adds tests for theme testbed rendering and delegated theme updates
src/dev/component-preview.ts Wires preview harness to use switchable theme + terminal painting + hot reload + toggle registration/disposal
src/app/pi-settings.ts Enables terminal-native progress by default in the sealed settings policy
src/app/tests/brunch-tui.test.ts Updates expectations for showTerminalProgress default and hostile-settings override
src/.pi/themes/brunch-light.json Reworks light theme tokens/vars (accent, ink/text convention, syntax tokens, page bg)
src/.pi/themes/brunch-dark.json Reworks dark theme tokens/vars (accent, ink/text convention, syntax tokens, page bg)
src/.pi/extensions/chrome/index.ts Sets a static ≤1-frame working indicator on session_start to avoid scroll-snapping
src/.pi/extensions/tests/chrome.test.ts Adds/updates tests asserting the scrollback-safe working indicator call occurs
src/.pi/components/workspace-dialog/component.ts Migrates ctrl+c handling to matchesKey(Key.ctrl('c'))
src/.pi/components/tui-lab/style-lab-component.ts Migrates navigation/escape handling to matchesKey
src/.pi/components/TOPOLOGY.md Documents the matchesKey convention for all component input handling
src/.pi/components/runtime-posture/axis-picker.ts Migrates picker key handling to matchesKey/Key
src/.pi/components/multi-choice-picker.ts Migrates picker key handling to matchesKey/Key
src/.pi/components/exchange-decision-picker.ts Migrates picker key handling to matchesKey/Key
src/.pi/components/exchange-answer-editor.ts Migrates escape/ctrl+c/ctrl+g handling to matchesKey/Key
src/.pi/components/tests/runtime-posture-axis-picker.test.ts Adds kitty-protocol regression coverage for navigation/commit
src/.pi/components/tests/exchange-decision-picker.test.ts Adds kitty-protocol regression coverage for decision + multi-choice pickers
package-lock.json Adjusts a bin path entry for pi-ai
memory/SPEC.md Adds/extends decision and lexicon entries around the follow-on “ask” refinement lane (D116-L / A39-L)
memory/PLAN.md Updates plan/frontier definitions and adds the exchange-ask refinement lane notes
memory/cards/orchestrator-tool-port--executor-surface-reconciliation.md Deletes a completed scope card file
memory/cards/exchange-ask-refinement--ask-terminal.md Adds a new active scope card describing the ask-refinement slice plan

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/dev/TOPOLOGY.md Outdated
Comment thread src/dev/component-preview/__tests__/theme.test.ts Outdated
Comment thread src/dev/component-preview/__tests__/theme-testbed.test.ts
Copilot AI review requested due to automatic review settings July 8, 2026 10:43
@lunelson lunelson force-pushed the ln/fe-1115-tui-refinements-1 branch from 7a30b1f to a9b403d Compare July 8, 2026 10:43
@lunelson lunelson changed the base branch from graphite-base/301 to ln/fe-1159-alpha-release July 8, 2026 10:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 28 changed files in this pull request and generated 3 comments.

Comment thread src/dev/TOPOLOGY.md Outdated
Comment thread src/dev/component-preview/__tests__/theme.test.ts Outdated
Comment thread src/dev/component-preview/theme.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.

Comment thread src/dev/component-preview/theme.ts
Base automatically changed from ln/fe-1159-alpha-release to next July 8, 2026 11:41
lunelson and others added 5 commits July 8, 2026 11:42
SwitchableComponentPreviewTheme (a real Theme subclass delegating all color
reads to the active variant) plus a consuming ctrl+t TUI input listener let
the gallery and any open entry reskin in place — no retheme contract on
components. BRUNCH_PREVIEW_THEME still picks the initial variant.

Co-authored-by: Cursor <cursoragent@cursor.com>
Theme colors only style glyphs, so toggling to light left the terminal's
dark background behind them. The toggle (and registration) now sets the
terminal background via OSC 11 to the variant's export.pageBg from the
theme JSON, and the dispose path restores the terminal default via OSC 111
before the TUI stops.

Co-authored-by: Cursor <cursoragent@cursor.com>
ProcessTerminal negotiates the kitty keyboard protocol where supported
(Ghostty), and keys then arrive as CSI-u sequences that raw byte equality
misses — the gallery could not move its selection and ctrl+t never matched.
Gallery navigation and the theme toggle now go through pi-tui's matchesKey,
with an explicit key-release guard on the toggle listener (input listeners
run before the TUI's release filter). OSC 11 terminal-support limit (Zed)
recorded as a ceiling.

Co-authored-by: Cursor <cursoragent@cursor.com>
The kitty keyboard protocol (negotiated by ProcessTerminal in Ghostty and
kitty) encodes key presses as CSI-u sequences, so every handleInput doing
raw byte comparison froze there: axis-picker left/right, decision-picker
and multi-choice up/down, answer-editor esc/ctrl+c, workspace-dialog
ctrl+c, and the tui-lab reference component. All now match through
pi-tui's matchesKey/Key, with Ghostty-regression tests per navigation
family and the convention recorded in the components TOPOLOGY.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ntax testbed

watchComponentPreviewTheme rebuilds the variant palettes when
src/.pi/themes/brunch-*.json change on disk (debounced, last-good palette
across mid-edit invalid JSON), so theme values iterate against the live
harness. The new theme-testbed gallery entry renders one fixture through
both live markdown surfaces — pi's assistant theme with real highlight.js
syntax-token colors (via pi's registered global theme symbol and a bound
facade over the delegating preview theme) and brunch's exchange theme —
plus a fg/bg contrast strip for the gray-ramp work.

Co-authored-by: Cursor <cursoragent@cursor.com>
lunelson and others added 11 commits July 8, 2026 11:42
Unstyled component text — markdown body, picker labels, anything not
wrapped in theme.fg(...) — was falling through to the terminal's own
default foreground, so the text token appeared to do nothing outside the
gallery menu. The harness now paints OSC 10 with the active variant's
text hex alongside the OSC 11 page background on registration, toggle,
and hot reload, and restores both defaults (OSC 110/111) on exit.

Co-authored-by: Cursor <cursoragent@cursor.com>
…d it from export.pageFg

createThemePaintingTerminal wraps the harness Terminal for emulators that
ignore OSC 10/11 (Zed): frame writes are prefixed with the reference page
fg/bg and default-reset codes are rewritten to that base, so erases and
resets stay on the theme's page. The reference colors now come from a
Brunch-only export.pageFg extension (plus export.pageBg) instead of the
text token, because pi's format defines text as default text with the
canonical value "" (terminal default) — the JSONs adopt that convention
and keep concrete ink only for themed-surface slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
…d derivatives

PLAN now reflects the re-activated component-dx TUI-refinement lane (Cards
1-3 done, Card 4 theme values in flight), the FE-1107 residue carried
forward from the retired 2026-07-06 handoff (KA conversation + owed
post-KA ln-plan pass), and the retained-unconfirmed FE-1154 plan-projection
card. Deleted the exhausted FE-1107 executor-surface-reconciliation scope
file and the reconciled HANDOFF.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
Pi's default working spinner re-renders every 80ms, and each write snaps
scroll-on-output terminals back to the bottom — worst during long silent
stretches when the spinner is the only writer. The chrome extension now
sets a single static frame at session_start (Loader starts no animation
interval for <=1 frame, so zero periodic writes), and liveness moves to
the terminal-native OSC 9;4 progress channel via showTerminalProgress in
the sealed settings policy (hostile fixture flipped to keep seal leakage
detectable). Also: the harness reference environment fg now defaults in
code, since pi's theme schema strips the unknown export.pageFg key.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ge refinement

Co-authored-by: Cursor <cursoragent@cursor.com>
…d, manual checks recorded

Co-authored-by: Cursor <cursoragent@cursor.com>
…refinement, retire consumed handoff

Co-authored-by: Cursor <cursoragent@cursor.com>
…tover, declared continuations)

Co-authored-by: Cursor <cursoragent@cursor.com>
… isolate the pi theme global in tests, fix OSC 10 prose drift

Semantic #RRGGBB validation in parseBrunchThemePalette (post-vars-resolution,
so dangling var references fail too) makes reload's throw-based last-good
fallback fire on valid-JSON bad-value saves instead of emitting malformed
OSC/SGR. The theme-testbed test now saves/restores pi's registered theme
global around each test. TOPOLOGY.md and the theme test comment describe
OSC 10 as painting export.pageFg, matching the implementation.

Co-authored-by: Cursor <cursoragent@cursor.com>
… noted

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings July 8, 2026 11:42
@lunelson lunelson force-pushed the ln/fe-1115-tui-refinements-1 branch from ed755a8 to fcbd45b Compare July 8, 2026 11:42
@graphite-app

graphite-app Bot commented Jul 8, 2026

Copy link
Copy Markdown

Merge activity

  • Jul 8, 11:42 AM UTC: Graphite rebased this pull request, because this pull request is set to merge when ready.

@lunelson lunelson merged commit 7030fc2 into next Jul 8, 2026
7 checks passed
@lunelson lunelson deleted the ln/fe-1115-tui-refinements-1 branch July 8, 2026 11:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 27 out of 28 changed files in this pull request and generated 1 comment.

Comment thread src/dev/component-preview/theme.ts
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.

2 participants