Skip to content

TUI recovery states

P4 applies the empty-state and notice recipes using the generated lipgloss roles. Conditions have one bold row, explanation and the next action use body ink, and empty rail sections reserve no rows.

These are deterministic app-model driver captures, not recordings of a live daemon. app/recovery_test.go drives the real home.Update and home.View paths, injects rejected mutations, and checks that session and task input survives. The SVGs faithfully convert the resulting ANSI cell grid. Matching SVG and ANSI goldens in app/testdata/recovery are both compared byte-for-byte by TestRecoveryDriverScenes, making geometry, copy, weight, colour and terminal escape sequences reviewable in tests. The 14 scenes in both themes have 28 .svg/.ansi pairs. Existing surrounding TUI chrome is outside P4. The same test also requires every gallery .svg and .ansi under docs/assets/recovery/tui-model-driver to match its asserted golden byte-for-byte. The zero-task and task-load-failure scenes keep the task manager's Tasks title and a pinned n new · esc back hint containing only live actions.

State Light Dark
Zero sessions Zero sessions, light Zero sessions, dark
No project registered No project registered, light No project registered, dark
Zero tasks Zero tasks, light Zero tasks, dark
Zero accounts Zero accounts, light Zero accounts, dark
Remote accounts; login refused Remote accounts, light Remote accounts, dark
Tasks unavailable Tasks unavailable, light Tasks unavailable, dark
Projects unavailable Projects unavailable, light Projects unavailable, dark
Cannot reach the daemon Cannot reach the daemon, light Cannot reach the daemon, dark
Failed session create Failed session create, light Failed session create, dark
Failed archive Failed archive, light Failed archive, dark
Failed kill Failed kill, light Failed kill, dark
Failed task save Failed task save, light Failed task save, dark
Failed existing task save Failed existing task save, light Failed existing task save, dark
Too-small terminal Too-small terminal, light Too-small terminal, dark

The complementary real tmux driver runs inside the isolated testbox with a cheap bash stand-in. It starts with no sessions, opens the empty task manager, submits a create rejected by the real daemon, verifies the name remains in the form, changes its backend, and reaches a live interactive terminal with FIRST_SESSION_REACHED echoed. It then checks the too-small-terminal screen. Its captured terminal text is real application evidence; it does not assert agent authentication or agent responses. No host AF home, daemon, app process or account is used.

Mutation recovery screens persist until one key returns to the retained state; the key is consumed so dismissing a failure cannot accidentally submit or delete. An async create failure while another form is open preserves that newer form and retains the failed draft for the next create in its original project. Background snapshot failures retain loaded sessions and retry automatically.

To verify, run scripts/testbox.sh test ./app -run 'TestRecovery' -count=1 and scripts/testbox.sh scenario scripts/tui-3915-scenario.sh. To recapture, set AF_TUI_RECOVERY_CAPTURE to an output directory inside the testbox and run the recovery tests. Capture mode writes both <scene>-<theme>.svg and <scene>-<theme>.ansi and skips golden comparisons. Inspect every SVG and ANSI diff before replacing both halves together under app/testdata/recovery. Both the SVG and ANSI gallery copies are generated from those goldens by scripts/gen-docs.sh and gated for drift in CI, so run that script and commit its output rather than copying either format across by hand. The test rejects a stale or missing gallery copy in either format. Keep the .gitattributes ANSI whitespace rule: cell padding and trailing viewport rows are part of the asserted frame. Verify again without AF_TUI_RECOVERY_CAPTURE so the test checks the committed pairs.