Files
cleveragents-core/docs/adr/ADR-021-cli-and-output-rendering.md
T
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

8.9 KiB

adr_number, title, status_history, tier, authors, superseded_by, related_adrs, acceptance
adr_number title status_history tier authors superseded_by related_adrs acceptance
21 CLI and Output Rendering
2026-02-16
Proposed
Jeffrey Phillips Freeman
2026-02-16
Accepted
Jeffrey Phillips Freeman
4
Jeffrey Phillips Freeman
null
number title relationship
1 Layered Architecture The CLI resides in the Presentation Layer and calls into Application Layer facades
number title relationship
5 Technical Stack Typer and Rich are the chosen CLI and rendering libraries
number title relationship
24 Configuration System CLI flags participate in the five-tier configuration resolution chain
votes_for votes_against abstentions
voter comment
Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com> The noun-verb command pattern with six output formats covers both human and machine consumers well

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.