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.
18 KiB
TUI Reference
The agents tui command launches the CleverAgents Terminal User Interface — a
full-screen, interactive application built on Textual.
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:
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
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 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 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
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
defaultpreset with emptyoverrides. cycle_ordervalues must be unique when greater than zero.actormust be namespaced:namespace/name.namemust 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
# 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-opusopenai/gpt-4oopenai/o3google/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:
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 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.