chore(cli): polish help and output #210

Open
opened 2026-02-22 23:40:08 +00:00 by freemo · 4 comments
Owner

Metadata

  • Commit Message: chore(cli): polish help and output
  • Branch: feature/m6-cli-polish

Background

CLI help text, progress indicators, and error messages are standardized across core commands. --format outputs are consistent (rich/color/table/plain/json/yaml) across all commands. plain format uses ASCII-only output for log pipeline compatibility.

Acceptance Criteria

  • Standardize help text, progress indicators, and error messages with recovery hints.
  • Ensure --format outputs are consistent (rich/color/table/plain/json/yaml) across core commands.
  • Ensure plain format uses ASCII-only output to support log pipelines.
  • Add stable column names and ordering for list commands (action list, plan list, project list, resource list).
  • Add --format json/yaml schema docs and align field names across commands.

Definition of Done

This issue is complete when:

  • All subtasks below are completed and checked off.
  • A Git commit is created where the first line of the commit message matches
    the Commit Message in Metadata exactly, followed by a blank line, then
    additional lines providing relevant details about the implementation. The
    commit body should be appropriate in size for a commit message and relatively
    complete in describing what was done.
  • The commit is pushed to the remote on the branch matching the Branch in
    Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and
    merged before this issue is marked done.

Subtasks

  • Standardize help text, progress indicators, and error messages with recovery hints.
  • Ensure --format outputs are consistent (rich/color/table/plain/json/yaml) across core commands.
  • Ensure plain format uses ASCII-only output to support log pipelines.
  • Add stable column names and ordering for list commands (action list, plan list, project list, resource list).
  • Add --format json/yaml schema docs and align field names across commands.
  • Add unified error envelope for JSON/YAML outputs (error.code, error.message, error.details).
  • Update CLI output examples where needed.
  • Add a CLI output contract section in docs/reference/cli_output.md.
  • Tests (Behave): Add features/cli_output_formats.feature covering rich/plain/json/yaml formatting for core commands.
  • Tests (Robot): Add CLI UX smoke tests for critical commands.
  • Tests (ASV): Add benchmarks/cli_render_bench.py for output rendering overhead.
  • Verify coverage >=97% via nox -s coverage_report. If coverage is <97% then review the current unit test coverage report at build/coverage.xml and use it to write new Behave based unit tests to improve code coverage. Specifically, write Behave style unit tests that are descriptively named and specifically improves coverage on whichever file has the most uncovered lines by writing tests that will target the uncovered lines in the report. Once that is done rerun nox -s coverage_report to verify all tests pass and coverage is above >=97%. Only mark this as complete once coverage is >=97%, if not repeat this task as many times as is needed until coverage reaches >=97%.
  • Run nox (all default sessions, including benchmark), fix any errors if needed ensuring nox passes across entire code base, do not ignore any failure even if it seems unrelated to this commit, fix it.

Section: #### M6: Autonomy Hardening + Server Stubs (Day 30)
Status: In Review

## Metadata - **Commit Message**: `chore(cli): polish help and output` - **Branch**: `feature/m6-cli-polish` ## Background CLI help text, progress indicators, and error messages are standardized across core commands. `--format` outputs are consistent (rich/color/table/plain/json/yaml) across all commands. `plain` format uses ASCII-only output for log pipeline compatibility. ## Acceptance Criteria - [x] Standardize help text, progress indicators, and error messages with recovery hints. - [x] Ensure `--format` outputs are consistent (rich/color/table/plain/json/yaml) across core commands. - [x] Ensure `plain` format uses ASCII-only output to support log pipelines. - [x] Add stable column names and ordering for list commands (`action list`, `plan list`, `project list`, `resource list`). - [x] Add `--format json/yaml` schema docs and align field names across commands. ## Definition of Done This issue is complete when: - All subtasks below are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. The commit body should be appropriate in size for a commit message and relatively complete in describing what was done. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. ## Subtasks - [x] Standardize help text, progress indicators, and error messages with recovery hints. - [x] Ensure `--format` outputs are consistent (rich/color/table/plain/json/yaml) across core commands. - [x] Ensure `plain` format uses ASCII-only output to support log pipelines. - [x] Add stable column names and ordering for list commands (`action list`, `plan list`, `project list`, `resource list`). - [x] Add `--format json/yaml` schema docs and align field names across commands. - [x] Add unified error envelope for JSON/YAML outputs (`error.code`, `error.message`, `error.details`). - [x] Update CLI output examples where needed. - [x] Add a CLI output contract section in `docs/reference/cli_output.md`. - [x] Tests (Behave): Add `features/cli_output_formats.feature` covering rich/plain/json/yaml formatting for core commands. - [x] Tests (Robot): Add CLI UX smoke tests for critical commands. - [x] Tests (ASV): Add `benchmarks/cli_render_bench.py` for output rendering overhead. - [x] Verify coverage >=97% via `nox -s coverage_report`. If coverage is <97% then review the current unit test coverage report at `build/coverage.xml` and use it to write new Behave based unit tests to improve code coverage. Specifically, write Behave style unit tests that are descriptively named and specifically improves coverage on whichever file has the most uncovered lines by writing tests that will target the uncovered lines in the report. Once that is done rerun `nox -s coverage_report` to verify all tests pass and coverage is above >=97%. Only mark this as complete once coverage is >=97%, if not repeat this task as many times as is needed until coverage reaches >=97%. - [x] Run `nox` (all default sessions, including benchmark), fix any errors if needed ensuring nox passes across **entire** code base, do not ignore any failure even if it seems unrelated to this commit, fix it. **Section**: #### M6: Autonomy Hardening + Server Stubs (Day 30) **Status**: In Review
freemo added this to the v3.5.0 milestone 2026-02-22 23:40:08 +00:00
freemo self-assigned this 2026-02-22 23:40:08 +00:00
Author
Owner

Expected completion updated (Day 15 rebaseline): Day 35 / 2026-03-15 (previously Day 31 / 2026-03-11)

**Expected completion updated (Day 15 rebaseline):** Day 35 / 2026-03-15 (previously Day 31 / 2026-03-11)
freemo added the due date 2026-03-09 2026-02-23 18:41:41 +00:00
freemo removed their assignment 2026-03-02 16:26:07 +00:00
Member

Implementation Notes

Core Change: Shared Renderer Layer (renderers.py)

Created src/cleveragents/cli/renderers.py as the single source of truth for all CLI output. The module provides:

  • ColumnSpec dataclass — Declares a table column with key, label, style, justify, truncate, and no_wrap attributes. Used by all list commands.
  • FieldSpec dataclass — Declares a detail-view field with key, label, multiline, and truncate attributes. Used by all show/create commands.
  • render_detail(data, title, fields, fmt) — Produces Rich Panel, plain key-value, JSON, or YAML from a single dict.
  • render_list(rows, columns, title, fmt) — Produces Rich Table, plain tabular, JSON array, or YAML list from a list of dicts. Column order is guaranteed identical across all formats because they all read from the same ColumnSpec list.
  • render_error(label, message, recovery, details, fmt) — Writes to stderr. For json/yaml formats, wraps in a unified envelope: {"error": {"code": ..., "message": ..., "details": ..., "recovery": ...}}.
  • render_success(message, fmt, data) — Green checkmark for rich, OK: ... for plain, data dict for JSON/YAML.
  • render_warning(message, fmt) — Yellow warning for rich, WARNING: ... for plain.
  • render_empty(entity_type, recovery, message, fmt) — Yellow "No X found." with optional custom message and recovery hint.
  • FORMAT_HELP — Single constant replacing 14 duplicated _FORMAT_HELP strings.

Refactored Commands (14 files)

All command files under src/cleveragents/cli/commands/ were refactored:

  • action.py, actor.py, invariant.py, lsp.py, validation.py — Removed module-level console = Console(), all output now through renderers.
  • project_context.py — Removed err_console.
  • plan.py — Only error/empty patterns replaced; kept console for streaming Live/Progress displays that require direct Rich control.
  • automation_profile.py, config.py, project.py, resource.py, session.py, skill.py, tool.py — Error and empty patterns replaced with renderer calls; some still retain console for complex Rich-specific output.

ASCII-Only Plain Format

Added _ascii_safe(text) helper in formatting.py that replaces non-ASCII characters with ?. Called in _format_plain() to guarantee log pipeline compatibility.

Pre-existing Fixes

  • server_mode test failures: Tests expected "disabled" but ~/.cleveragents/config.toml had server.url = "https://stub.example.com" set, causing resolve_server_mode() to return "stubbed". Fixed by patching resolve_server_mode to return "disabled" in affected step files.
  • Bandit B608 false positive: Added # nosec B608 to pre-existing SQL string construction in project.py (column names are hardcoded, not user input).

Test Console Patching Strategy

Since renderers now own the Console instances, test step files that previously patched module.console needed to ALSO patch renderers._console and renderers._err_console. Both the module's console attribute and the renderer's console must point to the same capture buffer for output to be captured correctly.

Nox Results

Session Result
lint All checks passed
typecheck 0 errors, 0 warnings
unit_tests 241 features, 7696 scenarios, 29865 steps, 0 failures
integration_tests 1042 tests, 1042 passed, 0 failed
coverage_report 97% (--fail-under=97 passed)
benchmark 1221+ benchmarks, all passed (~10 min)

PR

PR #521: #521

## Implementation Notes ### Core Change: Shared Renderer Layer (`renderers.py`) Created `src/cleveragents/cli/renderers.py` as the single source of truth for all CLI output. The module provides: - **`ColumnSpec` dataclass** — Declares a table column with `key`, `label`, `style`, `justify`, `truncate`, and `no_wrap` attributes. Used by all `list` commands. - **`FieldSpec` dataclass** — Declares a detail-view field with `key`, `label`, `multiline`, and `truncate` attributes. Used by all `show`/`create` commands. - **`render_detail(data, title, fields, fmt)`** — Produces Rich Panel, plain key-value, JSON, or YAML from a single dict. - **`render_list(rows, columns, title, fmt)`** — Produces Rich Table, plain tabular, JSON array, or YAML list from a list of dicts. Column order is guaranteed identical across all formats because they all read from the same `ColumnSpec` list. - **`render_error(label, message, recovery, details, fmt)`** — Writes to stderr. For `json`/`yaml` formats, wraps in a unified envelope: `{"error": {"code": ..., "message": ..., "details": ..., "recovery": ...}}`. - **`render_success(message, fmt, data)`** — Green checkmark for rich, `OK: ...` for plain, data dict for JSON/YAML. - **`render_warning(message, fmt)`** — Yellow warning for rich, `WARNING: ...` for plain. - **`render_empty(entity_type, recovery, message, fmt)`** — Yellow "No X found." with optional custom message and recovery hint. - **`FORMAT_HELP`** — Single constant replacing 14 duplicated `_FORMAT_HELP` strings. ### Refactored Commands (14 files) All command files under `src/cleveragents/cli/commands/` were refactored: - `action.py`, `actor.py`, `invariant.py`, `lsp.py`, `validation.py` — Removed module-level `console = Console()`, all output now through renderers. - `project_context.py` — Removed `err_console`. - `plan.py` — Only error/empty patterns replaced; kept `console` for streaming `Live`/`Progress` displays that require direct Rich control. - `automation_profile.py`, `config.py`, `project.py`, `resource.py`, `session.py`, `skill.py`, `tool.py` — Error and empty patterns replaced with renderer calls; some still retain `console` for complex Rich-specific output. ### ASCII-Only Plain Format Added `_ascii_safe(text)` helper in `formatting.py` that replaces non-ASCII characters with `?`. Called in `_format_plain()` to guarantee log pipeline compatibility. ### Pre-existing Fixes - **`server_mode` test failures**: Tests expected `"disabled"` but `~/.cleveragents/config.toml` had `server.url = "https://stub.example.com"` set, causing `resolve_server_mode()` to return `"stubbed"`. Fixed by patching `resolve_server_mode` to return `"disabled"` in affected step files. - **Bandit B608 false positive**: Added `# nosec B608` to pre-existing SQL string construction in `project.py` (column names are hardcoded, not user input). ### Test Console Patching Strategy Since renderers now own the `Console` instances, test step files that previously patched `module.console` needed to ALSO patch `renderers._console` and `renderers._err_console`. Both the module's console attribute and the renderer's console must point to the same capture buffer for output to be captured correctly. ### Nox Results | Session | Result | |---------|--------| | `lint` | All checks passed | | `typecheck` | 0 errors, 0 warnings | | `unit_tests` | 241 features, 7696 scenarios, 29865 steps, 0 failures | | `integration_tests` | 1042 tests, 1042 passed, 0 failed | | `coverage_report` | 97% (--fail-under=97 passed) | | `benchmark` | 1221+ benchmarks, all passed (~10 min) | ### PR PR #521: https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/521
Author
Owner

PM Status — Day 29 (2026-03-09)

@brent.edwards — Acknowledged your implementation completion for CLI help and output polish. The unified renderers.py layer and refactoring of 14 command files is a significant improvement to the codebase.

Quality gates: All nox sessions passing (lint, typecheck, 7696 scenarios, 1042 integration tests, 97% coverage, benchmarks) ✓

Note: PR #521 was submitted for this work but appears to have already been merged or closed. If it was merged, this issue should be moved to State/Completed. @brent.edwards — Can you confirm the merge status of PR #521?

If still open: Please ensure PR #521 is rebased against current master and conflict-free for final review.

**PM Status — Day 29 (2026-03-09)** @brent.edwards — Acknowledged your implementation completion for CLI help and output polish. The unified `renderers.py` layer and refactoring of 14 command files is a significant improvement to the codebase. **Quality gates:** All nox sessions passing (lint, typecheck, 7696 scenarios, 1042 integration tests, 97% coverage, benchmarks) ✓ **Note:** PR #521 was submitted for this work but appears to have already been merged or closed. If it was merged, this issue should be moved to State/Completed. @brent.edwards — Can you confirm the merge status of PR #521? **If still open:** Please ensure PR #521 is rebased against current master and conflict-free for final review.
freemo self-assigned this 2026-04-02 06:13:57 +00:00
Author
Owner

⚠️ Backlog Grooming Notice — Stale Issue

This issue has State/In Review with all subtasks checked off, but remains open. It was due on 2026-03-09 (over 3 weeks ago).

All acceptance criteria appear to be met. This issue may be blocked by open dependencies preventing closure. Please review:

  1. Check if the PR for branch feature/m6-cli-polish was merged
  2. If merged, close this issue
  3. If blocked by dependencies, identify which ones and update the issue

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: ca-backlog-groomer

⚠️ **Backlog Grooming Notice — Stale Issue** This issue has `State/In Review` with all subtasks checked off, but remains open. It was due on 2026-03-09 (over 3 weeks ago). All acceptance criteria appear to be met. This issue may be blocked by open dependencies preventing closure. Please review: 1. Check if the PR for branch `feature/m6-cli-polish` was merged 2. If merged, close this issue 3. If blocked by dependencies, identify which ones and update the issue --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-backlog-groomer
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

2026-03-09

Blocks
#397 Epic: Server & Autonomy Infrastructure
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#210
No description provided.