Skip to content

War Room: conduit watch as a TUI first (OpenTUI), web GUI second #89

Description

@queso

Context

prd/drafts/war-room.md specifies the War Room as a read-only view of the journal: a trace waterfall, one row per card, time on the x-axis. Four Claude Design rounds on 2026-09-28 settled the layout. The screen has a single-line header with meters for wall-clock, tokens, 5-hour plan quota, and the watchdog, plus tallies. It has a station color legend, half-height rows for done cards, a state column with one short token per row, a drawer showing the card's journal, and a strip of tool-call ticks for the current harness attempt. The TUI visual spec (frames, 160x45 golden text and ANSI frames, color tokens, and a cell-grid reference renderer) is in design/war-room/, added by #90.

Decision: TUI first

The PRD resolved "web over TUI" in June. This reverses the order but not the goal: the web GUI still follows.

  • Flows run on a remote box. A TUI works over SSH or docker exec -it with no port forwarding, and it doesn't need an auth decision.
  • There's no server layer: no Bun.serve endpoints, no SSE, and no reactiveSWR for the first version.
  • Tests assert on rendered text and colors in bun test, with no browser.
  • A vhs recording of a fixture run can serve as the launch demo.

Shared core (built once, reused by the web GUI)

  • A read-only journal and state DB reader that loads the current state and follows new rows by sequence number.
  • One pure projection function that folds journal events into view state. The June v0 prototype's projection sketch at design/warroom-prototype/lib/warroom-data.ts is the starting point. Reconcile its types with src/types/kernel.ts.
  • Replay: events up to a chosen point, re-folded through the same function.
  • "Not recorded" rendering, with each gap logged to a list of journal schema gaps (PRD FR-13).

TUI

  • conduit watch renders with @opentui/react, pinned to 0.5.12 because it's pre-1.0. It's Bun-native.
  • Minimum width is 160 columns. Bars use full and partial block characters. Borders use box-drawing characters.
  • There's no hover. The selected row's details go in a status line. Keys: j/k to select, enter to open the drawer, t for tool ticks, r for replay, esc to close. Mouse clicks work on rows and ticks.
  • The drawer is 60 columns wide and scrolls.

Testing

  • Unit and component tests use testRender from @opentui/react/test-utils: captureCharFrame() for text snapshots, captureSpans() for color assertions (green only on working elements, OVERDUE the loudest color on screen), mockInput and mockMouse for interactions, ManualClock for countdowns and watchdog timing, and resize() for the minimum width.
  • Core tests cover two things: replay gives the same view as live, and a burst of journal rows written in one tick folds without losing any.
  • The black-box suite runs the shipped binary in a tmux pane and captures the screen with tmux capture-pane -p -e.

Out of scope

  • Any write path, per PRD §7. Right-click menus are allowed but may only offer read-only actions.
  • The web GUI, which gets its own issue and reuses the core.
  • A multi-run view.

Open questions

  • A run-level kernel heartbeat in the journal. Without one, "kernel not observed" can't tell a crashed kernel from a slow one (PRD §10).
  • A run picker. Several flows will run at once, and the PRD limits v1 to a single run.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions