TUI cockpit (ign tui)
An interactive ratatui cockpit over the SAME actions layer the CLI dispatches through — every screen is the CLI family rendered live, not a parallel implementation:
| Screen | What it shows |
|---|---|
| Dashboard | Status/modules/metrics/sessions panels on a 5 s refresh; the global verbs (version, connections, wait …, doctor, restart) and the profile switcher (p) |
| Logs | Live tail (ign logs -f) with the level filter (l), follow/scrollback, and the loggers family behind a |
| Tags | The k9s-style browser: providers → tree → detail with on-demand reads; live watch (w); the tags family behind a; the Alarms tab carries active/history/ack |
| Projects | Project list → detail (record + resources) → resource preview; the project/resource/webdev families behind a |
| Rig | The compose rig's status summary, the full rig verb menu behind a, and a raw rig logs -f pane (l) |
| JVM profiling (special mode — not a tab) | Deliberately outside the Tab rotation: J opens a typed-ACKNOWLEDGE interstitial (the TUI-side --i-accept-the-risk) before the screen exists; inside, a persistent red banner, a flight-recorder status pane, and the capped safe defaults only — s sample 30 s @ 20 ms, w live watch (continuous 10 s @ 50 ms windows; stops on toggle/exit), f JFR start (60 s cap), F JFR stop + fetch, r refresh, Esc leaves. Switching profiles revokes the acknowledgment (see JVM profiling below) |
Behavior contract:
- Interactive-only.
ign tuirequires a TTY — piped stdout refuses with a usage error (exit 2) before the alternate screen is ever touched. Profile resolution failures (no profile, missing secret) also surface BEFORE the terminal flips: the normal stderr envelope and exit taxonomy, not a flash of alt-screen. - Silent stdout on success. The alternate screen owns all display; a clean exit prints NOTHING on stdout (no envelope, no summary line). Errors after the terminal is restored render to stderr per the frozen taxonomy — the envelope contract is the CLI's.
- Confirm parity. Exactly the CLI's
--yes-guarded verbs open a Confirm modal first (y≡--yes, Esc spawns nothing): restart, sessions terminate, loggers set/reset, tags provider/config delete, tags import-overwrite, project delete/import-overwrite, resource put/delete, rig reset/restore, rig trial reset. Everything else fires directly — includingrig downandwebdev deploy, which the CLI deliberately leaves unguarded. - Keybindings.
q/Ctrl-C quit (Ctrl-C works even behind a modal;qnever quits behind a modal — it types) · Tab/Shift-Tab cycle screens (the JVM-profiling special mode is NOT in the cycle —Jenters it through its gate,Escor Tab leaves) · Enter/Esc navigate (Esc ascends one level on the browser screens) ·aopens the screen's actions menu (grouped and prose-labeled — the Projects menu clusters project/resource/webdev verbs with each row naming its consequence) ·popens the profile switcher. Per-screen:rrefresh (Dashboard/Rig; on Tags it refires the deepest-visible pane so a stale error visibly reloads),llevel filter (Logs) / logs pane toggle (Rig),ffollow,wwatch a tag (Tags),halarm history (Alarms),tterminate a session (Dashboard). Modals take vim motions: in every list-bearing menuj/kstep andg/Gjump to first/last; the Result modal scrolls line-wise withj/k(arrows and PgUp/PgDn unchanged) and half-pages with Ctrl-d/Ctrl-u. - Coverage is CI-enforced. A structural test
(
crates/ignition-cli/tests/tui_coverage.rs) walks the live clap command tree and asserts bidirectional equality with the TUI route registry: every CLI leaf (plus the bare-invocablesessions,logs,logs loggersforms) has a TUI mapping and no orphan rows exist — adding a CLI command without a cockpit surface FAILS CI. The only unmapped leaf iscompletions(out-of-band by design).
Themes & capability degradation ([ui].theme)
Four named themes — default, dark, light, mono — selected by the
top-level [ui].theme config key (set it with any TOML editor; ign profile never needs to be involved). Every theme is AUTHORED at four
capability tiers — truecolor, ANSI-256, ANSI-16, mono — detected at
startup from NO_COLOR / COLORTERM / TERM: the palette steps down
without breaking layout or contrast. default and mono render
byte-identically at every tier (their non-mono slots are Reset);
dark carries WCAG-AAA body contrast (14.2:1 text on black); light
keeps black-text structure on either terminal background. Discipline is
CI-enforced: Color:: literals live ONLY in the style-tokens module
(ui/theme.rs) — a grep gate fails any style literal anywhere else.
A wrong-typed or unknown [ui].theme value warns and falls back to
default — a config typo never kills TUI startup.
Polling cadence (poll_interval_secs)
Each profile takes an optional poll_interval_secs — the Dashboard
refresh period, default 5 s, with ONE source of truth in the code.
Sub-second values are refused at config load (poll_interval_too_small,
exit 3 — the hard floor against hammering the gateway). The active value
adopts live across profile switches (same ride-along path as the theme).