Skip to content

EMRY-021: TUI 4-pane dashboard (ratatui) - #63

Merged
vxfemboy merged 2 commits into
mainfrom
emry-021-tui-app
Jun 25, 2026
Merged

EMRY-021: TUI 4-pane dashboard (ratatui)#63
vxfemboy merged 2 commits into
mainfrom
emry-021-tui-app

Conversation

@vxfemboy

@vxfemboy vxfemboy commented Jun 25, 2026

Copy link
Copy Markdown
Member

Closes EMRY-021 (#16). Branched off main.

What

  • ui.rsUiState: a pure reducer over the event stream (per-metric history, phase, progress, capped alerts, selection, pause). render() draws the 4 panes (header+progress / metric cards / braille chart / alert strip) in the warm palette into any ratatui Backend.
  • app.rsrun: channel-driven loop (drain bus + input, ~15 Hz cap, pause freezes the display); map_key binds q/Esc/14/p; run_terminal is the thin real-terminal shell.
  • examples/tui_demo.rs — streams a synthetic engine run to the dashboard.

Verification

  • ./scripts/pre-commit-rust.sh green: clippy -D warnings, 27 tui tests, total 96.5% lines.
  • Rendering is verified headlessly via TestBackend: a test renders a populated state and asserts the buffer contains the project name, metric label, and alert text. The render loop, state reducer, and key mapping are all covered; only the real-terminal shell (raw mode + blocking key read) is uncovered (that's the part that needs a TTY).
  • The live animated curve (cargo run -p emry-tui --example tui_demo)
image

MSRV note

ratatui 0.29's newest transitive deps (instability/darling) require rustc 1.88; I pinned them down (instability 0.3.7 / darling 0.20.11) so the project stays on its pinned 1.87. (Committed in Cargo.lock.)

Review-driven fixes

  1. unbounded() input channel → bounded(64) + try_send (honors the project's no-unbounded-channel invariant).
  2. Removed the UntilQuit finish-and-drained auto-exit — closes a drain/is_empty TOCTOU and is better UX (dashboard stays up post-run).
  3. Vec::remove(0) O(n) on 4096-cap history → VecDeque O(1) FIFO.
  4. Pause now actually skips draw (display freezes).
  5. Metric label refreshed each sample (no stale fallback labels).

Scope

EMA/throughput/ETA derived series in the dashboard → EMRY-022. emry demo/tui CLI wiring → EMRY-025.

vxfemboy added 2 commits June 25, 2026 00:41
UiState: pure reducer over the event stream (per-metric history, phase,
progress, capped alerts, selection, pause). render() draws the 4 panes
(header / metric cards / braille chart / alert strip) in the warm palette into
any ratatui Backend, so it's tested via TestBackend. app::run is the channel-
driven loop (drain bus + input, ~15Hz cap); run_terminal is the thin real-
terminal shell; map_key binds q/Esc, 1-4, p. examples/tui_demo.rs streams a
synthetic run to the dashboard.

Pinned instability 0.3.7 / darling 0.20.11 so ratatui 0.29 builds on the
project's rustc 1.87 (newer transitive versions require 1.88).
… history

- read_keys uses a bounded(64) channel + try_send (dropping keys under flood),
  honoring the no-unbounded-channel project invariant.
- run no longer auto-exits UntilQuit on finish (removes a drain/is_empty TOCTOU
  and keeps the dashboard up after a run so final values stay readable; exit on
  Quit only).
- Pausing now skips terminal.draw so the display actually freezes (state still
  updates underneath).
- MetricView.history is a VecDeque: O(1) FIFO instead of Vec::remove(0) O(n)
  shift on the 4096-cap history; converted to a slice at render time.
- Refresh the metric label each sample so seeded labels aren't stale.
@vxfemboy
vxfemboy merged commit 1c358ce into main Jun 25, 2026
3 checks passed
@vxfemboy vxfemboy mentioned this pull request Jun 25, 2026
4 tasks
@vxfemboy
vxfemboy deleted the emry-021-tui-app branch July 2, 2026 23:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant