A2C CLI
Inspection, validation, and review-first planning commands for A2C-governed repositories.
All parsing and validation is delegated to a2c_core; a2c_cli orchestrates AI calls,
formats results, and performs explicit apply writes.
Command: a2c (package: a2c_cli)
Inspection commands
| Command | Purpose |
|---|---|
a2c validate | Validate config and planning artifacts |
a2c web-sources check | Lint [web:NNN] tags against docs/web-source-mapping.md (ADR-0011) |
a2c web-sources fetch | Fetch mapped URLs to local, git-sources, or S3 archive (ADR-0012) |
a2c web-sources recover | Report mapping gaps and point to recovery prompt (ADR-0011) |
a2c list epics | List epics (id, title, status) |
a2c list adrs | List ADRs under docs/adr/ (number, title, status) |
a2c list tasks | List tasks (id, title, status, epic_id) |
a2c list sprints | List sprints (id, title, status) |
a2c show epic <id> | Show one epic (front matter + body sections) |
a2c show task <id> | Show one task |
a2c show sprint <id> | Show one sprint |
a2c show draft-epic <id> | Show one proposed epic draft (not applied) |
a2c show draft-task-intake <draft-key> | Show one single-task intake draft (not applied) |
a2c show draft-task <epic-id> <index> | Show one decomposition task draft (not applied) |
a2c doctor | Repository structure health check |
a2c setup-dev | Re-run venv, pre-commit hooks, and stack profile setup when configured |
a2c version | Print product version |
a2c init | Minimal A2C scaffold in an empty directory (markers, config, planning dirs) |
a2c bootstrap | Full A2C adoption (ADR-0000, method assets, changelog, pre-commit) |
a2c migrate | Brownfield adoption into an existing repo (AI-guided batches; ADR-0018) |
a2c tui config --interactive | Guided Textual config setup (launches a2c-tui) |
a2c tui config --editor | Tree-based Textual config editor (launches a2c-tui) |
When the start path is not yet an A2C repository, a2c tui config and a2c-tui config behave the same: offer minimal init, then open the config wizard (see tui.md).
See tui.md for TUI modes, keyboard bindings, and architecture.
Init vs bootstrap
| Command | Scope |
|---|---|
a2c init | Minimal scaffold so tools recognize the repo: AGENTS.md, .a2c/config.yaml, planning/ dirs; writes .a2c/adoption.yaml with the current A2C version |
a2c bootstrap | Full adoption: runs init if needed, ADR-0000, docs/web-source-mapping.md, CHANGELOG.md, standard .pre-commit-config.yaml (A2C hooks, file hygiene, gitlint), .gitlint (Conventional Commits policy), .gitignore, scripts/setup-dev.*. Creates .venv/ when needed, installs pre-commit, and registers git hooks automatically when Python and git are available. Default: copies rules/, templates/, prompts/, profiles/, cursor/ into this repo. **`--with-ai-rules submodule |
Stack profiles (bootstrap)
Bundled stack profile ids (see ADR-0016):
| Profile id | Purpose |
|---|---|
python | Python src layout, pyproject.toml, Ruff pre-commit hooks, editable dev install, pytest doctor |
python-pypi | Composes python + portable release scripts (bump_release.py, verify_release_version.py) |
cpp-cmake-conan | (planned) CMake / Conan native stack |
python-cpp-extension | (planned) Hybrid Python + native (SWIG default) |
a2c bootstrap --path ./my-lib --profile python-pypi
a2c bootstrap --path ./my-lib --profile python-pypi --release-forge gitlab --release-project your-group/my-lib
a2c setup-dev --path ./my-lib
a2c doctor --path ./my-lib
When --profile is omitted, bootstrap stays stack-agnostic (ADR-0015 only). On re-bootstrap, an existing workflows.default_profile in config re-applies that profile unless --profile overrides it.
a2c setup-dev runs base venv + pre-commit install, then the configured stack profile setup() hook (for example editable pip install -e ".[dev]" for python). Consumer scripts/setup-dev.* delegate to a2c setup-dev when the CLI is on PATH.
After adoption, every a2c command (except init, bootstrap, setup-dev, and version) prints warnings when the running CLI version or installed AI rules (submodule/clone tag at tools/ai-rules/) no longer match the version recorded at init/bootstrap. Use a2c doctor for a structured report. See ADR-0013.
CLI journal: every a2c command that runs inside an A2C repository (or init / bootstrap against a target path) appends one event to .a2c/cli-journal.yaml: timestamp, command path, options, success flag, and tool version. The journal is intended to be committed for audit and debugging (see ADR-0014). a2c doctor reports the latest event.
Method assets for copy mode are resolved from A2C_METHOD_ROOT, the development a2c-workflow tree, or bundled templates (ADR/docs only when copy is unavailable).
Superbuild meta-repositories use eai-supmig bootstrap --with-ai-rules for workspace-level policy — not a2c bootstrap.
a2c init --path ./my-project
a2c bootstrap --path ./my-project --profile python
a2c bootstrap --path ./my-project --with-ai-rules submodule
a2c bootstrap --path ./my-project --with-ai-rules clone
a2c tui config --interactive --path ./my-project
Interactive terminals (TTY): a2c bootstrap with no mount flag prompts for copy (default), submodule, or clone. Non-interactive runs default to copy. --with-ai-rules without submodule|clone prompts for mount mode only (TTY) or errors (CI).
Inputs intake (after bootstrap)
If you have draft ADRs, architecture notes, or workflow material in a local inputs/ folder, migrate them into canonical paths with the inputs intake prompt, then add inputs/ to .gitignore.
Cursor (no copy-paste): in chat, @-reference the prompt and state the batch:
@prompts/bootstrap/inputs-intake.md
Start batch-intake-00: inventory inputs/ and produce a migration plan.
With --with-ai-rules submodule|clone, reference the mounted method repo:
@tools/ai-rules/prompts/bootstrap/inputs-intake.md
Start batch-intake-00: inventory inputs/ and produce a migration plan.
Full guide: workflow/inputs-intake.md. Prompt asset: pathname:///a2c-assets/prompts/bootstrap/inputs-intake.md.
Legacy repository adoption
For existing git repositories (brownfield), start with a2c migrate before or after bootstrap. It writes .a2c/migration.yaml, seeds planning/migration/legacy-adoption.md, and prints the next AI batch. Batch 00 produces an anchoring ADR plan; batch 02 creates retrospective Accepted ADRs from legacy code and migration-only inputs/ context (not committed).
a2c migrate --path .
a2c migrate --entry-path bootstrap-first --path .
a2c migrate --tier docs-only --path .
a2c migrate --status --path .
a2c migrate --reassess --path .
a2c migrate --reset --path . # TTY: type 'reset'
a2c migrate --reset --path . --reset-confirm reset # non-interactive
a2c migrate --complete-batch batch-migrate-00 --path .
Every mutating a2c migrate invocation (except --status) shows anchoring readiness warnings on a TTY and asks “Are you sure you want to continue?” — including --complete-batch and --reassess. Tools never block; they inform.
In Cursor:
@planning/migration/legacy-adoption.md
Start batch-migrate-00: inventory this repository and write the migration plan including anchoring ADR candidates.
Full guide: workflow/legacy-adoption.md. Prompt asset: pathname:///a2c-assets/prompts/bootstrap/legacy-adoption.md. ADR: ADR-0018.
Historical delivery metrics (Milestone 9)
| Command | Purpose |
|---|---|
a2c metrics collect | Collect per-task and aggregate metrics into .a2c/metrics/ |
a2c metrics show | Show summary of collected metrics (optional --sprint, --epic, --tag) |
a2c metrics query | Query collected metrics with filters, grouping, and export formats |
See metrics.md for definitions, storage layout, query examples, and limitations.
Epic → task decomposition (Milestone 4)
Review-first workflow: plan → validate → review → apply.
| Command | Purpose |
|---|---|
a2c plan decompose-epic <epic-id> | Propose task drafts for an epic (no writes) |
a2c apply tasks-from-epic <epic-id> | Apply the cached valid proposal into planning/tasks/ |
Use --path / -C to point at a repository root (default: current directory).
Standalone binary (PyInstaller)
Build a single-file a2c executable (Windows: a2c.exe; Linux/macOS: a2c):
pip install -e "./packages/a2c-core" -e "./packages/a2c-cli" -e ".[dev]"
python scripts/build_a2c_cli_binary.py --clean
Output: dist/binary/a2c (or dist/binary/a2c.exe on Windows).
On develop, master, and merge-request pipelines, GitLab CI builds Linux binaries and publishes pipeline artifacts:
| Job | Architecture | Artifact |
|---|---|---|
build:a2c-cli-binary | linux x64 (default shared runner) | dist/binary/a2c |
build:a2c-cli-binary-linux-arm64 | linux arm64 (saas-linux-small-arm64) | dist/binary/a2c |
Tagged releases (v*.*.*) also publish package:a2c-cli-binary (x64) and package:a2c-cli-binary-linux-arm64 artifacts (permanent on tagged releases).
The binary bundles a2c-cli, a2c-core, Typer, Pydantic, and bundled workflow prompts. It still operates on
A2C repository trees on disk (--path / -C); it does not embed project schemas from schemas/.
Standalone TUI binary (PyInstaller)
Build a single-file a2c-tui executable (Windows: a2c-tui.exe; Linux/macOS: a2c-tui):
pip install -e "./packages/a2c-core" -e "./packages/a2c-tui" -e ".[dev]"
python scripts/build_a2c_tui_binary.py --clean
Output: dist/binary/a2c-tui (or dist/binary/a2c-tui.exe on Windows).
GitLab CI publishes Linux binaries as pipeline artifacts:
| Job | Architecture | Artifact |
|---|---|---|
build:a2c-tui-binary | linux x64 | dist/binary/a2c-tui |
build:a2c-tui-binary-linux-arm64 | linux arm64 | dist/binary/a2c-tui |
Tagged releases also publish package:a2c-tui-binary and package:a2c-tui-binary-linux-arm64 artifacts (permanent on tagged releases).
Examples
# Propose tasks (mock provider for local dev/tests)
a2c plan decompose-epic epic-onboarding --provider mock
# Inspect one draft
a2c show draft-task epic-onboarding 1
# Apply after review
a2c apply tasks-from-epic epic-onboarding
Guarantees
- AI output is treated as untrusted until validated through
a2c_core. plannever writes intoplanning/tasks/.applyre-validates drafts and refuses to overwrite existing task files unless--force.- Proposals are cached under
.a2c/cache/decompose-epic/<epic-id>/as Markdown draft tasks.
Limitations (this milestone)
- One epic at a time; task drafts only (no Sprint planning).
- No live LLM provider wired yet — use
--provider mock(and optional--fixture). - No automatic people/team assignment.
See epic-decomposition.md for the full workflow.
Epic authoring (Milestone 6)
Review-first workflow: brief → plan → validate → review → apply.
| Command | Purpose |
|---|---|
a2c plan create-epic | Propose one epic draft from a brief (no writes) |
a2c show draft-epic <id> | Show the cached epic draft |
a2c apply draft-epic <id> | Apply the draft into planning/epics/ |
Provide exactly one input: --from-text, --from-file, or --stdin.
a2c plan create-epic --from-text "Add dark mode for low-light usage." --provider mock
a2c show draft-epic epic-dark-mode
a2c apply draft-epic epic-dark-mode
After apply, use the existing Epic → Tasks flow (plan decompose-epic, apply tasks-from-epic).
See epic-authoring.md for the full workflow.
Single-task intake (Milestone 8)
Review-first workflow for ad hoc tasks and bug reports: input → plan → validate → review → apply.
| Command | Purpose |
|---|---|
a2c plan create-task | Propose one task draft from raw input (no writes) |
a2c show draft-task-intake <draft-key> | Show the cached task intake draft |
a2c apply draft-task <draft-key> | Apply the draft into planning/tasks/ (id allocated at apply) |
Provide exactly one input: --from-text, --from-file, --from-task-json, or --stdin. Use --type bug or --bug for bug templates. Optional --epic <id> links to an existing epic.
a2c plan create-task --from-text "Add health check endpoint for /api/status" --provider mock
a2c plan create-task --from-task-json ./task.json
a2c show draft-task-intake add-health-check-endpoint
a2c apply draft-task add-health-check-endpoint
a2c plan create-task --from-text "User reports 500 on profile save" --type bug
See task-authoring.md for the full workflow.
Epic decomposition providers (Milestone 5)
| Provider | Notes |
|---|---|
mock | Default; --fixture for Cursor-as-model |
openai | Requires OPENAI_API_KEY |
local | Requires --endpoint or A2C_LOCAL_LLM_ENDPOINT |
ollama | Preset for Ollama /v1; probes OLLAMA_HOST |
Resolution: --provider > decomposition.provider in config > mock.
a2c plan decompose-epic epic-onboarding --provider openai
a2c plan decompose-epic epic-onboarding --provider ollama --model llama3.2
General examples
a2c validate
a2c validate -C /path/to/repo
a2c list epics
a2c list tasks
a2c list sprints
a2c show epic epic-m2-contracts
a2c show task task-define-models
a2c show sprint sprint-m2
a2c doctor
Exit codes (CI)
| Code | Meaning |
|---|---|
0 | Success |
1 | Validation, decomposition, or apply check failed |
2 | Not inside an A2C repository |
3 | Artifact not found (show, unknown epic) |
5 | No valid cached proposal (apply, show draft-epic, show draft-task) |
Example CI step:
a2c validate || exit 1
Warnings (for example recommended ID shape) do not fail validate; errors do.
Core mapping
| CLI | a2c_core service |
|---|---|
validate | inspect_repository() / validate_repository() |
list, show | inspect_repository() → RepositorySnapshot |
doctor | check_repository_health() |
plan create-epic | create_epic_from_brief() + provider |
apply draft-epic | apply_epic_draft() |
show draft-epic | get_cached_epic_draft() |
plan create-task | create_task_from_input() + provider, or create_task_from_task_json() |
apply draft-task | apply_task_intake_draft() |
show draft-task-intake | get_cached_task_intake_draft() |
plan decompose-epic | decompose_epic() + provider |
apply tasks-from-epic | apply_tasks_from_epic() |
show draft-task | get_cached_proposal() |
JSON output (--json)
Read-only inspection commands emit the C4 envelope documented in architecture/initial-contracts.md:
| Command | command field |
|---|---|
a2c doctor --json | repo.doctor |
a2c validate --json | repo.validate |
a2c list epics --json | artifact.list.epics |
a2c list tasks --json | artifact.list.tasks |
a2c list sprints --json | artifact.list.sprints |
a2c list adrs --json | artifact.list.adrs |
a2c show epic <id> --json | artifact.show.epic |
a2c show task <id> --json | artifact.show.task |
a2c show sprint <id> --json | artifact.show.sprint |
a2c config show --json | config.show |
a2c config catalog --json | config.catalog |
a2c config validate --json | config.validate |
a2c config save --stdin --json | config.save |
Example:
a2c validate --path . --json
Deferred (later milestones)
- Native Ollama SDK (
a2c-core[ollama]) — seeplans/milestone-ollama-native-sdk.md - Sprint creation and assignment
- TUI integration