# TUI Reference The `agents tui` command launches the **CleverAgents Terminal User Interface** — a full-screen, interactive application built on [Textual](https://textual.textualize.io/). The TUI provides real-time plan monitoring, multi-session management, persona switching, and rich conversation with actors in a single terminal window. ## Installation The TUI requires the optional `tui` extra: ```bash pip install 'cleveragents[tui]' ``` Without this extra, `agents tui` raises an actionable error: ``` RuntimeError: Textual dependency missing. Install with: pip install 'cleveragents[tui]' ``` ## Launching the TUI ```bash agents tui ``` ### Options | Flag | Description | |------|-------------| | `--headless` | Run a one-shot startup check without opening the full UI loop (useful for CI smoke tests) | ## Layout The TUI is composed of the following regions, rendered top-to-bottom: ``` ┌─────────────────────────────────────────────────────┐ │ Header (clock) │ ├─────────────────────────────────────────────────────┤ │ Conversation area │ │ ┌─────────────────────────────────────────────┐ │ │ │ Help Panel Overlay (F1, hidden by default) │ │ │ └─────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────┐ │ │ │ Reference Picker Overlay (@) │ │ │ └─────────────────────────────────────────────┘ │ │ ┌─────────────────────────────────────────────┐ │ │ │ Slash Command Overlay (/) │ │ │ └─────────────────────────────────────────────┘ │ │ Prompt Input │ │ Persona Bar │ ├─────────────────────────────────────────────────────┤ │ Footer (key bindings) │ └─────────────────────────────────────────────────────┘ ``` ## Global Key Bindings | Key | Action | |-----|--------| | `Ctrl+Q` | Quit the TUI immediately | | `F1` | Toggle the context-sensitive help panel | | `Ctrl+T` | Cycle to the next argument preset for the active persona | | `Escape` | Close the current overlay and return to the prompt | ## Input Modes The prompt detects the input mode from the first character of the text: | Prefix | Mode | Behaviour | |--------|------|-----------| | *(none)* | **Normal** | Message text with optional `@reference` expansion | | `/` | **Command** | Slash command dispatched to the command router | | `!` or `$` | **Shell** | Shell command executed via subprocess | ### Normal Mode Type a message and press `Enter` to submit. Use `@` to open the Reference Picker overlay and insert file, resource, or plan references inline. ### Command Mode (`/`) Type `/` to open the Slash Command overlay. A filtered list of matching commands appears as you type. Press `Enter` to dispatch the selected command. See [Slash Commands](#slash-commands) for the full catalog. ### Shell Mode (`!`) Type `!` followed by a shell command to execute it in a subprocess. Output is captured and displayed in the conversation area. !!! warning "Shell mode safety" Shell execution is gated by the `CLEVERAGENTS_ALLOW_DANGEROUS_SHELL` environment variable. Set it to `1` or `true` to permit shell commands. When unset, shell commands are blocked. Before execution, the command is scanned by the **shell danger detection** subsystem. If a dangerous pattern is matched (e.g. `rm -rf /`, fork bombs, pipe-to-shell), a warning overlay is shown with the danger level and a description of the risk. The user can cancel or proceed. See [Shell Danger Detection](tui_shell_safety.md) for the full reference, including the built-in pattern registry and how to add custom patterns. ## Help Panel (F1) Press `F1` at any time to toggle the context-sensitive help panel. The panel content adapts to the current prompt context: | Context | Triggered when | |---------|---------------| | **Main Screen** | Prompt is empty or contains normal text | | **Slash Commands** | Prompt starts with `/` | | **Reference Picker** | Prompt contains `@` | | **Shell Mode** | Prompt starts with `!` or `$` | Each context shows global key bindings plus context-specific shortcuts. ## Persona Bar The status bar at the bottom of the conversation area displays: ``` | | | scope refs ``` - **persona_name** — the active persona (e.g. `default`) - **actor_name** — the actor bound to the persona (e.g. `openai/gpt-4o`) - **preset_name** — the active argument preset (e.g. `default`) - **scope refs** — count of scoped projects and plans Use `Ctrl+T` to cycle through the argument presets defined in the active persona. ## Slash Commands The TUI ships with **67 slash commands** across **14 groups**. Type `/` in the prompt to open the overlay and filter by name. ### Session | Command | Description | |---------|-------------| | `/session:create` | Create a new session tab | | `/session:list` | Display all sessions | | `/session:show` | Show session details | | `/session:switch` | Switch to a session | | `/session:close` | Close the current session | | `/session:delete` | Delete a saved session | | `/session:rename` | Rename current session | | `/session:export` | Export session to JSON | | `/session:import` | Import session from JSON | ### Persona | Command | Description | |---------|-------------| | `/persona:list` | Display all personas | | `/persona:set` | Switch active persona | | `/persona:create` | Create a persona | | `/persona:edit` | Edit a persona | | `/persona:delete` | Delete a persona | | `/persona:export` | Export persona YAML | | `/persona:import` | Import persona YAML | ### Scope | Command | Description | |---------|-------------| | `/scope:add` | Add scope reference | | `/scope:remove` | Remove scope reference | | `/scope:clear` | Clear session scope additions | | `/scope:show` | Show effective scope | ### Plan | Command | Description | |---------|-------------| | `/plan:use` | Start a new plan | | `/plan:list` | List plans | | `/plan:status` | Show plan status | | `/plan:tree` | Show decision tree | | `/plan:execute` | Execute a plan | | `/plan:apply` | Apply a completed plan | | `/plan:cancel` | Cancel a plan | | `/plan:diff` | Show plan diff | | `/plan:correct` | Correct a decision | | `/plan:resume` | Resume a plan | | `/plan:revert` | Revert plan state | | `/plan:rollback` | Rollback to checkpoint | | `/plan:explain` | Explain a decision | | `/plan:errors` | Show plan errors | | `/plan:artifacts` | Show plan artifacts | | `/plan:inspect` | Inspect plan details | ### Project | Command | Description | |---------|-------------| | `/project:list` | List projects | | `/project:create` | Create project | | `/project:show` | Show project details | | `/project:delete` | Delete project | | `/project:inspect` | Inspect project details | | `/project:context:show` | Show project context policy | ### Actor | Command | Description | |---------|-------------| | `/actor:list` | List actors | | `/actor:show` | Show actor details | | `/actor:set-default` | Set default actor | ### Resource | Command | Description | |---------|-------------| | `/resource:list` | List resources | | `/resource:show` | Show resource details | | `/resource:tree` | Show resource tree | | `/resource:inspect` | Inspect resource details | ### Config | Command | Description | |---------|-------------| | `/config:list` | List config entries | | `/config:get` | Get config value | | `/config:set` | Set config value | ### Tool | Command | Description | |---------|-------------| | `/tool:list` | List tools | | `/tool:show` | Show tool details | ### Skill | Command | Description | |---------|-------------| | `/skill:list` | List skills | | `/skill:show` | Show skill details | ### Invariant | Command | Description | |---------|-------------| | `/invariant:list` | List invariants | | `/invariant:add` | Add invariant | | `/invariant:remove` | Remove invariant | ### Profile | Command | Description | |---------|-------------| | `/profile:list` | List automation profiles | | `/profile:show` | Show automation profile | ### Context | Command | Description | |---------|-------------| | `/context:inspect` | Inspect context state | | `/context:set` | Set context policy | | `/context:simulate` | Simulate context assembly | ### Utility | Command | Description | |---------|-------------| | `/clear` | Clear conversation display | | `/theme` | Switch color theme | | `/settings` | Open settings | | `/help` | Show help | | `/about` | Show version information | | `/debug` | Toggle debug mode | ## Persona System Personas are YAML configuration files stored in `~/.config/cleveragents/personas/` (overridable via `CLEVERAGENTS_CONFIG_DIR`). Each persona binds an actor, optional argument presets, and scope references to a named identity. ### Persona YAML Schema ```yaml name: my-persona # Required. Must not contain path separators. actor: openai/gpt-4o # Required. Must be namespaced (namespace/name). description: "My persona" # Optional. icon: "" # Optional display icon. color: null # Optional terminal color. base_arguments: {} # Default arguments merged into every request. scoped_projects: [] # Project names always in scope. scoped_plans: [] # Plan IDs always in scope. cycle_order: 0 # Position in Ctrl+T cycle (0 = excluded). greeting: "" # Optional greeting message on activation. argument_presets: # Named argument override sets. - name: default # Required. Must have empty overrides. display: default overrides: {} - name: verbose display: Verbose overrides: verbosity: high ``` ### Rules - Every persona must contain exactly one `default` preset with empty `overrides`. - `cycle_order` values must be unique when greater than zero. - `actor` must be namespaced: `namespace/name`. - `name` must not contain `/`, `\`, `..`, null bytes, or control characters. ### Persona State The TUI tracks the active persona and current preset per session in memory. The last-used persona name is persisted to `~/.config/cleveragents/tui-state.yaml` and restored on the next launch. ### Import / Export ```bash # Export a persona to a file /persona:export # then provide name and output path # Import a persona from a file /persona:import # then provide the YAML file path ``` Export and import paths must be relative to the current working directory. ## Architecture The TUI is implemented as a Textual `App` subclass (`CleverAgentsTuiApp`) in `src/cleveragents/tui/app.py`. It communicates with the application layer exclusively through the A2A local facade — the same protocol used by the CLI. Key modules: | Module | Purpose | |--------|---------| | `tui/app.py` | Main Textual app, widget composition, key bindings | | `tui/persona/schema.py` | `Persona` and `PersonaPreset` Pydantic models | | `tui/persona/registry.py` | YAML-backed persona storage with file locking | | `tui/persona/state.py` | In-memory session-to-persona mapping | | `tui/input/modes.py` | `InputModeRouter` — normal / command / shell dispatch | | `tui/input/reference_parser.py` | `@reference` expansion and fuzzy suggestions | | `tui/input/shell_exec.py` | Subprocess shell execution with safety gate | | `tui/slash_catalog.py` | `SLASH_COMMAND_SPECS` — 67-command catalog | | `tui/widgets/help_panel_overlay.py` | Context-sensitive F1 help panel | | `tui/widgets/persona_bar.py` | Bottom status bar showing active persona | | `tui/widgets/prompt.py` | Prompt input widget | | `tui/widgets/reference_picker.py` | `@reference` picker overlay | | `tui/widgets/slash_command_overlay.py` | `/command` picker overlay | | `tui/widgets/thought_block.py` | Expandable actor reasoning trace widget | | `tui/permissions/models.py` | `ToolPermissionRequest`, `PermissionDecision`, `DiffDisplayMode` | | `tui/permissions/screen.py` | `PermissionsScreen` — split-pane diff view for tool permission requests | | `tui/permissions/service.py` | `PermissionRequestService` — request queue and session-scoped decisions | | `tui/widgets/permission_question.py` | `PermissionQuestionWidget` — inline single-file permission request widget | | `tui/widgets/actor_selection_overlay.py` | `ActorSelectionOverlay` — first-run actor selection overlay | | `tui/shell_safety/pattern_detector.py` | `DangerousPatternDetector` — shell command danger detection | | `tui/shell_safety/pattern_registry.py` | `DEFAULT_PATTERNS` — built-in dangerous shell pattern registry | | `tui/first_run.py` | `is_first_run()`, `create_default_persona_for_actor()` — first-run helpers | ## First-Run Experience On first launch — when no personas are configured — the TUI displays the `ActorSelectionOverlay` in the centre of the screen. The overlay guides the user to select an actor from a curated list: - `anthropic/claude-4-sonnet` *(recommended)* - `anthropic/claude-4-opus` - `openai/gpt-4o` - `openai/o3` - `google/gemini-2` **Key bindings inside the overlay:** | Key | Action | |-----|--------| | `j` / `↓` | Move selection down | | `k` / `↑` | Move selection up | | `/` | Enter search mode to filter actors | | `Enter` | Confirm the highlighted actor | After confirmation, a `"default"` persona is created and the overlay is dismissed. Subsequent launches restore the last active persona from `~/.config/cleveragents/tui-state.yaml`. **Module**: `cleveragents.tui.widgets.actor_selection_overlay` The `ActorSelectionOverlay` widget exposes: | Property / Method | Description | |-------------------|-------------| | `actors` | Full (unfiltered) actor list | | `filtered_actors` | Currently filtered actor list | | `selected_index` | Zero-based index of the highlighted actor | | `search_query` | Active search filter string | | `confirmed` | `True` if the user has confirmed a selection | | `selected_actor` | Confirmed actor name, or `None` if not yet confirmed | | `show(actors?)` | Display the overlay, optionally overriding the actor list | | `hide()` | Hide the overlay | | `move_up()` / `move_down()` | Navigate the list | | `set_search(query)` | Apply a substring filter (case-insensitive) | | `confirm()` | Confirm the highlighted actor; returns the actor name or `None` | The first-run detection helper is in `cleveragents.tui.first_run`: ```python from cleveragents.tui.first_run import is_first_run, create_default_persona_for_actor if is_first_run(registry): # Show ActorSelectionOverlay, then: persona = create_default_persona_for_actor(registry, "openai/gpt-4o") ``` --- ## 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](tui_permission_question.md) 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`](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`](tui_thought_block.md) for the full API reference. ## Related Documentation - [ADR-044: TUI Architecture and Framework](../adr/ADR-044-tui-architecture-and-framework.md) - [ADR-045: TUI Persona System](../adr/ADR-045-tui-persona-system.md) - [ADR-046: TUI Reference and Command System](../adr/ADR-046-tui-reference-and-command-system.md) - [TUI Permissions Screen](tui_permissions.md) - [TUI Permission Question Widget](tui_permission_question.md) - [TUI Shell Danger Detection](tui_shell_safety.md) - [TUI Thought Blocks](tui_thought_block.md) - [Session CLI Reference](session_cli.md) - [Output Rendering Framework](output_rendering.md) - [REPL Reference](repl.md)