Files
cleveragents-core/docs/reference/tui.md
T
freemo 78b70c09fe docs(v3.7.0): update API docs, README, architecture overview, and changelog
- README: add v3.7.0 highlights (first-run UX, estimation lifecycle,
  enriched domain events, correction attempts, devcontainer handler,
  A2A ValueError mapping); add What's New section; add doc links
- CHANGELOG: merge 'Unreleased (pre-3.7.0)' into v3.7.0 as a
  subsection; clear [Unreleased] block
- docs/reference/architecture_overview.md (new): high-level system
  layers, core abstractions, key services, protocols (A2A/MCP/LSP),
  estimation lifecycle, TUI architecture, server mode, observability
- docs/reference/estimation_lifecycle.md (new): EstimationResult
  model reference, configuration, PLAN_ESTIMATION_COMPLETE event,
  plan.cost_estimate_usd, writing a custom estimation actor
- docs/reference/correction_attempts.md (new): CorrectionAttemptRecord
  schema, state machine, CorrectionAttemptRepository API, DDL,
  CorrectionDryRunReport migration guide (removed redundant fields)
- docs/reference/tui.md: add first-run experience section
  (ActorSelectionOverlay, is_first_run, create_default_persona_for_actor),
  session export/import TUI section, persona export/import TUI section;
  update architecture module table with first_run.py and
  actor_selection_overlay.py entries
- mkdocs.yml: add Architecture Overview to top-level nav

ISSUES CLOSED: #1310 #1087 #1242 #1241 #891 #996 #1001
2026-04-28 09:25:00 +00:00

13 KiB
Raw Blame History

TUI — Text User Interface

The CleverAgents TUI is a Textual-based interactive terminal application launched with agents tui. It provides a full-screen chat-style interface with persona management, slash commands, @-reference resolution, and context-sensitive help.

ADRs: ADR-044, ADR-045, ADR-046

Installation

Textual is an optional dependency:

pip install 'cleveragents[tui]'

Without Textual, agents tui raises a RuntimeError with installation instructions. The --headless flag works without Textual and is useful for CI startup checks.

Launching

# Full interactive TUI
agents tui

# Headless startup check — prints JSON diagnostics and exits
agents tui --headless

The --headless output includes:

{
  "textual_available": true,
  "persona_count": 2,
  "default_persona": "default",
  "help": "Commands: /persona, /session, /help"
}

Keybindings

Key Action
F1 Toggle context-sensitive help panel
Escape Close current overlay / return to prompt
Enter Submit prompt
Tab Cycle to next persona
Ctrl+Tab Cycle to next argument preset
Ctrl+Q Quit TUI immediately

Input Modes

The prompt auto-detects the input mode from the first character:

Prefix Mode Behaviour
(none) Normal Expands @-references and sends to the active actor
/ Command Opens slash command overlay; dispatches on Enter
! or $ Shell Executes the remainder as a shell command

Mode detection is handled by InputModeRouter.detect_mode().

Normal mode — @ references

Type @ followed by a partial name to open the Reference Picker overlay. Candidates are drawn from a filesystem-backed catalog (projects, plans, resources, actors, tools, skills) with a 5-second TTL cache. Fuzzy matching uses prefix → substring → path-component → difflib scoring with recency boosting.

@my-proj          # resolves to project:local/my-project
@main-repo        # resolves to resource:local/main-repo

Resolved references are expanded inline before the prompt is submitted.

Command mode — / slash commands

Type / to open the Slash Command overlay. Start typing to filter the 67 available commands across 14 groups. Press Enter to dispatch.

See Slash Commands for the full catalog.

Shell mode — ! passthrough

! git status
! ls -la

The command is executed in a subprocess with a configurable timeout (default: 30 seconds). Output is displayed in the transcript.

Slash Commands

67 commands across 14 groups. All commands follow the group:action naming convention.

Group Commands
Session session:create, session:list, session:show, session:switch, session:close, session:delete, session:rename, session:export, session:import
Persona persona:list, persona:set, persona:create, persona:edit, persona:delete, persona:export, persona:import
Scope scope:add, scope:remove, scope:clear, scope:show
Plan plan:use, plan:list, plan:status, plan:tree, plan:execute, plan:apply, plan:cancel, plan:diff, plan:correct, plan:resume, plan:revert, plan:rollback, plan:explain, plan:errors, plan:artifacts, plan:inspect
Project project:list, project:create, project:show, project:delete, project:inspect, project:context:show
Actor actor:list, actor:show, actor:set-default
Resource resource:list, resource:show, resource:tree, resource:inspect
Config config:list, config:get, config:set
Tool tool:list, tool:show
Skill skill:list, skill:show
Invariant invariant:list, invariant:add, invariant:remove
Profile profile:list, profile:show
Context context:inspect, context:set
Utility help, clear, exit

Widgets

CleverAgentsTuiApp

The root Textual application. Composes:

  • Header — application title bar
  • PersonaBar — active persona name, icon, and preset indicator
  • PromptInput — multi-mode prompt with mode indicator
  • SlashCommandOverlay/-triggered command picker
  • ReferencePickerOverlay@-triggered reference picker
  • HelpPanelOverlayF1-toggled context-sensitive help
  • Footer — keybinding hints

PersonaBar

Displays the active persona's icon and name plus the current argument preset name. Updates automatically when the persona or preset changes.

PromptInput

Single-line input widget. Displays a mode indicator (> normal, / command, ! shell) and emits InputSubmittedEvent on Enter.

SlashCommandOverlay

Fuzzy-filtered list of all 67 slash commands. Keyboard-navigable. Dismissed by Escape.

ReferencePickerOverlay

Fuzzy-filtered list of catalog entries. Dismissed by Escape or on reference selection.

HelpPanelOverlay

Context-sensitive help panel. Content varies by current mode:

  • Main Screen — global keybindings + main-screen shortcuts
  • Slash Commands — slash command navigation hints
  • Reference Picker — reference picker navigation hints
  • Shell Prompt — shell mode usage notes

Source Locations

src/cleveragents/tui/
├── app.py                    # CleverAgentsTuiApp, SessionView, _FallbackCleverAgentsTuiApp
├── commands.py               # TuiCommandRouter, run_tui()
├── slash_catalog.py          # SLASH_COMMAND_SPECS, SlashCommandSpec
├── cleveragents.tcss         # Textual CSS stylesheet
├── input/
│   ├── modes.py              # InputMode, InputModeRouter, ModeResult
│   ├── reference_parser.py   # ReferenceMatch, ReferenceParseResult, parse_references()
│   └── shell_exec.py         # ShellResult, run_shell_command()
├── persona/
│   ├── schema.py             # Persona, PersonaPreset
│   ├── registry.py           # PersonaRegistry
│   └── state.py              # PersonaState
├── search/
│   └── fuzzy.py              # FuzzyCandidate, score_match(), rank_candidates()
└── widgets/
    ├── help_panel_overlay.py # HelpPanelOverlay, resolve_help_context()
    ├── persona_bar.py        # PersonaBar
    ├── prompt.py             # PromptInput
    ├── reference_picker.py   # ReferencePickerOverlay
    └── slash_command_overlay.py # SlashCommandOverlay

Running Tests

Behave (BDD unit tests)

nox -s unit_tests -- features/tui_persona.feature
nox -s unit_tests -- features/tui_slash_commands.feature
nox -s unit_tests -- features/tui_input_modes.feature

Robot Framework (smoke / integration tests)

nox -s integration_tests -- robot/tui_smoke.robot

Inline Permission Questions

For single-file permission requests, the TUI renders a PermissionQuestionWidget inline in the conversation stream rather than pushing the full PermissionsScreen.

Permission Required

The actor wants to write to:
  src/api/main.py

   a  Allow once
    A  Allow always (this session)
    r  Reject once
    R  Reject always (this session)

Press v to open full PermissionsScreen with diff view

Key bindings:

Key Action
a Allow once
A Allow always (this session)
r Reject once
R Reject always (this session)
/ Navigate options
Enter Confirm highlighted option
v Open full PermissionsScreen with diff view

A PermissionDecisionEvent is emitted when the user makes a decision.

See Permission Question Widget for the full API reference.


Permissions Screen

When an actor requests a write operation on a resource, the TUI raises the PermissionsScreen overlay. The user reviews the proposed changes in a split-pane layout (file list left, diff view right) and decides whether to allow or reject the operation.

Key bindings inside PermissionsScreen:

Key Action
a Allow this request once
A Allow all requests from this tool for the session
r Reject this request once
R Reject all requests from this tool for the session
d Cycle diff mode: unified → side-by-side → context

See tui_permissions.md for the full API reference.

Actor Thought Blocks

Actors that support extended thinking (e.g. Claude extended thinking mode) emit reasoning traces that are rendered as ThoughtBlockWidget instances in the conversation stream. Thought blocks are displayed with muted styling and can be expanded or collapsed with Space.

See tui_thought_block.md for the full API reference.

First-Run Experience

On the first launch (when no personas are configured), the TUI displays the Actor Selection Overlay — a guided setup screen that lets the user pick an actor to get started.

┌─────────────────────────────────────────────────────┐
│  Welcome to CleverAgents                            │
│                                                     │
│  Select an actor to get started:                    │
│                                                     │
│  > anthropic/claude-4-sonnet                        │
│    anthropic/claude-4-opus                          │
│    openai/gpt-4o                                    │
│    openai/o3                                        │
│    google/gemini-2                                  │
│                                                     │
│  Search: ___________                                │
│  [Enter] Select   [Esc] Cancel                      │
└─────────────────────────────────────────────────────┘

After the user selects an actor, a "default" persona is automatically created and persisted to the persona registry. Subsequent launches restore the last-used persona and skip the first-run overlay.

First-run detection: is_first_run(registry) returns True when PersonaRegistry.list_personas() returns an empty list.

Module: cleveragents.tui.first_run

Function Description
is_first_run(registry) Returns True when no personas are configured
create_default_persona_for_actor(registry, actor) Creates and persists a "default" persona for the given actor

Widget: cleveragents.tui.widgets.actor_selection_overlay

Function Description
render_actor_selection(actors, selected_index, search_query) Renders the actor selection overlay content

Default actors offered in the overlay:

  • anthropic/claude-4-sonnet
  • anthropic/claude-4-opus
  • openai/gpt-4o
  • openai/o3
  • google/gemini-2

Session Export / Import (TUI)

Sessions can be exported and imported directly from the TUI using slash commands or the Sessions Screen.

# Export the current session to JSON
/session:export

# Import a session from a JSON file
/session:import

Export produces a JSON file containing the full session transcript and metadata. Import restores a session from a previously exported file. Both operations are also available via the CLI:

agents session export --session-id <ID> --output session.json
agents session import --input session.json

Persona Export / Import (TUI)

Personas can be exported to YAML and imported from YAML files:

# Export a persona
/persona:export

# Import a persona
/persona:import

Export paths must be relative to the current working directory. Imported personas are validated against the persona schema before being saved to the registry.