TUI
Purpose
The TUI (Terminal User Interface) provides an interactive Bubbletea-based interface for monitoring and managing fab agents. It displays real-time agent status, chat history, and recent work, while enabling users to send messages, approve permissions, answer questions, and control agent lifecycle.
Non-goals:
- Does not implement daemon communication (delegated to
daemon.TUIClient) - Does not manage agent processes directly (delegated to supervisor and orchestrator)
- Does not persist state across sessions (session-only in-memory state)
Interface
CLI Command
| Command | Description |
|---|---|
fab tui |
Launch the TUI connected to the running daemon |
Key Bindings
| Mode | Key | Action |
|---|---|---|
| Normal | q, Ctrl+C |
Quit TUI |
| Normal | Tab |
Cycle focus between agent list and chat view |
| Normal | j/k, ↑/↓ |
Navigate agent list or scroll chat |
| Normal | g/G |
Jump to top/bottom |
| Normal | Ctrl+U/Ctrl+D |
Page up/down in chat |
| Normal | Enter |
Enter input mode (send message to agent) |
| Normal | y |
Approve pending permission or answer |
| Normal | n |
Reject pending permission |
| Normal | x |
Abort selected agent (with confirmation) |
| Normal | p |
Start a new planner agent |
| Normal | s |
Toggle supervisor/manager view |
| Normal | r |
Reconnect when disconnected |
| Input | Enter |
Send message |
| Input | Esc |
Cancel input mode |
| Input | Tab |
Exit input mode |
| Input | Shift+Enter |
Insert newline |
| Input | ↑/↓ |
Navigate input history |
UI Components
| Component | Description |
|---|---|
Header |
Displays branding, agent counts, commit count, usage meter, and connection status |
AgentList |
Navigable list of agents with state indicators, project, backend, and duration |
ChatView |
Scrollable conversation history with permission/question overlays |
InputLine |
Text input with history support for sending messages |
RecentWork |
Displays recent commits made by agents |
HelpBar |
Context-sensitive keyboard shortcut hints |
Interaction Modes
The TUI uses a modal state machine to manage user interaction:
| Mode | Description |
|---|---|
ModeNormal |
Default navigation mode |
ModeInput |
User is typing a message |
ModeAbortConfirm |
Awaiting abort confirmation (y/n) |
ModeUserQuestion |
Selecting answer for Claude's question |
ModePlanProjectSelect |
Selecting project for new planner |
ModePlanPrompt |
Entering prompt for new planner |
Configuration
The TUI reads global configuration from ~/.config/fab/config.toml:
| Key | Description |
|---|---|
log-level |
Controls TUI debug logging (logs to file, not terminal) |
Runtime options (passed programmatically):
| Option | Description |
|---|---|
InitialAgentID |
Agent to select on startup (empty = first agent) |
Verification
Run the TUI unit tests:
$ go test ./internal/tui/... -v
=== RUN TestNewModeState
Run the mode state machine tests specifically:
$ go test ./internal/tui/... -run TestModeState -v
--- PASS: TestModeState_SetFocus
Examples
Monitoring agent activity
- Start the TUI:
fab tui - Use
j/kto navigate the agent list - View chat history for the selected agent
- Press
Enterto send a message to the agent
Approving a tool permission
When an agent requests permission to use a tool:
- The agent row shows
!indicator (attention needed) - The chat view displays the pending permission request
- Press
yto approve ornto reject
Answering a user question
When Claude uses AskUserQuestion:
- The chat view shows the question with selectable options
- Use
j/kto navigate options - Press
yto submit the selected answer - Select "Other" and press
yto enter a custom response
Starting a planner
- Press
pin normal mode - Select a project using
j/kand pressEnter - Type your planning prompt
- Press
Enterto start the planner
Gotchas
- Connection loss: The TUI auto-reconnects with exponential backoff (up to 10 attempts). Press
rfor manual reconnection when disconnected. - Permission timeout: Permissions must be approved within 5 minutes (handled by supervisor). Unanswered permissions cause agent failure.
- Chat history on reconnect: After daemon restart, chat history may be lost. The TUI refetches history on reconnection.
- Input mode isolation: In input mode, navigation keys are captured by the text input. Press
EscorTabto exit. - Spinner animation: Running agents show animated spinners. Manager agents show a static indicator when idle.
Decisions
Bubbletea architecture: The TUI uses the Elm-like Bubbletea framework with a central Model and message-based updates. This provides predictable state management and clean separation between UI and logic.
Modal state machine: A centralized ModeState manages all interaction modes. This prevents invalid state combinations (e.g., input mode during abort confirmation) and simplifies focus management.
Event streaming: The TUI maintains a dedicated streaming connection to the daemon for real-time updates. Events are processed asynchronously via a message channel to avoid blocking the UI.
Entry merging on history fetch: When fetching chat history, the TUI merges with any streaming entries that arrived during the fetch. This prevents race conditions where switching agents loses recent messages.
Automatic reconnection: Exponential backoff (500ms to 8s) handles transient connection issues without user intervention. The header displays connection state for visibility.
Paths
internal/tui/tui.go- Main model, initialization, and view compositioninternal/tui/update.go- Message handling and state updatesinternal/tui/mode.go- Modal state machineinternal/tui/keybindings.go- Keyboard shortcut definitionsinternal/tui/commands.go- Bubbletea commands for daemon communicationinternal/tui/messages.go- Internal message typesinternal/tui/helpers.go- Model helper methods (focus sync, layout, state pruning)internal/tui/agentlist.go- Agent list componentinternal/tui/chatview.go- Chat view component with permission/question overlaysinternal/tui/header.go- Header component with status indicatorsinternal/tui/inputline.go- Text input with historyinternal/tui/helpbar.go- Context-sensitive help barinternal/tui/recentwork.go- Recent commits displayinternal/tui/styles.go- Lipgloss styling definitionsinternal/cli/tui.go- CLI command that launches the TUI