Skip to content

TUI design system: slice A

The gallery files were regenerated from master after P2/P5 for #3917. The slice history below records the original implementation; the images now show the final design.

Slice A applies the fixed generated light/dark roles throughout the TUI and removes the private Config/account ANSI palette and raw overlay backdrop colours. theme.Roles() and theme.Styles() expose typed fields. The source guard in ui/theme/literals_test.go rejects production colour constructors, adaptive palette definitions, hex strings and raw extended SGR colour values under ui/ and app/; PTY parser test inputs and generated SVG fixtures are not chrome. The all-role SGR test checks foreground and background in both themes within one channel step of the tokens, documenting termenv's float truncation tracked in termenv #217; the web remains exact. Legacy palette input no longer changes TUI colours. Slice B owns the shared overlay recipe and density/copy cuts; slice C owns Light/Dark/System selection and migration. To meet the stricter 480 ms frame requirement, the sidebar measures rows through the viewport after its selection/scroll anchor and defers styling the unreachable suffix. Existing scrolling and cell geometry stay the same; the container model goldens pass without recapture for this optimization. Shared daemon config retirement is tracked in #3936, with the boundary contract.

Capture provenance

These 96 stills are deterministic real app-model Update/View output, converted from ANSI cells by P4's SVG writer. They are not live-daemon screen recordings. TestDesignDriverScenes adds thirty-five chrome scenes to P4's thirteen recovery scenes. Both run only in the isolated sandbox created by make playtest-container-detached; no host TUI, app tests or daemon tests run. The supplementary P4 live tmux scenario passed retained failed creation, backend recovery, first attached stand-in terminal and the tiny-terminal state. Its captured text does not claim real agent authentication or agent responses.

Reproduce with the existing make harness and the unique sandbox name it prints:

make playtest-container-detached
# Inside that sandbox, with /src as cwd:
AF_TUI_DESIGN_CAPTURE=/home/dev/sandbox/p5-design \
AF_TUI_RECOVERY_CAPTURE=/home/dev/sandbox/p5-recovery \
/usr/local/go/bin/go test ./app -run 'Test(Recovery|DesignDriverScenes)' -count=1
bash /src/scripts/tui-3915-scenario.sh

Copy the capture directories out of that sandbox, inspect the SVGs in both palettes, and update the matching app/testdata/design / app/testdata/recovery goldens. Without capture environment variables, tests compare the actual output to those goldens. Keep captured ANSI beside the gallery for source inspection.

Codex review corrections

Search results now use Lost, Dead and Archived roles; Config key and account selections use Ink on SurfaceRaised. The blurred sidebar title uses Surface on InkMuted, with a 4.5:1 contrast gate in both palettes. Regression tests pin these role assignments. Only the affected accounts, config, zero-accounts, search, pane, keyboard and preview SVG/ANSI pairs were refreshed in the make-created playtest sandbox; all 96 driver goldens pass. The search fixture now includes lost, dead and archived results.

The final whole-PR role audit records every changed file, role pair and staged B/C boundary. It additionally fixes blank working/in-flight search cells, archive-failure Dead text, muted Config location, retained selection ink and token-only placeholder contrast. The fourth-round sweep of all style constructions also separates Accent selection markers from Ink labels and gives input carets the validated Surface-on-Accent pair. Refreshed both-theme captures cover search, selection, project picker, hooks, tasks, config/accounts and zero-accounts; new trigger, program and schedule-type scenes expose focused field markers. Search hit regions now use render-plan positions, with a regression test for session titles identical to scroll indicators.

The fifth-round state mapping enumeration checks liveness, in-flight operations, operator kind, selection/focus/blur, edit/add modes, warnings and diagnostics. Its source branch inventory includes compact fallbacks. Hook edit/add fields now use the raised surface; search selection includes state cells; unselected task metadata is muted. The audit also fixes Config/account and rail selection gaps, selected project counts, project markers that reused Ready’s glyph, and failure notice colours. New both-theme scenes cover these transitions. Remaining B recipes are listed explicitly in the enumeration rather than counted as completed A work.

The focused weekday retains its checked value: checked days use [M]-style labels, unchecked days keep the plain letter. Both occupy three cells; focus keeps the same raised/underlined treatment. TrueColor and ASCII regressions cover the toggle in both palettes, with separate checked/unchecked stills.

Search and both pickers use InkMuted for overflow indicators, while selectable labels retain Ink. Separate scrolled scenes show both directions; regression coverage includes compact/normal geometry and both themes.

Performance and verification

One make perf-container pass at 1,000 sessions verified the Codex corrections on top of the gate update at 5c2637fa. Full frame averaged 62.555 ms (range 48.318–69.715); key-to-render averaged 65.651 ms (59.161–77.491). Every sample meets P5's stricter 480 / 351 ms limits. The harness still reports P1's original looser CI ceilings; these are not the thresholds used to accept P5. Raw samples and the complete report preserve the evidence. Before deferring invisible rows, this slice averaged 498.625 / 247.484 ms; those samples motivated the viewport change. No baseline or budget was relaxed.

All required formatting, build, vet, fast lint, file-length and theme drift checks passed, as did changed UI/doctor/design-generator package tests. The full app package passed inside the make-created playtest sandbox. Full diff and all stills were self-reviewed before requesting review.

Stills

Scene Light Dark
archive warning archive warning, light archive warning, dark
accounts accounts, light accounts, dark
archive failed archive-failed, light archive-failed, dark
config config, light config, dark
confirmation confirmation, light confirmation, dark
create failed create-failed, light create-failed, dark
help help, light help, dark
hooks hooks, light hooks, dark
keyboard keyboard, light keyboard, dark
kill failed kill-failed, light kill-failed, dark
no daemon no-daemon, light no-daemon, dark
no project no-project, light no-project, dark
pane pane, light pane, dark
preview preview, light preview, dark
project picker project-picker, light project-picker, dark
projects unavailable projects-unavailable, light projects-unavailable, dark
prompt prompt, light prompt, dark
search search, light search, dark
selection selection, light selection, dark
sessions sessions, light sessions, dark
task create task-create, light task-create, dark
task edit save failed task-edit-save-failed, light task-edit-save-failed, dark
task save failed task-save-failed, light task-save-failed, dark
tasks tasks, light tasks, dark
tasks unavailable tasks-unavailable, light tasks-unavailable, dark
too small too-small, light too-small, dark
zero accounts zero-accounts, light zero-accounts, dark
zero sessions zero-sessions, light zero-sessions, dark
zero tasks zero-tasks, light zero-tasks, dark
Alarm Alarm, light Alarm, dark
task schedule task schedule light task schedule dark
task weekdays task weekdays light task weekdays dark
task-trigger task-trigger light task-trigger dark
task-program task-program light task-program dark
task-schedule-type task-schedule-type light task-schedule-type dark
hooks-edit hooks-edit light hooks-edit dark
hooks-add hooks-add light hooks-add dark
rail-task-selection rail-task-selection light rail-task-selection dark
rail-project-selection rail-project-selection light rail-project-selection dark
notice notice light notice dark
failure-notice failure-notice light failure-notice dark
project-picker-existing project-picker-existing light project-picker-existing dark
config-edit config-edit light config-edit dark
account-register account-register light account-register dark
task-weekdays-unchecked Unchecked weekday light Unchecked weekday dark
search-overflow search-overflow light search-overflow dark
selection-overflow selection-overflow light selection-overflow dark
project-picker-overflow project-picker-overflow light project-picker-overflow dark