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

18 KiB
Raw Blame History

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 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

# 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:

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.