Files
correx/docs/modules/apps/app-tui.adoc
T
kami 9734eec63c docs: add module documentation in AsciiDoc with PlantUML diagrams
Generated by per-group subagents covering all 52 modules across:
core (18), infrastructure (10), apps (5), interfaces (3),
plugins (7), testing (9)

Documentation format:
- AsciiDoc (.adoc) files in docs/modules/<group>/
- PlantUML (.puml) files in docs/diagrams/
- .adoc files reference diagrams via include:: directives

Each doc covers: purpose, responsibilities, non-responsibilities,
key types, event flow, integration points, invariants, PlantUML
diagram, known issues, and open questions.
2026-05-26 16:59:21 +04:00

116 lines
5.4 KiB
Plaintext

= app-tui
== purpose
Terminal UI built on the Tamboulib TUI framework that provides a real-time interactive dashboard for monitoring and controlling Correx sessions.
== responsibilities
* Display a live session list with status, workflow name, and background-update badges
* Show workflow definitions available on the server for starting new sessions
* Stream session lifecycle events (stage, tool, inference) in a scrollable event strip
* Display tool diffs when tool executions complete with file modifications
* Surface approval requests with tool name, tier, risk summary, and command preview
* Accept approval decisions (approve / reject) and steering notes via keyboard input
* Support session filtering by workflow name, input history navigation, and keyboard-driven UI modes
== non-responsibilities
* Does not contain any domain orchestration or event-sourcing logic
* Does not persist any state — all state is in-memory and rebuilt on reconnect
* Does not authenticate or encrypt connections
* Does not support mouse interaction
== key types
=== TuiState
* **kind**: data class
* **purpose**: Root application state. Contains `connection`, `sessions`, `input`, `provider` sub-states plus display metadata (cursor position, input buffer, history, snapshot phase flags, per-session cursors).
=== SessionsState
* **kind**: data class
* **purpose**: Holds the list of `SessionSummary` objects, filter text, session/workflow selection, and background update counter.
=== DisplayState
* **kind**: enum
* **purpose**: Tri-state enum (`IDLE`, `IN_SESSION`, `APPROVAL`) that drives which layout the TUI renders.
=== SessionSummary
* **kind**: data class
* **purpose**: Projected view of a session for display — ID, status, workflow, stage, tools, recent events, pending approval.
=== TuiWsClient
* **kind**: class
* **purpose**: Ktor WebSocket client that maintains a persistent global stream (`/stream`). Exposes cold `Flow<ServerMessage>` and `Flow<ConnectionEvent>` backed by `Channel.UNLIMITED`. Implements exponential backoff reconnection.
=== Action (sealed interface)
* **kind**: sealed interface
* **purpose**: Union of all user input and system events (navigation, input editing, approval, server messages, connection events).
=== KeyEvent (sealed class)
* **kind**: sealed class
* **purpose**: Normalized key events independent of the TUI backend (TambouiKeyEvent mapping).
=== RootReducer
* **kind**: object
* **purpose**: Top-level reducer that coordinates `SnapshotPhaseReducer` + four sub-reducers (`InputReducer`, `SessionsReducer`, `ConnectionReducer`, `ProviderReducer`). Handles cross-reducer state weaving (input history, approval dismissal, auto-enter on session start).
=== SnapshotPhaseReducer
* **kind**: object
* **purpose**: Manages the snapshot-to-live transition. Buffers event-bearing messages during snapshot replay; drains buffered events atomically when `SnapshotComplete` arrives; deduplicates live events by `sessionSequence`.
=== Effect (sealed interface)
* **kind**: sealed interface
* **purpose**: Side-effect descriptors produced by reducers — either `SendWs(ClientMessage)` or `Quit`.
=== EffectDispatcher
* **kind**: class
* **purpose**: Executes effects sequentially. Dispatches WS messages via `TuiWsClient.send()` and `Quit` via a callback that exits the TUI runner.
== event flow
*inbound:* `ServerMessage` frames from the global WebSocket stream, decoded by `TuiWsClient` and wrapped in `Action.ServerEventReceived`. Also connection lifecycle events (`Connected`, `Disconnected`, `RetryScheduled`).
*outbound:* `ClientMessage` frames sent via `Effect.SendWs` — `StartSession`, `CancelSession`, `ApprovalResponse`.
== integration points
* `:apps:server` — imports `ServerMessage`, `ClientMessage`, `ApprovalDecision`, `PauseReason`, `WorkflowDto`, `ProviderHealthDto`
* `:core:events` — imports `ApprovalRequestId`, `SessionId`
* `:core:approvals` — imports `Tier`
Tamboulib framework: `tamboui-tui`, `tamboui-widgets`, `tamboui-core`, `tamboui-jline3-backend`.
== invariants
* `ws.messages` and `ws.connection` are single-consumer cold flows — adding a second collector drops messages from one
* Effects are dispatched sequentially (dispatchAll) — order matches `RootReducer` concatenation
* `Effect.Quit` is always appended last by `RootReducer.reduce`
* Snapshot phase is entered initially and on every `Disconnected`; buffered events are drained atomically at `SnapshotComplete`
* Live event deduplication uses per-session `sessionSequence` cursor; gaps are warned and applied anyway
* The TUI creates one WS connection (`/stream`) — per-session streams are not used
== PlantUML diagram
[plantuml, app-tui, "png"]
----
include::../../diagrams/app-tui.puml[]
----
== known issues
* `StageToolManifest` arriving before `SessionStarted` is silently dropped (TODO RF-3) — the session won't exist in the list yet
* Chat submission in `IN_SESSION` is blocked (returns empty effects) — router integration is deferred to Epic 14
* `InputHistory` limit is hardcoded to 50 entries per session
* Event strip shows at most 5 events for the selected session
* Session list is capped at 7 visible entries; overflow is shown as a count but not scrollable
== open questions
* Should the TUI support per-session WebSocket streams instead of relying solely on the global stream?
* Should approval decisions support freeform steering note input that can exceed one line?
* How should workflow picker handle very large numbers of available workflows (10+)?