TUI
Swarm's terminal user interface (TUI) is the primary way to monitor and interact with a running swarm session. It provides real-time visibility into agent states, logs, events, and session metadata.
Design Philosophy
The TUI is a first-class component, not an afterthought (ADR-007). It's built with ratatui (a Rust TUI framework) on top of crossterm for terminal handling, rendering at approximately 30 FPS (33ms frame interval).
For environments where a TUI isn't suitable (CI, remote servers, testing), the --no-tui flag runs swarm in headless mode, logging to stdout instead.
Components
TuiApp
The TuiApp struct holds all mutable TUI state:
| Field | Type | Description |
|---|---|---|
agents | Vec<AgentEntry> | Ordered list of agents (sorted by name) |
selected | usize | Index of the currently selected agent |
log_viewer | LogViewer | Log file viewer for the selected agent |
event_viewer | EventViewer | Real-time streaming event viewer |
input | String | Current contents of the command input bar |
session_id | String | Displayed in the status bar |
quit_requested | bool | Set to true when user requests quit |
context_info | HashMap<String, ContextInfo> | Per-agent context window usage |
show_task_list | bool | Task list overlay visibility (Ctrl+T) |
tasks | Vec<Task> | Snapshot of tasks from the task store |
show_workflow_panel | bool | Workflow panel visibility (Ctrl+W) |
show_iteration_panel | bool | Iteration panel visibility (Ctrl+I) |
AgentEntry
Each agent in the TUI is represented as an AgentEntry:
| Field | Type | Description |
|---|---|---|
name | String | Agent name |
state | AgentState | Current state from the state machine |
log_path | PathBuf | Path to the agent's log file |
liveness | Option<AgentLiveness> | Liveness monitoring data (idle time, stall, nudges) |
Agent Panel
The left panel shows a list of all agents with their current state:
┌─ Agents ──────────────────┐
│ ● backend Running │
│ ● frontend Running │
│ ○ reviewer CoolingDown│
│ ■ supervisor Stopped │
└───────────────────────────┘
Each agent shows:
- A state indicator icon
- The agent name
- The current state label
- Liveness suffix when available (running duration, idle time, stall warnings)
Log/Event Viewer
The right panel displays output for the selected agent:
- Event viewer — Real-time streaming events from the agent's backend session
- Log viewer — Fallback log file viewer when event streaming isn't available
The viewer auto-scrolls to follow new output.
Input Bar
The bottom of the screen shows a command input bar where you can type messages to send to agents. The input bar is always visible.
Overlays
Toggle-able overlay panels:
| Overlay | Toggle | Content |
|---|---|---|
| Task list | Ctrl+T | Tasks from the beads task store |
| Workflow progress | Ctrl+W | Active/recent workflow runs and stages |
| Iteration progress | Ctrl+I | Iteration loop runs and status |
Context Window
Per-agent context window usage is tracked and displayed:
| Field | Description |
|---|---|
used_tokens | Tokens consumed in the current session |
max_tokens | Maximum context window size |
usage_percent | Percentage of context used |
Navigation
| Key | Action |
|---|---|
Up / Down | Select previous/next agent |
Ctrl+T | Toggle task list overlay |
Ctrl+W | Toggle workflow panel |
Ctrl+I | Toggle iteration panel |
q / Ctrl+C | Quit (triggers graceful shutdown) |
State Refresh
The TUI refreshes agent states each frame by calling AgentRegistry::states(). Liveness data is refreshed from a watch channel provided by the liveness monitor. This keeps the display current without expensive polling.
Headless Mode
When --no-tui is specified:
- No terminal UI is rendered
- Agent state changes are logged to stdout via
tracing - The orchestrator still runs all the same subsystems (router, periodic tasks, etc.)
- Shutdown is triggered by SIGTERM only (no interactive quit)
Related
- ADR-007: TUI First — Design rationale
- Architecture — How the TUI fits in the system
- Orchestration — TUI launch in the start flow