dgenio / dgenio/contextweaver

Standardize machine-readable CLI output: --json on all subcommands, documented exit codes, shell completion

Open
#536 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/cli complexity:complex developer-experience enhancement priority: medium
Dominant language
Python
Stars
9
Forks
17
Avg merge
21h 36m
Merged PRs (30d)
22

Description

Summary

Bring the CLI to a consistent scripting contract: every subcommand that produces data supports --json, exit codes are defined and documented, and shell completion (already available via Typer) is documented and verified.

Priority: P2 · Confidence: Medium

Why this matters

The CLI is a primary adopter touchpoint and increasingly an automation surface (CI checks, budget gates, pipelines). Today --json exists on some commands but not others, so scripts must scrape Rich-formatted text for the rest; exit-code semantics are implicit, so budget-check-style gating in user CI is guesswork. A uniform contract makes every subcommand composable and is cheap to deliver because the pattern already exists in-tree.

Current evidence

  • src/contextweaver/__main__.py: --json options exist at lines ~465 and ~570 (route and one other command), while stats uses a --format rich|text enum (lines ~433–447) and build / ingest / replay / eval / budget-check have no machine-readable mode (verified by search — only two json_output declarations).
  • Two different conventions already coexist (--json flag vs --format enum) — an inconsistency to resolve deliberately.
  • No exit-code documentation anywhere in README/docs for the CLI.
  • Adjacent open issues: #398 (new inspect command) and #395 (gateway doctor) will both want this contract; neither defines it.

External context

CLI conventions for tooling consumed by scripts: stable JSON on stdout, human rendering elsewhere or behind a flag, exit 0 success / documented non-zero classes. Typer provides --install-completion out of the box — it only needs docs and a smoke test.

Proposed implementation

  1. Decide the convention (recommend --json everywhere; keep --format as alias where it exists, fold via the deprecation machinery later).
  2. Add --json to build, ingest, replay, stats, eval, budget-check — emitting the existing to_dict() payloads (BuildStats, eval reports, etc.); JSON goes to stdout, logs/progress to stderr.
  3. Define and document exit codes: 0 success; 1 check-failed (budget-check over budget, eval below threshold); 2 usage error (Typer default); 3 input/data error. Audit current behavior against this and adjust.
  4. Document contextweaver --install-completion in README/quickstart; add a CLI-reference docs section listing every subcommand's JSON shape and exit codes.

AI-agent execution notes

  • Inspect first: __main__.py end-to-end (all 10 subcommands + the mcp sub-app), _mcp_cli.py, existing json_output implementations as the pattern, tests/test_cli.py.
  • Run: pytest tests/test_cli.py tests/test_mcp_serve_cli.py -q; manual contextweaver build --json | python -m json.tool smoke for each command.
  • Add tests: each subcommand's --json output parses and contains expected keys; exit codes per class (use CliRunner); stdout purity (no Rich artifacts in JSON mode).
  • Preserve: default human-readable output unchanged; print() exemption applies only to __main__.py/_demos.py.
  • Do not redesign command semantics — output/exit contract only.

Acceptance criteria

  • All data-producing subcommands support --json with parseable, documented output.
  • Exit-code table documented and enforced by tests.
  • Completion installation documented and smoke-tested.

Test plan

CliRunner-based tests per command for JSON validity and exit codes; a round-trip test (build --json output consumed by route/stats where applicable); full make ci.

Documentation plan

New "CLI reference" docs page (or README CLI section expansion) with the contract table; CHANGELOG.

Migration and compatibility notes

Human-readable defaults unchanged. If any current non-zero exit behavior shifts to match the documented classes, list each change in CHANGELOG. --format remains as a deprecated alias until the deprecation machinery handles it.

Risks and tradeoffs

JSON shapes become a compatibility surface — anchor them to the existing to_dict() serializations (already schema-governed via make schemas) rather than inventing CLI-specific shapes. Two-convention cleanup creates minor churn now to avoid permanent inconsistency.

Suggested labels

developer-experience, enhancement, area/cli

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Inspect src/contextweaver/main.py end to end, _mcp_cli.py, existing json_output implementations, and tests/test_cli.py plus tests/test_mcp_serve_cli.py. Run the named pytest suites first and use the existing to_dict() payloads as the reference. Done means every data-producing subcommand has parseable documented JSON, tested exit codes, clean stdout, documented completion, and unchanged human-readable defaults.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, developer-experience, documentation, testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.