Files
freemo 71177c6e1a
CI / lint (push) Failing after 18s
CI / build (push) Successful in 18s
CI / helm (push) Successful in 29s
CI / quality (push) Successful in 37s
CI / security (push) Failing after 52s
CI / typecheck (push) Failing after 58s
CI / coverage (push) Has been skipped
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Failing after 1m58s
CI / docker (push) Has been skipped
CI / benchmark-publish (push) Has been cancelled
CI / e2e_tests (push) Has been cancelled
CI / integration_tests (push) Has been cancelled
CI / status-check (push) Has been cancelled
docs: update changelog, API docs, and architecture for 2026-04-02 merged PRs
- CHANGELOG: add [Unreleased] entries for TUI first-run experience (#1391),
  session Markdown export (#1004), and UKO provenance/temporal versioning (#891)
- README: add first-run experience and Markdown transcript export bullets
- docs/api/tui.md: new TUI API reference covering first-run, persona system,
  input routing, slash commands, session export/import, and widgets
- docs/api/index.md: add TUI entry to module index
- docs/api/resource.md: document DatabaseResourceHandler and DevcontainerHandler
  full protocol implementations with method tables and examples
- docs/architecture.md: expand UKO section with provenance/temporal versioning
  details; update TUI design decision summary
- mkdocs.yml: add TUI page to API Reference nav

ISSUES CLOSED: #1391 #1004 #891
2026-04-02 19:30:53 +00:00

5.8 KiB

cleveragents.tui — Interactive Terminal UI

The tui package provides the full-screen Textual-based terminal user interface. It requires the optional cleveragents[tui] extra.

See ADR-044 (TUI framework), ADR-045 (persona system), and ADR-046 (reference and command system) for design rationale.


Launching the TUI

pip install "cleveragents[tui]"
agents tui

First-Run Experience

is_first_run(registry: PersonaRegistry) → bool

Returns True when no personas are configured — used by app.on_mount() to decide whether to show the actor selection overlay.

create_default_persona_for_actor(registry: PersonaRegistry, actor: str) → None

Creates and persists a "default" persona bound to actor after the user completes the first-run selection flow.

ActorSelectionOverlay

from cleveragents.tui.widgets import ActorSelectionOverlay

A centred Textual widget displayed on first launch.

Method Description
show() Make the overlay visible
hide() Dismiss the overlay
move_up() Move selection cursor up (wraps)
move_down() Move selection cursor down (wraps)
set_search(query: str) Apply fuzzy filter to actor list
confirm() → str Confirm selection; returns actor name and hides overlay
render_actor_selection() → str Pure rendering function (testable without Textual)

Default actor list (in display order):

Actor Notes
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 down
k / Move up
/ Enter fuzzy search
Enter Confirm selection

Persona System

Personas are YAML files stored in ~/.config/cleveragents/personas/. Each persona binds an actor, optional argument presets, and scope references to a named identity.

PersonaRegistry

from cleveragents.tui.persona import PersonaRegistry

registry = PersonaRegistry()
registry.load()                          # load all YAML files from config dir
persona = registry.get("default")       # retrieve by name
registry.save(persona)                  # persist changes
registry.ensure_default(actor="openai/gpt-4o")  # create default if absent

Persona

@dataclass
class Persona:
    name: str
    actor: str
    presets: list[ArgumentPreset]
    scope_refs: list[str]

Input Mode Routing

The prompt auto-detects three input modes from the first character:

First character Mode Handler
(none / letter) Normal Message + @reference expansion
/ Command Slash command overlay
! Shell Subprocess passthrough

InputModeRouter

from cleveragents.tui.routing import InputModeRouter

router = InputModeRouter(container)
await router.dispatch(input_text, session_id)

Slash Commands

67 slash commands across 14 groups are exposed via SlashCommandOverlay.

from cleveragents.tui.commands import SLASH_COMMAND_SPECS

# SLASH_COMMAND_SPECS: dict[str, list[SlashCommandSpec]]
# Keys are group names; values are lists of command specs.

Groups: Session, Persona, Scope, Plan, Project, Actor, Resource, Config, Tool, Skill, Invariant, Profile, Context, Utility.

Session commands (via TuiCommandRouter)

Command Description
/session:export [--format json|md] [path] Export session to JSON or Markdown
/session:import <path> Import a session from a JSON file
# Export as Markdown transcript
/session:export --format md ~/my-session.md

# Export as canonical JSON (default)
/session:export ~/my-session.json

# Import a previously exported session
/session:import ~/my-session.json

Session Export / Import

Session.as_export_markdown() → str

Domain method on Session that renders a human-readable Markdown transcript. The output is lossy (for sharing/documentation) and cannot be re-imported.

from cleveragents.domain.models.core.session import Session

session: Session = ...
md = session.as_export_markdown()
# Returns a Markdown string with:
# - Header block: session ID, actor, created_at, message count
# - Message history: role | timestamp | content
# - Linked plan references

CLI

# Export as canonical JSON (importable)
agents session export --session-id <ID> --output session.json

# Export as Markdown transcript (human-readable, not importable)
agents session export --session-id <ID> --output session.md --format md

# Import from JSON
agents session import --input session.json

Widgets

ThoughtBlockWidget

Renders actor reasoning traces inline in the conversation stream.

from cleveragents.tui.widgets import ThoughtBlockWidget
  • Collapsed by default; press Space to expand/collapse
  • Muted styling distinguishes thought blocks from regular messages
  • Backed by ThoughtBlock domain model with configurable max_lines (default: 10)

PermissionsScreen

Full-screen overlay for tool permission requests.

from cleveragents.tui.screens import PermissionsScreen
Key Action
a Allow once
A Allow always
r Reject once
R Reject always
d Cycle diff display mode (unified → side-by-side → context)

TUI State Persistence

The TUI persists minimal state to ~/.config/cleveragents/tui-state.yaml:

last_persona: "default"

This is loaded on startup to restore the last active persona.