From 3c741d926d1f165c93483087eaa45adb3de26a2f Mon Sep 17 00:00:00 2001 From: Jeffrey Phillips Freeman Date: Thu, 2 Apr 2026 08:08:31 +0000 Subject: [PATCH] docs: add v3.7.0 release documentation and TUI reference - CHANGELOG.md: add v3.7.0 release section documenting TUI milestone (M8) with Added/Changed/Fixed/Security categories covering all major changes from the Unreleased section relevant to this release - README.md: add Feature Overview table, TUI quick-start guide with keybinding reference, and first-plan walkthrough; fix clone URL - docs/reference/tui.md: new TUI reference covering installation, launch, keybindings, input modes (@-references, /commands, !-shell), slash command catalog (67 commands / 14 groups), widget inventory, and source locations - docs/reference/tui_persona.md: new persona system reference covering Persona schema, PersonaRegistry, PersonaState, slash commands, and default persona behaviour --- CHANGELOG.md | 68 +++++++++++ README.md | 69 ++++++++++- docs/reference/tui.md | 212 ++++++++++++++++++++++++++++++++++ docs/reference/tui_persona.md | 119 +++++++++++++++++++ 4 files changed, 466 insertions(+), 2 deletions(-) create mode 100644 docs/reference/tui.md create mode 100644 docs/reference/tui_persona.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 36aab2df1..5caff02f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,74 @@ ## Unreleased +## v3.7.0 — TUI Implementation (2026-04-02) + +This release delivers the full Text User Interface (TUI) milestone (M8) per +ADR-044, ADR-045, and ADR-046. The TUI is built on Textual and provides an +interactive terminal application with persona management, slash commands, +context-sensitive help, and fuzzy reference resolution. + +### Added + +- **TUI application** (`agents tui`): Textual-based interactive terminal UI + with `CleverAgentsTuiApp`, graceful fallback when Textual is not installed, + and a `--headless` mode for startup diagnostics. (#695) +- **Input mode routing**: Three distinct input modes — Normal (`@` references), + Command (`/` slash commands), and Shell (`!` passthrough) — dispatched by + `InputModeRouter` with mode auto-detection. (#695) +- **Persona system**: YAML-backed persona registry (`PersonaRegistry`) with + atomic file writes, file-lock safety, and per-session state tracking + (`PersonaState`). Personas carry actor bindings, argument presets, scoped + project/plan lists, and cycle ordering. (#695) +- **Slash command catalog**: 67 slash commands across 14 groups (Session, + Persona, Scope, Plan, Project, Actor, Resource, Config, Tool, Skill, + Invariant, Profile, Context, Utility) defined in `SlashCommandSpec` + descriptors. (#1002) +- **Slash command overlay**: Interactive overlay widget (`SlashCommandOverlay`) + with fuzzy filtering and keyboard navigation. (#695) +- **Reference picker overlay**: `@`-triggered overlay (`ReferencePickerOverlay`) + for resolving project/plan/resource/actor/tool/skill references with + filesystem-backed catalog and 5-second TTL cache. (#695) +- **Fuzzy search**: `score_match` and `rank_candidates` helpers with + prefix/substring/path-component/difflib scoring and recency boosting. (#695) +- **Context-sensitive help panel**: `F1`-toggled `HelpPanelOverlay` with + mode-aware content (Main Screen, Slash Commands, Reference Picker, Shell + Prompt) and global keybinding reference. (#1013) +- **Persona bar widget**: `PersonaBar` status widget displaying active persona + name, icon, and current argument preset. (#695) +- **Prompt widget**: `PromptInput` with mode indicator and submit handling. (#695) +- **TUI command router**: `TuiCommandRouter` dispatching `/persona` and + `/session` slash commands with DI container integration. (#695) + +### Changed + +- `agents actor run` now takes positional `` and `` arguments, + aligning with the specification. The previous `--prompt/-p` option is + removed. (#901) +- `SandboxManager.commit_all()` is now an all-or-nothing atomic operation per + specification line 45938. Partial failures trigger LIFO rollback of already- + committed sandboxes. (#925) +- `resource_selection` decision type reclassified as phase-agnostic (valid in + both Strategize and Execute phases), aligning with ADR-007 and ADR-033. (#931) + +### Fixed + +- Execution environment resolution now honours project-level override + (precedence level 2) per the 6-level precedence chain. (#1080) +- `project context set` missing `--execution-env-priority` flag — setting is + now persisted and displayed by `project context show`. (#1079) +- `list_actions()` now queries the database when persistence is enabled so + actions created by prior CLI invocations are visible. (#760) +- `shell=True` subprocess usage in `cli_coverage_steps.py` replaced with + `shlex.split()` and `shell=False` for command injection prevention. (#734) + +### Security + +- Template rendering hardened with sandboxed Jinja2 renderer denying attribute + access, function calls, and filters. (#319) +- `CleverAgentsError` base class introduced with structured error types and + secret redaction in error details. (#320) + - Added a context-sensitive TUI help panel overlay toggled by `F1`, with help content that varies for main-screen, slash-command, reference, and shell prompt modes. Updated Behave and Robot coverage for help-panel diff --git a/README.md b/README.md index db49367ee..c505ed2cb 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,32 @@ CleverAgents is a Python-first automation platform. It provides a unified `agent - Unified CLI entry points: `cleveragents` and `agents` - Fast Typer/Click-based interface with parity for help/version behavior +- **Interactive TUI** (`agents tui`) built on Textual with persona management, slash commands, and fuzzy reference resolution - Behavior-driven coverage via Behave and Robot Framework - Nox automation for linting, typing, testing, docs, builds, and benchmarks - MkDocs-powered documentation with CleverAgents branding +## Feature Overview + +| Feature | Description | +|---------|-------------| +| **Plan lifecycle** | Full strategize → execute → apply pipeline with LLM actors | +| **Actor system** | YAML-defined actors compiled to LangGraph graphs | +| **Skill registry** | Composable skill bundles with MCP, file, git, and inline tools | +| **Resource system** | DAG-based resource registry with 30+ built-in types (git, fs, container, LSP) | +| **Automation profiles** | Named profiles (manual, cautious, supervised, auto, ci, full-auto) controlling autonomy | +| **Sandbox & checkpoint** | Copy-on-write, overlay-fs, git-worktree, and transaction sandbox strategies | +| **ACMS** | Advanced Context Management System with UKO ontology and 10-stage assembly pipeline | +| **TUI** | Textual terminal UI with personas, slash commands, and `@`-reference picker | +| **A2A / Server** | Agent-to-Agent protocol facade; Kubernetes Helm chart for server deployment | +| **Observability** | LangSmith tracing, structured logging via structlog, audit event bus | + ## Quick Start ```bash # clone the CleverAgents core repository -git clone https://git.cleverthis.com/cleveragents/core.git -cd core +git clone https://git.cleverthis.com/cleveragents/cleveragents-core.git +cd cleveragents-core # install dependencies python -m venv .venv @@ -30,6 +46,55 @@ agents --help agents --version ``` +### First plan + +```bash +# initialise the local database +agents init + +# register a project +agents project create local/my-project --description "My first project" + +# add a git resource +agents resource add git-checkout local/my-repo --url https://github.com/example/repo.git + +# link resource to project +agents project link-resource local/my-project local/my-repo + +# create an action +agents action create --config examples/actions/simple.yaml + +# start a plan +agents plan use local/my-action --project local/my-project + +# execute the plan (requires an LLM API key) +agents plan execute +``` + +### Interactive TUI + +```bash +# install the optional Textual dependency +pip install 'cleveragents[tui]' + +# launch the TUI +agents tui + +# headless startup check (no Textual required) +agents tui --headless +``` + +Inside the TUI: + +| Key / Prefix | Action | +|---|---| +| `F1` | Toggle context-sensitive help panel | +| `/` | Open slash command overlay (67 commands) | +| `@` | Open reference picker (projects, plans, resources, …) | +| `!` | Shell passthrough mode | +| `Tab` | Cycle to next persona | +| `Ctrl+Q` | Quit | + ## Developing Pre-commit hooks run automatically on every `git commit` (formatting, linting, type diff --git a/docs/reference/tui.md b/docs/reference/tui.md new file mode 100644 index 000000000..fb89338b8 --- /dev/null +++ b/docs/reference/tui.md @@ -0,0 +1,212 @@ +# TUI — Text User Interface + +The CleverAgents TUI is a Textual-based interactive terminal application +launched with `agents tui`. It provides a full-screen chat-style interface +with persona management, slash commands, `@`-reference resolution, and +context-sensitive help. + +**ADRs**: [ADR-044](../adr/ADR-044-tui-architecture-and-framework.md), +[ADR-045](../adr/ADR-045-tui-persona-system.md), +[ADR-046](../adr/ADR-046-tui-reference-and-command-system.md) + +## Installation + +Textual is an optional dependency: + +```bash +pip install 'cleveragents[tui]' +``` + +Without Textual, `agents tui` raises a `RuntimeError` with installation +instructions. The `--headless` flag works without Textual and is useful for +CI startup checks. + +## Launching + +```bash +# Full interactive TUI +agents tui + +# Headless startup check — prints JSON diagnostics and exits +agents tui --headless +``` + +The `--headless` output includes: + +```json +{ + "textual_available": true, + "persona_count": 2, + "default_persona": "default", + "help": "Commands: /persona, /session, /help" +} +``` + +## Keybindings + +| Key | Action | +|-----|--------| +| `F1` | Toggle context-sensitive help panel | +| `Escape` | Close current overlay / return to prompt | +| `Enter` | Submit prompt | +| `Tab` | Cycle to next persona | +| `Ctrl+Tab` | Cycle to next argument preset | +| `Ctrl+Q` | Quit TUI immediately | + +## Input Modes + +The prompt auto-detects the input mode from the first character: + +| Prefix | Mode | Behaviour | +|--------|------|-----------| +| *(none)* | **Normal** | Expands `@`-references and sends to the active actor | +| `/` | **Command** | Opens slash command overlay; dispatches on `Enter` | +| `!` or `$` | **Shell** | Executes the remainder as a shell command | + +Mode detection is handled by `InputModeRouter.detect_mode()`. + +### Normal mode — `@` references + +Type `@` followed by a partial name to open the Reference Picker overlay. +Candidates are drawn from a filesystem-backed catalog (projects, plans, +resources, actors, tools, skills) with a 5-second TTL cache. Fuzzy matching +uses prefix → substring → path-component → difflib scoring with recency +boosting. + +``` +@my-proj # resolves to project:local/my-project +@main-repo # resolves to resource:local/main-repo +``` + +Resolved references are expanded inline before the prompt is submitted. + +### Command mode — `/` slash commands + +Type `/` to open the Slash Command overlay. Start typing to filter the 67 +available commands across 14 groups. Press `Enter` to dispatch. + +See [Slash Commands](#slash-commands) for the full catalog. + +### Shell mode — `!` passthrough + +``` +! git status +! ls -la +``` + +The command is executed in a subprocess with a configurable timeout +(default: 30 seconds). Output is displayed in the transcript. + +## Slash Commands + +67 commands across 14 groups. All commands follow the `group:action` naming +convention. + +| Group | Commands | +|-------|---------| +| **Session** | `session:create`, `session:list`, `session:show`, `session:switch`, `session:close`, `session:delete`, `session:rename`, `session:export`, `session:import` | +| **Persona** | `persona:list`, `persona:set`, `persona:create`, `persona:edit`, `persona:delete`, `persona:export`, `persona:import` | +| **Scope** | `scope:add`, `scope:remove`, `scope:clear`, `scope:show` | +| **Plan** | `plan:use`, `plan:list`, `plan:status`, `plan:tree`, `plan:execute`, `plan:apply`, `plan:cancel`, `plan:diff`, `plan:correct`, `plan:resume`, `plan:revert`, `plan:rollback`, `plan:explain`, `plan:errors`, `plan:artifacts`, `plan:inspect` | +| **Project** | `project:list`, `project:create`, `project:show`, `project:delete`, `project:inspect`, `project:context:show` | +| **Actor** | `actor:list`, `actor:show`, `actor:set-default` | +| **Resource** | `resource:list`, `resource:show`, `resource:tree`, `resource:inspect` | +| **Config** | `config:list`, `config:get`, `config:set` | +| **Tool** | `tool:list`, `tool:show` | +| **Skill** | `skill:list`, `skill:show` | +| **Invariant** | `invariant:list`, `invariant:add`, `invariant:remove` | +| **Profile** | `profile:list`, `profile:show` | +| **Context** | `context:inspect`, `context:set` | +| **Utility** | `help`, `clear`, `exit` | + +## Widgets + +### `CleverAgentsTuiApp` + +The root Textual application. Composes: + +- `Header` — application title bar +- `PersonaBar` — active persona name, icon, and preset indicator +- `PromptInput` — multi-mode prompt with mode indicator +- `SlashCommandOverlay` — `/`-triggered command picker +- `ReferencePickerOverlay` — `@`-triggered reference picker +- `HelpPanelOverlay` — `F1`-toggled context-sensitive help +- `Footer` — keybinding hints + +### `PersonaBar` + +Displays the active persona's `icon` and `name` plus the current argument +preset name. Updates automatically when the persona or preset changes. + +### `PromptInput` + +Single-line input widget. Displays a mode indicator (`>` normal, `/` command, +`!` shell) and emits `InputSubmittedEvent` on `Enter`. + +### `SlashCommandOverlay` + +Fuzzy-filtered list of all 67 slash commands. Keyboard-navigable. Dismissed +by `Escape`. + +### `ReferencePickerOverlay` + +Fuzzy-filtered list of catalog entries. Dismissed by `Escape` or on +reference selection. + +### `HelpPanelOverlay` + +Context-sensitive help panel. Content varies by current mode: + +- **Main Screen** — global keybindings + main-screen shortcuts +- **Slash Commands** — slash command navigation hints +- **Reference Picker** — reference picker navigation hints +- **Shell Prompt** — shell mode usage notes + +## Source Locations + +``` +src/cleveragents/tui/ +├── app.py # CleverAgentsTuiApp, SessionView, _FallbackCleverAgentsTuiApp +├── commands.py # TuiCommandRouter, run_tui() +├── slash_catalog.py # SLASH_COMMAND_SPECS, SlashCommandSpec +├── cleveragents.tcss # Textual CSS stylesheet +├── input/ +│ ├── modes.py # InputMode, InputModeRouter, ModeResult +│ ├── reference_parser.py # ReferenceMatch, ReferenceParseResult, parse_references() +│ └── shell_exec.py # ShellResult, run_shell_command() +├── persona/ +│ ├── schema.py # Persona, PersonaPreset +│ ├── registry.py # PersonaRegistry +│ └── state.py # PersonaState +├── search/ +│ └── fuzzy.py # FuzzyCandidate, score_match(), rank_candidates() +└── widgets/ + ├── help_panel_overlay.py # HelpPanelOverlay, resolve_help_context() + ├── persona_bar.py # PersonaBar + ├── prompt.py # PromptInput + ├── reference_picker.py # ReferencePickerOverlay + └── slash_command_overlay.py # SlashCommandOverlay +``` + +## Running Tests + +### Behave (BDD unit tests) + +```bash +nox -s unit_tests -- features/tui_persona.feature +nox -s unit_tests -- features/tui_slash_commands.feature +nox -s unit_tests -- features/tui_input_modes.feature +``` + +### Robot Framework (smoke / integration tests) + +```bash +nox -s integration_tests -- robot/tui_smoke.robot +``` + +## Related + +- [Persona System](tui_persona.md) — detailed persona management reference +- [ADR-044](../adr/ADR-044-tui-architecture-and-framework.md) — TUI architecture decisions +- [ADR-045](../adr/ADR-045-tui-persona-system.md) — persona system design +- [ADR-046](../adr/ADR-046-tui-reference-and-command-system.md) — reference and command system diff --git a/docs/reference/tui_persona.md b/docs/reference/tui_persona.md new file mode 100644 index 000000000..b14478316 --- /dev/null +++ b/docs/reference/tui_persona.md @@ -0,0 +1,119 @@ +# TUI Persona System + +Personas are named configurations that bind a TUI session to a specific actor, +argument preset, and project/plan scope. They are stored as YAML files under +`~/.config/cleveragents/personas/` and managed by `PersonaRegistry`. + +**ADR**: [ADR-045](../adr/ADR-045-tui-persona-system.md) + +## Persona Schema + +```yaml +name: my-persona # required; no path separators or control chars +description: "..." # optional human-readable description +icon: "🤖" # optional display icon +actor: openai/gpt-4o # required; must be namespaced (namespace/name) +color: "#4CAF50" # optional hex color for UI theming +base_arguments: # default CLI argument overrides + format: json + log_level: warning +scoped_projects: # project names pre-loaded into session scope + - local/my-project +scoped_plans: # plan IDs pre-loaded into session scope + - 01JXYZ... +argument_presets: # named override bundles (Tab cycles through these) + - name: default + display: "default" + overrides: {} + - name: verbose + display: "verbose" + overrides: + log_level: debug + format: rich +cycle_order: 0 # sort order for Tab cycling (lower = earlier) +greeting: "Hello!" # optional greeting shown on persona activation +``` + +### Field validation + +| Field | Constraint | +|-------|-----------| +| `name` | Non-empty; no `/`, `\`, `..`, null bytes, or control characters | +| `actor` | Must contain `/` (namespaced reference) | +| `argument_presets` | Auto-populated with a `default` preset if empty | + +## PersonaRegistry + +`PersonaRegistry` manages YAML files in `~/.config/cleveragents/personas/` +(overridable via `CLEVERAGENTS_CONFIG_DIR`). + +### Key methods + +| Method | Description | +|--------|-------------| +| `list_personas()` | Return all valid personas sorted by `cycle_order` then `name` | +| `get(name)` | Return a `Persona` by name, or `None` if not found | +| `save(persona)` | Atomically write persona YAML (temp-file + rename) | +| `delete(name)` | Remove persona YAML file | +| `ensure_default()` | Create and return the built-in `default` persona if absent | +| `get_last_persona()` | Return the last-active persona name from `tui-state.yaml` | +| `set_last_persona(name)` | Persist the last-active persona name | + +File writes use `fcntl.LOCK_EX` for concurrent-access safety and an atomic +temp-file rename pattern to prevent partial writes. + +## PersonaState + +`PersonaState` tracks the active persona and argument preset per TUI session +in memory. It is not persisted across TUI restarts (the last-active persona +name is persisted separately via `PersonaRegistry.set_last_persona()`). + +### Key methods + +| Method | Description | +|--------|-------------| +| `active_name(session_id)` | Return the active persona name for a session | +| `active_persona(session_id)` | Return the full `Persona` object | +| `set_active_persona(session_id, name)` | Switch active persona; raises `ValueError` if unknown | +| `current_preset(session_id)` | Return the active preset name | +| `cycle_preset(session_id)` | Advance to the next preset in the persona's list | + +## Slash commands + +Personas are managed via `/persona:*` slash commands in the TUI: + +| Command | Description | +|---------|-------------| +| `/persona:list` | Display all personas | +| `/persona:set ` | Switch active persona | +| `/persona:create` | Create a new persona | +| `/persona:edit ` | Edit an existing persona | +| `/persona:delete ` | Delete a persona | +| `/persona:export ` | Export persona YAML to stdout | +| `/persona:import` | Import persona YAML from stdin | + +## Default persona + +If no personas exist, `PersonaRegistry.ensure_default()` creates a built-in +`default` persona bound to the globally configured default actor. This ensures +the TUI always has at least one usable persona on first launch. + +## Source Locations + +``` +src/cleveragents/tui/persona/ +├── schema.py # Persona, PersonaPreset (Pydantic models) +├── registry.py # PersonaRegistry (YAML file management) +└── state.py # PersonaState (in-memory session tracking) +``` + +## Running Tests + +```bash +nox -s unit_tests -- features/tui_persona.feature +``` + +## Related + +- [TUI Overview](tui.md) — full TUI reference +- [ADR-045](../adr/ADR-045-tui-persona-system.md) — persona system design decisions -- 2.52.0