Files
cleveragents-core/docs/reference/tui.md
T
freemo dd17d0f8e6
CI / lint (push) Has been cancelled
CI / typecheck (push) Has been cancelled
CI / security (push) Has been cancelled
CI / quality (push) Has been cancelled
CI / benchmark-publish (push) Has been cancelled
CI / unit_tests (push) Has been cancelled
CI / integration_tests (push) Has been cancelled
CI / e2e_tests (push) Has been cancelled
CI / build (push) Has been cancelled
CI / helm (push) Has been cancelled
CI / coverage (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / status-check (push) Has been cancelled
CI / benchmark-regression (push) Has been cancelled
docs(tui): add shell safety, permission question widget, and first-run docs
Add reference documentation for three new TUI features:

- docs/reference/tui_shell_safety.md: Full reference for the shell danger
  detection subsystem (DangerousPatternDetector, ShellDangerLevel,
  DangerousPattern, DangerousCommandWarning, DEFAULT_PATTERNS registry).
  Covers all built-in patterns across CRITICAL/HIGH/MEDIUM/LOW levels,
  usage examples, and custom pattern extension.

- docs/reference/tui_permission_question.md: Full reference for the inline
  PermissionQuestionWidget (issue #997). Documents InlinePermissionQuestion,
  PermissionRequestType, PermissionDecision, render_permission_question(),
  PermissionDecisionEvent, and PermissionQuestionWidget with key bindings
  and usage examples.

- docs/reference/tui.md: Extended with First-Run Experience section
  (ActorSelectionOverlay, first_run helpers), Inline Permission Questions
  section, shell danger detection note in Shell Mode, updated module table,
  and links to new reference pages.
2026-04-03 18:01:26 +00:00

503 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:
```
<persona_name> | <actor_name> | <preset_name> | <N> 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)