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 | ||
| accounts | ||
| archive failed | ||
| config | ||
| confirmation | ||
| create failed | ||
| help | ||
| hooks | ||
| keyboard | ||
| kill failed | ||
| no daemon | ||
| no project | ||
| pane | ||
| preview | ||
| project picker | ||
| projects unavailable | ||
| prompt | ||
| search | ||
| selection | ||
| sessions | ||
| task create | ||
| task edit save failed | ||
| task save failed | ||
| tasks | ||
| tasks unavailable | ||
| too small | ||
| zero accounts | ||
| zero sessions | ||
| zero tasks | ||
| Alarm | ||
| task schedule | ||
| task weekdays | ||
| task-trigger | ||
| task-program | ||
| task-schedule-type | ||
| hooks-edit | ||
| hooks-add | ||
| rail-task-selection | ||
| rail-project-selection | ||
| notice | ||
| failure-notice | ||
| project-picker-existing | ||
| config-edit | ||
| account-register | ||
| task-weekdays-unchecked | ||
| search-overflow | ||
| selection-overflow | ||
| project-picker-overflow |