返回 CodeWhale
AGENTS.md
根目录 / crates / tui / AGENTS.md
1 # crates/tui — agent guidance
2
3 Scope: the TUI, the runtime engine embedded in it, and everything a user sees.
4 Read the repo-root `AGENTS.md` first. Current flakes and known debt are in
5 `docs/ops/CURRENT.md`, not here.
6
7 ## The shell grammar (do not regress it)
8
9 The default shell is the underwater system (`src/tui/underwater.rs`, `ocean.rs`,
10 `widgets/`, `views/`). Its contract:
11
12 - **One owner per fact.** Route/mode/permission/context live in the header;
13 Tasks/To-do in the top strip; receipts and the single live row in the
14 transcript; phase/cost/detail keys in the footer. Never restate a fact in a
15 second place.
16 - **One live row.** Settled receipts are still; only the active row and the
17 footer phase mark move. Decorative motion exists only in empty idle water and
18 stops the instant the user types or anything needs attention.
19 - **Phase is typed.** `ShellPhase::from_app` derives idle/typing/working/
20 waiting/approval/done/failed from real app state. Never invent state in a
21 renderer; never compare English strings to detect state — use the enums.
22 - **Treatment is typed.** `OceanTreatment` (ombre/flat/classic) parses once from
23 settings. Every treatment keeps ambient life; appearance and motion
24 (`low_motion`, `fancy_animations`) are independent axes.
25 - **Footer notices go through the toast system** (`push_status_toast` /
26 `active_status_toast`), never the legacy `status_message` sink: toasts carry
27 level + TTL, errors hold sticky, acknowledgements expire.
28 - **Compact tiers shed chrome, not content.** At small sizes a room drops
29 titles/captions/spacers before the object the user opened it to manipulate,
30 and bodies budget from the footer's *wrapped* height (`wrapped_footer_lines` /
31 `action_footer_lines`).
32 - **Rows are objects.** Anything selectable has a hitbox recorded at render
33 time, keyboard + mouse parity, and visible focus. Destructive controls arm
34 before they fire.
35
36 ## Localization
37
38 Every user-visible string goes through `tr(locale, MessageId::…)` — no hardcoded
39 English in render paths. Glyphs (`▸ · ▾ ─`), key names (`Enter`, `Alt+?`), and
40 commands (`/fleet setup`) are composed in code, never embedded in translations.
41 Adding a string is a four-part change: see `locales/AGENTS.md`.
42
43 ## Verification
44
45 ```sh
46 cargo test -p codewhale-tui --bins --locked # unit suite (bin targets only)
47 cargo test -p codewhale-tui --tests --locked # every crates/tui/tests/ target
48 cargo clippy --workspace --all-targets --locked -- -D warnings
49 ```
50
51 Narrower reruns of the slow acceptance targets, once `--tests` has told you
52 which one moved:
53
54 ```sh
55 cargo test -p codewhale-tui --test qa_pty --locked # PTY snapshots
56 cargo test -p codewhale-tui --test release_runtime_qa --locked
57 cargo test -p codewhale-tui --test terminal_matrix_qa --locked
58 ```
59
60 **`--bins` and `--tests` are disjoint target sets.** `crates/tui/tests/` holds
61 two dozen process-level acceptance targets that a `--bins` run never compiles,
62 let alone executes, so a green `cargo test -p codewhale-tui --bin codewhale-tui`
63 says nothing about them. `adaptive_evidence_acceptance` sat red across two
64 releases for exactly that reason: every routine command anyone ran was a `--bins`
65 run, and only `cargo test --workspace` reached it. Run both, or run the
66 workspace gate.
67
68 Run clippy with `--all-targets`: `--bin` alone skips test targets and lets lints
69 reach CI.
70
71 Real-terminal QA gotchas, learned the hard way:
72
73 - The local tmux **server** may carry `NO_COLOR=1` and `TERM=dumb` from old VHS
74 runs — launch panes with `env -u NO_COLOR` or all color QA silently lies. tmux
75 also force-enables the low-motion overlay; prove full motion with
76 `TMUX`/`TMUX_PANE` removed.
77 - Scripted PTY input: one Enter on the slash menu both accepts the highlighted
78 match and runs it. A scripted second Enter lands *inside* whatever modal just
79 opened. Send one key, wait, capture.
80 - Judge motion from repeated captures diffed over time, never single
81 screenshots. Layout gates: 40x12, 60x16, 80x24, 100x32, 140x40.
82 - `CODEWHALE_TUI_DEBUG=1` writes per-frame diff sizes to
83 `~/.codewhale/logs/tui-render.log`. Streaming should be tens of cells per
84 frame; a multi-thousand-cell frame is only acceptable on a genuine layout
85 transition.
86
86 lines MARKDOWN