Skip to main content

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:

ScreenWhat it shows
DashboardStatus/modules/metrics/sessions panels on a 5 s refresh; the global verbs (version, connections, wait …, doctor, restart) and the profile switcher (p)
LogsLive tail (ign logs -f) with the level filter (l), follow/scrollback, and the loggers family behind a
TagsThe 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
ProjectsProject list → detail (record + resources) → resource preview; the project/resource/webdev families behind a
RigThe 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 tui requires 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 — including rig down and webdev deploy, which the CLI deliberately leaves unguarded.
  • Keybindings. q/Ctrl-C quit (Ctrl-C works even behind a modal; q never quits behind a modal — it types) · Tab/Shift-Tab cycle screens (the JVM-profiling special mode is NOT in the cycle — J enters it through its gate, Esc or Tab leaves) · Enter/Esc navigate (Esc ascends one level on the browser screens) · a opens the screen's actions menu (grouped and prose-labeled — the Projects menu clusters project/resource/webdev verbs with each row naming its consequence) · p opens the profile switcher. Per-screen: r refresh (Dashboard/Rig; on Tags it refires the deepest-visible pane so a stale error visibly reloads), l level filter (Logs) / logs pane toggle (Rig), f follow, w watch a tag (Tags), h alarm history (Alarms), t terminate a session (Dashboard). Modals take vim motions: in every list-bearing menu j/k step and g/G jump to first/last; the Result modal scrolls line-wise with j/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-invocable sessions, logs, logs loggers forms) has a TUI mapping and no orphan rows exist — adding a CLI command without a cockpit surface FAILS CI. The only unmapped leaf is completions (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).