colibri/docs/wiki/tui.md
Sam & Claude b8d499e85c
Some checks are pending
CI / rust (pull_request) Waiting to run
CI / markdown (pull_request) Waiting to run
CI / port (pull_request) Waiting to run
CI / agent-jail-pkgs (pull_request) Waiting to run
docs: rename PLAN/PROPOSAL/HANDOFF/ENHANCEMENT → implementation names
7 renames (no plan/proposal/handoff/enhancement in filenames):

    CLAWDIE-INSTALLER-HANDOFF.md → CLAWDIE-INSTALLER-VALIDATION.md
    CLAWDIE-STUDIO-PROPOSAL.md   → CLAWDIE-STUDIO.md
    COLIBRI-SKILLS-PLAN.md       → COLIBRI-SKILLS.md
    FREEBSD-BUILD-LANE-HANDOFF.md→ FREEBSD-BUILD-LANE.md
    GLASSPANE-TUI-ENHANCEMENTS.md→ GLASSPANE-TUI-DESIGN.md
    MULTI-AGENT-HOST-PLAN.md     → MULTI-AGENT-HOST.md
    PLAN-WIKI-CLAWDIE-SI.md      → WIKI-CLAWDIE-SI.md

  16 cross-references updated across 10 files.
  wiki-lint --strict: PASS (146 refs, 0 failures).
2026-06-26 17:32:39 +02:00

104 lines
4.8 KiB
Markdown

# Terminal dashboard (colibri-tui)
← [index](./index.md)
The TUI is Colibri's live terminal dashboard. It connects to the daemon's Unix
socket, pulls the `GlasspaneSnapshot`, and renders a color-coded table of
supervised panes. It is a **display client**, not part of the daemon, and not
the same thing as `colibri-glasspane`.
## Why it is not `colibri-glasspane`
`colibri-glasspane` is the **state machine** that decides what state an agent
is in from its JSONL events. `colibri-tui` is the **screen** that asks the
daemon "what does the radar look like right now?" and draws it.
| Artifact | Role | Resident crate |
| ------------------- | -------------------------------------------------------- | ------------------------------------------------------- |
| `colibri-glasspane` | Pane state machine, event ingestor, snapshot builder | `crates/colibri-glasspane` |
| `colibri-tui` | Terminal dashboard client with rows, colors, keybindings | `crates/colibri-glasspane-tui` (binary = `colibri-tui`) |
The split matters because the daemon, the MCP bridge, the CLI, and tests all
use `colibri-glasspane`. The TUI is just one consumer. If the TUI is not
installed, or crashes, agents keep running.
## Decisions
### Keep the daemon separate from any terminal UI
`colibri-tui` is a standalone process. It resolves the daemon socket the same
way the CLI does (`DaemonConfig::from_env().socket_path`), then calls
`client.glasspane_snapshot()` every two seconds. The daemon has no awareness of
crossterm or ratatui.
This is the same "service owns state, clients render it" pattern as the MCP
bridge and the CLI. It keeps Colibri headless-safe, which is required for an
`rc.d` service that must boot before any operator logs in.
`crates/colibri-glasspane-tui/src/main.rs` (socket resolution, refresh loop)
### TUI gets spawn/stop keys, not just read-only status
You can spawn a local test agent (`s`) and stop the selected pane (`x`) from
the dashboard. That overlaps with commands the `colibri` CLI can already do,
but the experience is different: a CLI command is one-shot; the TUI is a live
supervision surface with a selected row and an immediate status bar.
We kept the action keys because the dashboard's job is to let an operator
notice and react — spot a stalled pane and stop it without leaving the
terminal.
`crates/colibri-glasspane-tui/src/main.rs` (`spawn_agent`, `kill_selected`)
### One taxonomy from one snapshot
The TUI does not parse agent stdout. It only reads the already-folded
`GlasspaneSnapshot`, so Pi, zot, and local test agents are rendered with the
same columns, colors, and state icons. The rendering code concerns itself only
with layout and keybindings; all semantic decisions live in
`colibri-glasspane`.
`crates/colibri-glasspane/src/lib.rs` (`AgentState`, `GlasspaneSnapshot`)
### Naming: the binary is `colibri-tui`, the crate is `colibri-glasspane-tui`
The crate directory is `colibri-glasspane-tui` because the package implements
"a TUI for the glasspane." The installed binary is named `colibri-tui`
because that is what an operator types. `CLAWDIE-STUDIO.md` and other
docs refer to `colibri-tui` as shorthand; there is no separate `colibri-tui`
crate.
This duality is currently accepted. If we ever add a second TUI surface (e.g.
a `colibri-tui-web` or `colibri-tui-gui`), the naming becomes confusing and
should be revisited.
## Current keybindings
| Key | Action |
| ---------------------- | ----------------------------------------------- |
| `q` / `Esc` | Quit, or close detail pane if open |
| `r` | Refresh snapshot now |
| `s` | Spawn a local `colibri-test-agent` |
| `x` | Stop the selected pane |
| `Enter` | Open/close the detail pane for the selected row |
| `Tab` / `Shift-Tab` | Cycle through distinct sessions |
| `j` / `k` or `↓` / `↑` | Navigate the pane table |
## When to use the TUI vs the CLI
Use the TUI when:
- You want a live, auto-refreshing view of all panes.
- You are picking a pane to inspect or stop visually.
- You are on an SSH session with only a terminal.
Use the `colibri` CLI when:
- You are scripting or piping output (`colibri snapshot | jq`).
- You need a command not bound to a key (e.g. `claim-task`, `set-cost-mode`).
- You want a one-shot answer without entering an alternate screen.
## See also
- [glasspane](./glasspane.md) — the pane state machine the TUI renders
- [operator-cli](./operator-cli.md) — the `colibri` CLI that shares the same socket client