Files
cleveragents-core/docs/adr/ADR-021-cli-and-output-rendering.md
freemo d5b122d4a3
CI / lint (push) Successful in 14s
CI / quality (push) Successful in 21s
CI / security (push) Successful in 36s
CI / build (push) Successful in 36s
CI / typecheck (push) Successful in 39s
CI / benchmark-regression (push) Has been skipped
CI / unit_tests (push) Successful in 2m57s
CI / integration_tests (push) Successful in 3m23s
CI / docker (push) Successful in 53s
CI / coverage (push) Successful in 5m58s
CI / benchmark-publish (push) Successful in 19m27s
Docs: Updated to A2A and integrating rest standard
2026-03-11 13:19:55 -04:00

172 lines
8.9 KiB
Markdown

---
adr_number: 21
title: CLI and Output Rendering
status_history:
- - '2026-02-16'
- Proposed
- Jeffrey Phillips Freeman
- - '2026-02-16'
- Accepted
- Jeffrey Phillips Freeman
tier: 4
authors:
- Jeffrey Phillips Freeman
superseded_by: null
related_adrs:
- number: 1
title: Layered Architecture
relationship: The CLI resides in the Presentation Layer and calls into Application Layer facades
- number: 5
title: Technical Stack
relationship: Typer and Rich are the chosen CLI and rendering libraries
- number: 24
title: Configuration System
relationship: CLI flags participate in the five-tier configuration resolution chain
acceptance:
votes_for:
- voter: Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>
comment: The noun-verb command pattern with six output formats covers both human and machine consumers well
votes_against: []
abstentions: []
---
## Context
CleverAgents is a CLI-first application. The command-line interface is the primary entry point for all user interaction — creating actions, managing projects, executing plans, configuring the system, and reviewing results. The CLI must support a large number of entity types and operations, provide consistent command structure, and render output in multiple formats (human-readable terminal output, structured JSON/YAML for scripting, plain text for piping).
## Decision Drivers
- The CLI is the primary entry point for all user interaction and must scale to many entity types and operations
- Output must serve both human consumers (styled terminal) and machine consumers (JSON/YAML for scripting)
- Command structure must be consistent and predictable across a large number of entity types
- Entity definitions must be versionable and reviewable, favoring YAML-first registration over CLI-only creation
- Log output and structured command output must be cleanly separated (stderr vs. stdout)
## Decision
The CLI uses **Typer** (>= 0.9.0) with the `agents <noun> <verb>` command pattern. Output rendering supports **six formats** (`rich`, `color`, `table`, `plain`, `json`, `yaml`) selectable via the `--format` flag or `core.format` configuration key. Rich (via Typer's built-in integration) provides styled terminal rendering with panels, tables, trees, syntax highlighting, progress spinners, and markdown.
## Design
### Command Structure
All commands follow the `agents <noun> <verb>` pattern:
```
agents plan create|use|execute|apply|show|list|correct|cancel
agents action create|show|list|remove
agents project create|link|unlink|show|list|remove|context
agents actor add|show|list|remove
agents tool add|show|list|remove
agents skill add|show|list|remove
agents validation add|attach|detach|show|list|remove
agents resource add|show|list|remove
agents resource-type add|show|list|remove
agents invariant add|remove|list|show
agents session new|list|show|resume|archive
agents config set|get|list
agents automation-profile add|show|list|remove
```
Typer's nested command group support maps directly to this pattern. Each noun is a Typer command group; each verb is a command within that group.
### Six Output Formats
| Format | Description | Use Case |
|--------|-------------|----------|
| `rich` | Full Rich rendering: panels, tables, trees, syntax highlighting, spinners | Interactive terminal use (default) |
| `color` | Colored text without Rich panels/tables | Simpler terminals |
| `table` | Tabular output using Rich Table | Data comparison, tabular listings |
| `plain` | Plain unformatted text | Piping to other tools, logs |
| `json` | Structured JSON output | Scripting, API integration, `jq` processing |
| `yaml` | Structured YAML output | Configuration review, human-readable structured data |
The format is resolved per-invocation: `--format` CLI flag > `CLEVERAGENTS_FORMAT` env var > `core.format` config key > default (`rich`).
### Global CLI Flags
| Flag | Description |
|------|-------------|
| `--format` | Output format (6 options) |
| `--data-dir` | Override `core.data-dir` |
| `--config-path` | Override `core.config-path` |
| `-v` through `-vvvvv` | Verbosity (ERROR → WARN → INFO → DEBUG → TRACE) |
### Phase Transition Verbs
The CLI verbs for plan lifecycle transitions are semantic — they describe the user's intent, not the internal phase name:
| Verb | Meaning |
|------|---------|
| `create` | Create an action (template) |
| `use` | Apply an action to a project → enters Strategize |
| `execute` | Begin execution of the strategy → enters Execute |
| `apply` | Commit sandbox changes to real resources → enters Apply |
There is no `strategize` command — `use` implicitly transitions to the Strategize phase.
### Entity Configuration Pattern
For entity registration commands (`agents actor add`, `agents tool add`, etc.), the CLI requires a `--config <FILE>` flag pointing to a YAML configuration file that fully defines the entity. CLI flags alongside `--config` serve as optional overrides for values in the YAML. This ensures that YAML is the complete, versionable entity definition.
### Rich Rendering Components
The Rich library (transitive via Typer) provides:
- **Panel**: Bordered information blocks for plan summaries, decision details.
- **Table**: Structured tabular output for listings and comparisons.
- **Tree**: Hierarchical display for decision trees, plan hierarchies, skill composition.
- **Syntax**: Syntax-highlighted code display for diffs, file contents.
- **Progress / Spinner**: Progress indication during long-running operations.
- **Markdown**: Rendered markdown for documentation and descriptions.
### Future Presentation Surfaces
The architecture supports additional presentation surfaces without modifying the Application Layer:
- **Textual TUI**: Reactive terminal UI using the same Rich primitives.
- **Textual Web**: TUI served as a web application.
- **IDE Plugin**: Embedded TUI integration.
- **A2A Server**: JSON-RPC 2.0 endpoint for server mode.
All presentation surfaces consume the same Application Layer service facades.
## Constraints
- All CLI commands must follow the `agents <noun> <verb>` pattern. No top-level verbs without a noun group.
- Every command that produces output must support all six output formats. The `--format` flag must be available on every output-producing command.
- Entity registration commands must accept `--config <FILE>` as the primary definition mechanism. CLI-only entity creation (without a YAML file) is not supported for registered entities.
- Structured formats (`json`, `yaml`) must produce machine-parseable output with no intermixed human-readable text, progress indicators, or log messages.
- Log output from `-v` flags goes to stderr (or the configured `core.log.terminal-stream`), never to stdout, to avoid contaminating structured output.
## Consequences
### Positive
- The `agents <noun> <verb>` pattern provides a consistent, predictable command structure that scales to many entity types.
- Six output formats support both interactive use and scripting/automation without separate APIs.
- Typer's type inference from Python type hints reduces CLI boilerplate and ensures argument validation.
- The YAML-first entity registration pattern makes entity definitions versionable and reviewable.
### Negative
- Typer's abstraction occasionally limits fine-grained control over help text formatting and argument parsing.
- Supporting six output formats for every command increases the implementation and testing surface.
- The `agents <noun> <verb>` pattern can produce long commands for complex operations.
### Risks
- Adding new entity types or verbs could create command namespace conflicts if naming is not carefully managed.
- Rich rendering assumes a modern terminal with Unicode and ANSI color support. Minimal terminals may produce garbled output.
- The separation of log output (stderr) from command output (stdout) may confuse users who are not familiar with this pattern.
## Alternatives Considered
**Click (without Typer)** — Typer is built on Click and provides automatic type inference, Rich integration, and more concise command definitions. Using Click directly would require more boilerplate for the same functionality.
**`--json` flag instead of `--format`** — A boolean `--json` flag was considered but rejected in favor of the more general `--format` flag that supports six formats including `yaml`, `table`, and `plain`.
## Compliance
- **Command structure tests**: Tests verify that all commands follow the `agents <noun> <verb>` pattern and that help text is generated correctly.
- **Format tests**: Each output-producing command is tested with all six format options to verify correct output structure.
- **Structured output tests**: Tests verify that `json` and `yaml` outputs are valid, parseable, and contain no non-structured content.
- **Stderr separation tests**: Tests verify that `-v` log output goes to stderr and does not appear in stdout when `--format json` is used.
- **BDD scenarios**: Behave features exercise CLI workflows end-to-end with various format options.