diff --git a/.github/workflows/lint-docs.yml b/.github/workflows/lint-docs.yml index 9349b40..1293ff9 100644 --- a/.github/workflows/lint-docs.yml +++ b/.github/workflows/lint-docs.yml @@ -4,7 +4,7 @@ on: push: branches: - main - - develop + - dev paths: - '**.md' - '.markdownlint.json' diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..3a13f8b --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,29 @@ +# Roadmap + +The APS roadmap lives in [`plans/index.aps.md`](plans/index.aps.md) — we use APS +to plan APS. + +## Quick Overview + +| Horizon | Focus | Status | +|---------|-------|--------| +| **v0.2 Usability** | Scaffold, templates, docs, validation | Done | +| **v0.3 Distribution** | Install overhaul, multi-harness agents | Current | +| **Future** | GitHub Action, VS Code extension, formal spec | Planned | + +See [plans/index.aps.md](plans/index.aps.md) for the full breakdown with modules, +status, and work items. + +## Non-Goals + +These are explicitly out of scope: + +- **Execution engines** — APS describes intent; it doesn't run code +- **Vendor plugins** — No Jira/Linear/Notion plugins (specs are portable markdown) +- **AI training** — Not a dataset for model fine-tuning +- **Hosted services** — No cloud component; everything runs locally + +## Contributing + +Have ideas for the roadmap? [Open an issue](https://github.com/EddaCraft/anvil-plan-spec/issues) +to discuss, or submit a PR updating [plans/index.aps.md](plans/index.aps.md). diff --git a/aps-planning/SKILL.md b/aps-planning/SKILL.md index dc98d03..8bc9471 100644 --- a/aps-planning/SKILL.md +++ b/aps-planning/SKILL.md @@ -55,11 +55,19 @@ Before planning, understand what exists: ``` 1. Check: Does plans/ directory exist? -2. Check: Does plans/index.aps.md exist? -3. Check: Are there module files in plans/modules/? -4. Check: Are there design docs in designs/? -5. Read plans/aps-rules.md if present (agent guidance) -6. Identify: Is this new work or continuing existing work? +2. If plans/ does not exist → run: aps init + (This bootstraps the APS structure. If aps is not on PATH, check bin/aps in the anvil-plan-spec repo or run: curl -fsSL https://raw.githubusercontent.com/EddaCraft/anvil-plan-spec/main/install.sh | sh) + After init completes, continue to step 3. +3. Check: Does plans/.aps-version exist? + If it exists, read the version. Current APS version is 0.2.0. + If the version in .aps-version is lower than 0.2.0 → run: aps update + (This updates templates, the skill file, and tool files to the current spec version.) + After update completes, continue to step 4. +4. Check: Does plans/index.aps.md exist? +5. Check: Are there module files in plans/modules/? +6. Check: Are there design docs in designs/? +7. Read plans/aps-rules.md if present (agent guidance) +8. Identify: Is this new work or continuing existing work? ``` ### 2. Plan (pick the right template) diff --git a/bin/aps b/bin/aps index 443dc2f..c7cc87d 100755 --- a/bin/aps +++ b/bin/aps @@ -3,8 +3,9 @@ # APS CLI - Anvil Plan Spec tooling # # Usage: -# aps init [dir] Create APS structure in a new project -# aps update [dir] Update templates, skill, and commands +# aps init [dir] Create APS structure in a new project (v2 layout) +# aps update [dir] Update templates, skill, and tool files +# aps migrate [dir] Convert v1 layout to v2 # aps lint [file|dir] Validate APS documents (default: plans/) # aps lint --json Output as JSON # aps --help Show this help @@ -38,8 +39,9 @@ show_help() { aps - Anvil Plan Spec CLI Usage: - aps init [dir] Create APS structure in a new project - aps update [dir] Update templates, skill, and commands + aps init [dir] Create APS structure in a new project (v2 layout) + aps update [dir] Update templates, skill, and tool files + aps migrate [dir] Convert v1 layout to v2 (.aps/ consolidation) aps lint [file|dir] Validate APS documents aps lint --json Output results as JSON aps --help Show this help @@ -52,8 +54,11 @@ Environment: APS_VERSION Git ref to download from (default: main) Examples: - aps init # Init in current directory - aps update # Update templates and skill + aps init # Interactive wizard (v2 layout) + aps init --profile solo --scope small --tools claude-code + aps update # Update templates and tool files + aps migrate # Convert v1 -> v2 + aps migrate --dry-run # Preview migration aps lint # Lint plans/ directory aps lint plans/index.aps.md # Lint specific file aps lint . --json # Lint current dir, JSON output @@ -72,6 +77,10 @@ main() { shift cmd_update "$@" ;; + migrate) + shift + cmd_migrate "$@" + ;; lint) shift cmd_lint "$@" diff --git a/docs/agent-testing.md b/docs/agent-testing.md new file mode 100644 index 0000000..e1cd7aa --- /dev/null +++ b/docs/agent-testing.md @@ -0,0 +1,167 @@ +# Agent Cross-Harness Test Plan + +Test plan for AGENT-006: verifying APS agents work correctly in each tool's +environment. + +## Test Matrix + +| Tool | Agent Format | Test Method | Status | +|------|-------------|-------------|--------| +| Claude Code | `.claude/agents/*.md` | Task dispatch in live project | Validated | +| Codex | `.codex/agents/*.toml` + config | `/agent spawn` | Manual (needs Codex) | +| Copilot | `.github/agents/*.md` | Agent discovery | Manual (needs Copilot) | +| OpenCode | `.opencode/agents/*.md` | `@mention` invocation | Manual (needs OpenCode) | +| Gemini | `.gemini/skills/*/SKILL.md` | `gemini skills link` | Manual (needs Gemini) | + +## Automated Validation (Complete) + +### Build Script + +- [x] `build.sh` runs without errors +- [x] `build.sh` is idempotent (running twice produces identical output) +- [x] All 14 output files generated (2 core + 2 Claude Code + 2 Copilot + 2 + OpenCode + 3 Codex + 2 Gemini verified) + +### Format Validation + +**Claude Code:** + +- [x] YAML frontmatter: `name`, `description`, `model`, `tools` +- [x] Model values use valid shorthand (`opus`, `sonnet`) +- [x] Tools list matches expected (planner: +Task, librarian: no Task) + +**Copilot:** + +- [x] YAML frontmatter: `name`, `description` only +- [x] No unsupported fields (model, tools) +- [x] Body identical to Claude Code variant + +**OpenCode:** + +- [x] YAML frontmatter: `description`, `mode`, `model`, `steps`, `tools`, + `permission` +- [x] `mode: subagent` (not primary) +- [x] Model uses `provider/model-id` format (`anthropic/claude-opus-4-6`, + `anthropic/claude-sonnet-4-6`) +- [x] No `name` field (filename-derived) +- [x] Permission maps set dangerous tools to `"ask"` + +**Codex:** + +- [x] TOML format with `sandbox_mode` and `developer_instructions` +- [x] Config snippet has correct `[agents.*]` blocks +- [x] `o4-mini` model (OpenAI — commented for clarity) +- [x] Developer instructions contain full core prompt + +**Gemini:** + +- [x] Pure markdown (no YAML frontmatter) +- [x] Self-contained (condensed, not a core prompt copy) +- [x] Covers key responsibilities in skill-appropriate format + +### Content Validation + +**Planner (all variants):** + +- [x] Project init +- [x] Index/module/work-item creation +- [x] Status tracking +- [x] Work item execution +- [x] Wave-based parallel coordination +- [x] Action plan support +- [x] References `plans/` paths (D-017 compliance) +- [x] Does not duplicate SKILL.md content + +**Librarian (all variants):** + +- [x] Archiving completed modules +- [x] Orphan detection +- [x] Cross-reference maintenance +- [x] Stale doc flagging +- [x] References `plans/` paths (D-017 compliance) + +## Manual Test Procedures + +### Claude Code + +```bash +# 1. Copy agents to test project +cp scaffold/agents/claude-code/aps-planner.md /tmp/test-project/.claude/agents/ +cp scaffold/agents/claude-code/aps-librarian.md /tmp/test-project/.claude/agents/ + +# 2. Dispatch planner via Task tool +# Ask: "What's the plan status?" +# Expect: Agent reads plans/, reports module statuses + +# 3. Dispatch librarian +# Ask: "Audit the repo for orphaned files" +# Expect: Agent scans plans/, reports findings +``` + +### Codex + +```bash +# 1. Place agent files +cp scaffold/agents/codex/aps-planner.toml /tmp/test-project/.codex/agents/ +cp scaffold/agents/codex/aps-librarian.toml /tmp/test-project/.codex/agents/ +# Merge codex-config-snippet.toml into .codex/config.toml + +# 2. Spawn planner +# /agent spawn aps-planner +# Ask: "What's the plan status?" + +# 3. Spawn librarian +# /agent spawn aps-librarian +# Ask: "Audit the repo" +``` + +### Copilot + +```bash +# 1. Place agent files +cp scaffold/agents/copilot/aps-planner.md /tmp/test-project/.github/agents/ +cp scaffold/agents/copilot/aps-librarian.md /tmp/test-project/.github/agents/ + +# 2. In Copilot Chat, agents should appear as available +# 3. Invoke @aps-planner and @aps-librarian +``` + +### OpenCode + +```bash +# 1. Place agent files +cp scaffold/agents/opencode/aps-planner.md /tmp/test-project/.opencode/agents/ +cp scaffold/agents/opencode/aps-librarian.md /tmp/test-project/.opencode/agents/ + +# 2. Switch to subagent via Tab or @aps-planner +# 3. Ask for plan status +``` + +### Gemini + +```bash +# 1. Place skill files +cp -r scaffold/agents/gemini/aps-planner /tmp/test-project/.gemini/skills/ +cp -r scaffold/agents/gemini/aps-librarian /tmp/test-project/.gemini/skills/ + +# 2. Link skills +# gemini skills link . --scope workspace + +# 3. Activate skill in conversation +``` + +## Issues Found and Fixed + +1. **Stale OpenCode model IDs** — Updated from `claude-opus-4-20250514` / + `claude-sonnet-4-20250514` to `claude-opus-4-6` / `claude-sonnet-4-6` +2. **Missing vendor comment** — Added inline comment to Codex config snippet + clarifying `o4-mini` is an OpenAI model + +## Notes + +- Full end-to-end testing of non-Claude-Code tools requires those tools + installed. The automated validation covers everything that can be checked + without the tools: file format, content correctness, build reproducibility. +- Claude Code agents were validated live (format + content + dispatch readiness). +- The Gemini planner skill intentionally omits wave-based execution detail — + this is appropriate condensation for the skill format. diff --git a/docs/agents.md b/docs/agents.md index 4324b9e..3bf8772 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -64,7 +64,7 @@ with planning or cleanup. ### Claude Code -Copy the agent files to your project: +**Install:** ```bash mkdir -p .claude/agents @@ -75,9 +75,27 @@ cp scaffold/agents/claude-code/aps-librarian.md .claude/agents/ Or if you installed APS via the scaffold scripts, agents are available in `scaffold/agents/claude-code/` within the APS repository. +**Usage:** + +Dispatch via the Agent tool or Task tool within Claude Code: + +``` +# Ask the planner to create a plan +> Use @aps-planner to plan the authentication module + +# Ask the planner for status +> Use @aps-planner to report the current plan status + +# Ask the librarian to audit +> Use @aps-librarian to scan for orphaned files and broken references +``` + +The Planner runs on Opus (deep reasoning). The Librarian runs on Sonnet +(fast, cheaper). Both are configured in the agent frontmatter. + ### Copilot -Copy to `.github/agents/` in your repository: +**Install:** ```bash mkdir -p .github/agents @@ -85,9 +103,21 @@ cp scaffold/agents/copilot/aps-planner.md .github/agents/ cp scaffold/agents/copilot/aps-librarian.md .github/agents/ ``` +**Usage:** + +Invoke in Copilot Chat by mentioning the agent: + +``` +@aps-planner create a plan for the payments module +@aps-librarian check for stale docs in the repo +``` + +Copilot auto-discovers agents in `.github/agents/`. No model selection is +available — Copilot uses its default model. + ### OpenCode -Copy to `.opencode/agents/` in your project: +**Install:** ```bash mkdir -p .opencode/agents @@ -95,12 +125,22 @@ cp scaffold/agents/opencode/aps-planner.md .opencode/agents/ cp scaffold/agents/opencode/aps-librarian.md .opencode/agents/ ``` -Agents are configured as subagents — invoke via `@aps-planner` or -`@aps-librarian`. +**Usage:** + +Agents are configured as subagents (`mode: subagent`). Invoke via `@mention`: + +``` +@aps-planner what's the next ready work item? +@aps-librarian archive completed modules +``` + +Switch to an agent as a primary with Tab, or invoke as subagent with +`@mention`. The Planner uses `anthropic/claude-opus-4-20250514`; edit the +`model` field in the frontmatter to change. ### Codex -Place the TOML configs and merge the config snippet: +**Install:** ```bash mkdir -p .codex/agents @@ -109,11 +149,37 @@ cp scaffold/agents/codex/aps-librarian.toml .codex/agents/ ``` Then merge `scaffold/agents/codex/codex-config-snippet.toml` into your -`.codex/config.toml`. Use `/agent spawn aps-planner` to start. +`.codex/config.toml`: + +```toml +[agents.aps-planner] +model = "o4-mini" +config_file = ".codex/agents/aps-planner.toml" + +[agents.aps-librarian] +model = "o4-mini" +config_file = ".codex/agents/aps-librarian.toml" +``` + +**Usage:** + +Spawn agent threads with the `/agent` command: + +``` +/agent spawn aps-planner +> Plan the user authentication module + +/agent spawn aps-librarian +> Audit the repo for orphaned files +``` + +Agent threads run concurrently and can be managed with `/agent route` and +`/agent close`. Codex uses `o4-mini` by default; change the `model` field in +`.codex/config.toml` if needed. ### Gemini -Copy skills and register them: +**Install:** ```bash mkdir -p .gemini/skills @@ -122,8 +188,22 @@ cp -r scaffold/agents/gemini/aps-librarian .gemini/skills/ gemini skills link . --scope workspace ``` -Gemini skills are not auto-discovered — the `gemini skills link` step is -required. Without it, the copied files won't be available. +**Important:** Gemini skills are not auto-discovered — the `gemini skills link` +step is required. Without it, the copied files won't be available. + +**Usage:** + +Gemini has no agent mechanism — the planner and librarian are skills, not +agents. They activate when you ask about planning or repo hygiene: + +``` +Plan the authentication module using APS +Scan the repo for broken cross-references +``` + +The skill provides guidance but doesn't have the same dispatch model as +agents in other tools. For active orchestration, consider using Claude Code +or Codex. ## Model Cost diff --git a/docs/plans/2026-02-27-onboarding-design.md b/docs/plans/2026-02-27-onboarding-design.md index 19f96d9..3c3656f 100644 --- a/docs/plans/2026-02-27-onboarding-design.md +++ b/docs/plans/2026-02-27-onboarding-design.md @@ -160,38 +160,35 @@ no-dependency alternative. Both paths produce the same end state. ``` aps-cli/ src/ - index.ts Entry point (commander) + main.rs Entry point (clap) commands/ - init.ts Init wizard command - lint.ts Lint (port from bash or shell out) - update.ts Update command + init.rs Init wizard command + lint.rs Lint (port from bash or native) + update.rs Update command tui/ - components/ OpenTUI components (SolidJS) - Select.tsx Single-select prompt - MultiSelect.tsx Checkbox multi-select (custom) - Confirm.tsx Y/N dialog - Spinner.tsx Progress indicator - Header.tsx Branded header - ResultsDashboard.tsx Summary panel - commands/ + widgets/ Ratatui widgets (shared EddaCraft TUI) + select.rs Single-select prompt + multi_select.rs Checkbox multi-select + confirm.rs Y/N dialog + spinner.rs Progress indicator + header.rs Branded header + results_dashboard.rs Summary panel + views/ init/ - InitWizard.tsx Wizard orchestrator - ProfileStep.tsx Step 1: profile selection - ScopeStep.tsx Step 2: scope selection - ToolingStep.tsx Step 3: AI tools multi-select - SummaryStep.tsx Step 5: results dashboard - utils/ - theme.ts EddaCraft shared theme - tty-detection.ts TTY/fallback detection - build.ts Bun compile script (cross-platform) - package.json - tsconfig.json + wizard.rs Wizard orchestrator + profile_step.rs Step 1: profile selection + scope_step.rs Step 2: scope selection + tooling_step.rs Step 3: AI tools multi-select + summary_step.rs Step 5: results dashboard + theme.rs EddaCraft shared theme + tty.rs TTY/fallback detection + Cargo.toml ``` -Built with OpenTUI (Bun/Zig) using the SolidJS reconciler. Components -should match the visual language of Anvil-001 (shared EddaCraft theme, -keyboard conventions). Compiled to a single binary via -`bun build --compile` for each target platform. +Built with Rust using Ratatui for terminal UI. Components should match the +visual language of the Anvil product family (shared EddaCraft theme, +keyboard conventions). Compiled to a single static binary via +`cargo build --release` for each target platform. ## Keyboard Conventions (from Anvil-001) @@ -207,25 +204,19 @@ keyboard conventions). Compiled to a single binary via | Decision | Choice | Notes | |----------|--------|-------| -| TUI framework | **OpenTUI** (Bun/Zig) | SolidJS reconciler, native Zig TUI core, same product family as Anvil. Migrating from Ink. | -| Distribution | **Single binary** via `bun build --compile` | Cross-compile for linux-x64, darwin-arm64, windows-x64. Zero runtime deps for end users. | +| TUI framework | **Ratatui** (Rust) | Shared EddaCraft TUI library, same product family as Anvil. Supersedes OpenTUI (Bun/Zig) decision from 2026-02-27. | +| Distribution | **Single binary** via `cargo build --release` | Cross-compile for linux-x64, linux-arm64, darwin-arm64, darwin-x64, windows-x64. Zero runtime deps for end users. | | Where source lives | TBD | APS is public, Anvil is private. Need to decide whether aps-cli lives in APS repo or elsewhere. | -| Shared TUI components | TBD | Depends on source location. OpenTUI components may be extracted as a shared public package or copied. | +| Shared TUI components | TBD | Depends on source location. Ratatui widgets may be extracted as a shared crate or vendored. | -### Why OpenTUI +### Why Ratatui -- Same product family as Anvil-001 (migrating Anvil from Ink to OpenTUI) -- Bun-compiled single binary — same approach Claude Code uses in production -- SolidJS reconciler for reactive components -- Built-in Select, Input, Textarea, TabSelect, Slider, ScrollBox, Markdown -- Native Zig core delivers sub-ms rendering -- Bun cross-compilation covers all target platforms - -### Risk: Native Zig Addon in Compiled Binary - -OpenTUI's Zig TUI core is a native addon. There is an open Bun issue -about `--compile` not always embedding native addons correctly. A spike -should verify this works before committing to the architecture. +- Same product family as Anvil (shared EddaCraft TUI built on Ratatui) +- Rust compiles to true static binaries — no runtime, no VM, no native addon issues +- Ratatui is the dominant Rust TUI framework with active ecosystem +- Rich widget library (List, Table, Paragraph, Tabs, Gauge, etc.) +- Crossterm backend handles cross-platform terminal compatibility +- `cargo build --release` cross-compilation via `cross` or `cargo-zigbuild` ## Relationship to Existing Install @@ -238,27 +229,20 @@ about what to include. ## Build & Cross-Compilation -The CLI compiles to standalone binaries via `bun build --compile`: - -```typescript -// build.ts -import solidPlugin from "@opentui/solid/bun-plugin" - -const targets = [ - { target: "bun-linux-x64", outfile: "./dist/aps-linux-x64" }, - { target: "bun-linux-arm64", outfile: "./dist/aps-linux-arm64" }, - { target: "bun-darwin-arm64", outfile: "./dist/aps-darwin-arm64" }, - { target: "bun-darwin-x64", outfile: "./dist/aps-darwin-x64" }, - { target: "bun-windows-x64", outfile: "./dist/aps-windows-x64.exe" }, -] - -for (const { target, outfile } of targets) { - await Bun.build({ - entrypoints: ["./src/index.ts"], - plugins: [solidPlugin], - compile: { target, outfile }, - }) -} +The CLI compiles to standalone binaries via `cargo build --release`. +Cross-compilation uses `cross` or `cargo-zigbuild` for multi-platform +targets: + +```bash +# Native build +cargo build --release + +# Cross-compile (using cross) +cross build --release --target x86_64-unknown-linux-gnu +cross build --release --target aarch64-unknown-linux-gnu +cross build --release --target aarch64-apple-darwin +cross build --release --target x86_64-apple-darwin +cross build --release --target x86_64-pc-windows-gnu ``` Binaries are published as GitHub release assets. The `curl | bash` @@ -266,9 +250,7 @@ installer can optionally download the binary instead of the bash CLI. ## Prior Art -- **Anvil-001** (`anvil init`) — 5-step TUI wizard with Ink (migrating to - OpenTUI). Direct inspiration for UX patterns and shared theme. +- **Anvil** (`anvil init`) — TUI wizard built with Rust/Ratatui (shared + EddaCraft TUI). Direct inspiration for UX patterns and shared theme. - **Superpowers** — Per-platform install instructions (Claude Code, Cursor, Codex, OpenCode). Inspiration for the multi-tool selection model. -- **Claude Code** — Ships as a Bun-compiled single binary. Validates the - distribution approach at scale. diff --git a/docs/plans/2026-03-16-aps-migration-design.md b/docs/plans/2026-03-16-aps-migration-design.md new file mode 100644 index 0000000..af947af --- /dev/null +++ b/docs/plans/2026-03-16-aps-migration-design.md @@ -0,0 +1,474 @@ +# APS v2 Migration & Onboarding Overhaul Design + +**Date:** 2026-03-16 +**Status:** Draft + +## Problem + +APS v0.3 shipped most of its planned features (agents, multi-tool support, +interactive init) but diverged from the planned `.aps/` directory consolidation. +The current install produces a scattered layout: + +- `bin/aps` + `lib/` at project root +- `aps-planning/` at project root (skill files + hook scripts) +- `.claude/commands/` (deprecated format, should be skills only) +- No `config.yml` to record install choices +- `designs/` lives at root, separate from `plans/` +- `aps-rules.md` mixes APS format rules with project-specific context + +Additionally, the internal planning repo experiment (aps-closed) didn't work. +Plans are moving back into the main repo and need reconciliation with reality. + +## Goal + +1. Consolidate all APS-owned tooling under `.aps/` as originally designed + (D-011, D-012) +2. Ship a shell-prompt install wizard (profile, scope, AI tools) that produces + the new layout with `config.yml` +3. Provide a migration path for existing v1 installs +4. Clean up the planning content structure (`designs/` and `issues.md` into + `plans/`, split `aps-rules.md`) +5. Move plans back into anvil-plan-spec and reconcile with shipped state + +## Success Criteria + +- [ ] Fresh `aps init` produces `.aps/` layout with config.yml +- [ ] `aps migrate` converts v1 layout to v2 without data loss +- [ ] `aps update` reads config.yml and refreshes without re-prompting +- [ ] No `bin/`, `lib/`, `aps-planning/`, or `.claude/commands/` at project root +- [ ] `aps-rules.md` contains only APS format rules (updatable) +- [ ] `project-context.md` contains project-specific context (user-owned) +- [ ] `plans/designs/` and `plans/issues.md` are part of the scaffold +- [ ] Shell-prompt wizard works in interactive terminals; flags work for CI +- [ ] Agent bootstraps `project-context.md` on first run after install + +## Sequencing: aps-rules.md and designs/ Migration + +The new `aps-rules.md` (which references `plans/designs/` instead of root +`designs/`) ships **only with the v2 layout**. It is never installed into a +v1 project via `aps update`. The sequencing: + +1. `aps update` on v1 projects: continues shipping the current `aps-rules.md` + with `designs/` at root. No change until user runs `aps migrate`. +2. `aps migrate`: moves files to v2 layout, then installs the new + `aps-rules.md` that references `plans/designs/`. +3. `aps init` (fresh install): produces v2 layout with new `aps-rules.md` + from the start. + +This ensures agents never see a `plans/designs/` reference while the files +are still at root `designs/`. + +## Global vs Per-Project Install + +The global install (`aps init --global` or `scaffold/install --global`) +places the CLI at `~/.aps/bin/aps` and adds it to PATH. This is unchanged +by this design — `~/.aps/` is the global tooling root, `.aps/` (in a project) +is the per-project tooling root. They serve different purposes: + +- **`~/.aps/`** (global): CLI only, no config, no project files. Used when + the user wants `aps` available system-wide without per-project install. +- **`.aps/`** (per-project): CLI + config + scripts. Created by `aps init` + or `aps migrate` inside a project directory. + +When both exist, the per-project `.aps/bin/aps` takes precedence (via direnv +`PATH_add .aps/bin` or explicit path). The global install is a convenience +for users who work across many projects. + +## Directory Layout: Before and After + +### Before (v1 — current) + +``` +bin/ + aps + lib/ + output.sh + lint.sh + scaffold.sh + rules/ + +aps-planning/ + SKILL.md + reference.md + examples.md + hooks.md + scripts/ + +plans/ + aps-rules.md # mixed: APS rules + project context + index.aps.md + modules/ + execution/ + decisions/ + +designs/ # separate from plans/ + +.claude/ + commands/ # deprecated + plan.md + plan-status.md + agents/ # if installed +``` + +### After (v2 — `.aps/` layout) + +``` +.aps/ + config.yml # install choices, read by updater + bin/aps # CLI + lib/ # CLI internals + scripts/ # hook scripts + init-session.sh + pre-tool-check.sh + post-tool-nudge.sh + check-complete.sh + enforce-plan-update.sh + +plans/ + aps-rules.md # APS-managed, safe to update + project-context.md # user-owned, never overwritten + index.aps.md + modules/ + execution/ + decisions/ + designs/ # moved in from root + issues.md # planning-adjacent tracker + +.claude/skills/aps-planning/ # Claude Code, Copilot, OpenCode + SKILL.md + reference.md + examples.md + +.claude/agents/ # Claude Code (optional) + aps-planner.md + aps-librarian.md + +# Additional tool-specific dirs per selection: +# .github/agents/ (Copilot) +# .opencode/agents/ (OpenCode) +# .codex/agents/ (Codex) +# .agents/skills/aps-planning (Codex, Gemini) +``` + +## Install Wizard Flow (Shell Prompts) + +Three questions, then scaffold + verify. + +### Step 1: Profile (single-select) + +``` +What are you using APS for? + + 1) Solo dev — personal project + 2) Team adoption — rolling out for a team + 3) AI agent setup — planning layer for AI tools +``` + +Determines template defaults and guidance tone. + +### Step 2: Scope (single-select) + +``` +What's the scope of your first plan? + + 1) Small feature (1-3 work items) -> quickstart template + 2) Module with boundaries -> module template + 3) Multi-module initiative -> index + module templates + 4) Monorepo (multiple packages/apps) -> monorepo index +``` + +Determines which index and module templates get scaffolded. + +### Step 3: AI Tooling (multi-select) + +``` +Which AI tools do you use? (comma-separated, e.g. 1,2,4) + + 1) Claude Code + 2) GitHub Copilot + 3) Codex + 4) OpenCode + 5) Gemini + 6) None / manual only +``` + +Determines which agents, skills, and hooks get installed. + +### Step 4: Scaffold + +Produces `.aps/` layout based on selections. Writes `config.yml`. + +### Step 5: Agent Context Bootstrap + +Post-install message directs user to run their agent to populate +`project-context.md`. For Claude Code: "Run /plan in Claude Code to set up +your project context." For other tools: points to AGENTS.md. + +If no agent is available, `project-context.md` ships as a template with +TODO markers. + +### Step 6: Verify + +`aps lint plans/` confirms scaffold is valid. + +### Non-Interactive Fallback + +When TTY is not available or `--non-interactive` flag is set: + +- Defaults: solo dev, small feature, no AI tools +- Override via flags: `--profile team --scope monorepo --tools claude,copilot` +- Silent operation with exit code + +## config.yml Schema + +```yaml +# .aps/config.yml — written by installer, read by updater +aps: + version: "0.3.0" # APS release version that was installed + config_schema: 1 # config.yml schema version (for future compat) + installed: "2026-03-16" # date of initial install + updated: "2026-03-16" # date of last aps update + +project: + type: simple # simple | monorepo + monorepo_tool: ~ # pnpm | turbo | lerna | nx + planning: internal # internal | external + planning_repo: ~ # path or URL (null if internal) + profile: solo # solo | team | agent + +tools: + - name: claude-code + skill: .claude/skills/aps-planning + hooks: full # full | minimal | none + agents: + - aps-planner + - aps-librarian + - name: codex + skill: .agents/skills/aps-planning + instruction_file: AGENTS.md +``` + +**Version field semantics:** + +- `aps.version`: The APS release version (from the repo's `package.json`) + that was last installed or updated. `aps update` compares this against the + latest release to decide whether files need refreshing. +- `aps.config_schema`: Integer schema version for the config.yml format + itself. Starts at 1. Incremented if the config structure changes in a way + that requires migration logic in the updater. +- `aps.installed`: Date of initial installation. Informational, never changed + after first write. +- `aps.updated`: Timestamp of the last `aps update` run. Informational. + +**Canonical tool identifiers** (used in config.yml, CLI flags, and internally): + +| Display Name | Identifier | +|-------------|------------| +| Claude Code | `claude-code` | +| GitHub Copilot | `copilot` | +| Codex | `codex` | +| OpenCode | `opencode` | +| Gemini | `gemini` | +| None / manual | `generic` | + +CLI flags use these identifiers: `--tools claude-code,copilot` + +## aps-rules.md Split + +### aps-rules.md (APS-managed) + +Contains only APS format rules: hierarchy, naming conventions, status flows, +work item structure, action plan format. Same for every project. Updated by +`aps update`. + +### project-context.md (user-owned) + +Contains project-specific context: what the project is, team, tech stack, +conventions, active decisions. Populated by agent on first run or manually +by user. Never overwritten by `aps update`. + +Template shipped by scaffold: + +```markdown +# Project Context + +## Overview + + + +## Team + + + +## Tech Stack + + + +## Conventions + + + +## Active Decisions + + +``` + +## Migration Path (v1 to v2) + +`aps migrate` detects v1 layout and converts. Supports `--dry-run` to preview +changes without modifying files. + +### Detection + +v1 layout is detected by the presence of any of: `bin/aps` at project root, +`aps-planning/` directory, or `.claude/commands/plan.md`. + +### File Moves + +| v1 Location | v2 Location | Action | +|-------------|-------------|--------| +| `bin/aps` | `.aps/bin/aps` | Move | +| `bin/lib/` or `lib/` | `.aps/lib/` | Move | +| `aps-planning/SKILL.md` | `.claude/skills/aps-planning/SKILL.md` | Move | +| `aps-planning/reference.md` | `.claude/skills/aps-planning/reference.md` | Move | +| `aps-planning/examples.md` | `.claude/skills/aps-planning/examples.md` | Move | +| `aps-planning/hooks.md` | Deleted | Remove (hook scripts are the source of truth; hooks.md was human reference only) | +| `aps-planning/scripts/` | `.aps/scripts/` | Move | +| `.claude/commands/plan.md` | Deleted | Back up to `.aps/backup/commands/` then remove | +| `.claude/commands/plan-status.md` | Deleted | Back up to `.aps/backup/commands/` then remove | +| `designs/` | `plans/designs/` | Move | +| `plans/aps-rules.md` (mixed) | `plans/aps-rules.md` + `plans/project-context.md` | Split (see below) | +| (none) | `.aps/config.yml` | Create (inferred) | +| (none) | `plans/issues.md` | Create from template | + +### aps-rules.md Split Logic + +The current `aps-rules.md` contains these section categories: + +**APS-managed (stays in aps-rules.md):** + +- APS Hierarchy (Index, Module, Work Item, Action Plan) +- Naming conventions (ID format, file naming) +- Status flows (Draft → Ready → In Progress → Complete) +- Work item structure (Intent, Expected Outcome, Validation) +- Action plan format (waves, checkpoints, steps) +- Decision logging format +- Template reference + +**Project-specific (moves to project-context.md):** + +- Session Start/End Ritual content +- Project-specific conventions +- Monorepo-specific configuration +- Any section referencing specific tech stack, team, or project names + +The migration script splits on section headers. Sections that match +APS-managed patterns stay; everything else moves to `project-context.md`. +If the script can't determine the boundary (e.g., user has heavily +customized the file), it preserves the original as +`.aps/backup/aps-rules-original.md` and installs fresh copies of both files. + +### config.yml Inference Logic + +When creating `config.yml` from an existing v1 install, the migration +infers choices by checking for installed files: + +| Check | Inference | +|-------|-----------| +| `plans/modules/` contains `*-monorepo*` or `index-monorepo*` | `project.type: monorepo` | +| `pnpm-workspace.yaml` exists | `project.monorepo_tool: pnpm` | +| `turbo.json` exists | `project.monorepo_tool: turbo` | +| `lerna.json` exists | `project.monorepo_tool: lerna` | +| `nx.json` exists | `project.monorepo_tool: nx` | +| `.claude/agents/aps-planner.md` exists | tool: `claude-code` with agents | +| `.claude/skills/aps-planning/` exists | tool: `claude-code` (or copilot/opencode) | +| `.github/agents/aps-planner.md` exists | tool: `copilot` | +| `.opencode/agents/aps-planner.md` exists | tool: `opencode` | +| `.codex/agents/aps-planner.toml` exists | tool: `codex` | +| `.gemini/skills/aps-planner/` exists | tool: `gemini` | +| `.agents/skills/aps-planning/` exists (no `.codex/` or `.gemini/` to disambiguate) | tool: `codex` (more common v1 install) | +| None of the above tool markers | tool: `generic` | + +For ambiguous cases (e.g., `.claude/skills/` exists but could be any of +three tools), the migration defaults to `claude-code` since that's the +most common v1 install. Profile defaults to `solo` since v1 didn't track +this. + +The generated config includes a comment: `# Inferred by aps migrate — review +and adjust if needed`. + +### Post-Migration + +- Update hook paths in `.claude/settings.local.json` (`.aps/scripts/` paths) +- Remove empty directories (`bin/`, `aps-planning/`, `.claude/commands/`) +- Print summary of what moved and what was backed up +- Run `aps lint plans/` to verify +- If `--dry-run`, print the above as a preview without modifying files + +## AGENTS.md + +The root `AGENTS.md` stays at the project root. It serves as the entry point +for Codex and Copilot (both read `AGENTS.md` as their instruction file). The +v2 layout does not move or replace it. + +When tools are selected during install, APS appends an "APS Planning" section +to `AGENTS.md` (creating it if it doesn't exist) that points agents to +`plans/` and `.aps/`. This is the same behavior described in D-013. + +## Agent Context Bootstrap Contract + +After install, `project-context.md` ships as a template with TODO markers. +The post-install message tells the user how to populate it per their tool: + +- **Claude Code:** "Run /plan in Claude Code to set up your project context" +- **Other tools:** "See AGENTS.md for how to populate plans/project-context.md" + +The **aps-planner agent** (all tool variants) includes this behavior in its +system prompt: + +1. On first invocation, check if `plans/project-context.md` contains TODO + markers or is a template. +2. If so, read the project (package.json, README, AGENTS.md/CLAUDE.md, git + log, directory structure) and populate the file with inferred context. +3. For anything it can't infer (team, conventions), leave a TODO marker and + tell the user what to fill in. +4. If `project-context.md` is already populated, skip this step. + +This behavior is part of the agent prompt, not the CLI. It requires no +changes to the bash scripts — the agent handles it naturally when dispatched. + +## Relationship to TUI + +This design uses shell prompts exclusively. The Anvil project is delivering +an EddaCraft-standard TUI (OpenTUI / Bun / Zig) that APS will adopt when +available. The shell-prompt wizard will be replaced by the TUI wizard; the +non-interactive flag path remains regardless. + +No TUI work is in scope for this design. + +## Relationship to Existing Onboarding Design + +The `2026-02-27-onboarding-design.md` describes the TUI-based wizard flow. +This design implements the same wizard logic (profile, scope, tools) using +shell prompts as an interim step. The TUI design remains the target UX. + +## New Decisions + +| Decision | Choice | Notes | +|----------|--------|-------| +| D-022 | External planning repo reversed | Plans move back to main repo. aps-closed deleted. | +| D-023 | Commands fully dropped | Skills only. No `.claude/commands/` shipped. Supersedes D-015. | +| D-024 | aps-rules.md split | `aps-rules.md` (APS-managed) + `project-context.md` (user-owned). | +| D-025 | designs/ and issues.md into plans/ | Single planning content root. | + +## Risks + +| Risk | Impact | Mitigation | +|------|--------|------------| +| Existing users have customized `aps-rules.md` | Medium | Migration backs up original, splits by section headers, preserves unrecognized content in `project-context.md` | +| Hook path changes break active sessions | Low | Migration updates `settings.local.json` automatically | +| Agent can't infer project context accurately | Low | Template with TODO markers as fallback | +| Users resist `.aps/` hidden directory | Low | Same convention as `.git/`, `.github/`, `.vscode/` | +| Users have customized `.claude/commands/` files | Low | Migration backs up to `.aps/backup/commands/` before deletion | +| New `aps-rules.md` references `plans/designs/` on v1 layout | High | New rules only ship with v2 layout; `aps update` on v1 projects uses the old rules (see Sequencing section) | +| config.yml inference guesses wrong tool | Low | Generated config includes review comment; user can edit | diff --git a/lib/scaffold.sh b/lib/scaffold.sh index 6464fd1..e3fc960 100644 --- a/lib/scaffold.sh +++ b/lib/scaffold.sh @@ -1,12 +1,79 @@ #!/usr/bin/env bash # -# Scaffold logic for `aps init` and `aps update` +# Scaffold logic for `aps init`, `aps update`, and `aps migrate` # APS_VERSION="${APS_VERSION:-main}" APS_BASE_URL="https://raw.githubusercontent.com/EddaCraft/anvil-plan-spec/$APS_VERSION" -# Files to download for plans/ +# --- v2 file lists (.aps/ layout) --- + +# Plan templates and rules for plans/ +V2_PLAN_FILES=( + "scaffold/plans/aps-rules-v2.md" + "scaffold/plans/project-context.md" + "scaffold/plans/issues.md" + "scaffold/plans/modules/.module.template.md" + "scaffold/plans/modules/.simple.template.md" + "scaffold/plans/modules/.index-monorepo.template.md" + "scaffold/plans/execution/.steps.template.md" +) + +# Skill files for .claude/skills/aps-planning/ +V2_SKILL_FILES=( + "scaffold/aps-planning/SKILL.md" + "scaffold/aps-planning/reference.md" + "scaffold/aps-planning/examples.md" +) + +# Hook scripts for .aps/scripts/ +V2_SCRIPT_FILES=( + "aps-planning/scripts/install-hooks.sh" + "aps-planning/scripts/init-session.sh" + "aps-planning/scripts/check-complete.sh" + "aps-planning/scripts/pre-tool-check.sh" + "aps-planning/scripts/post-tool-nudge.sh" + "aps-planning/scripts/enforce-plan-update.sh" + "aps-planning/scripts/install-hooks.ps1" + "aps-planning/scripts/init-session.ps1" + "aps-planning/scripts/check-complete.ps1" + "aps-planning/scripts/pre-tool-check.ps1" + "aps-planning/scripts/post-tool-nudge.ps1" + "aps-planning/scripts/enforce-plan-update.ps1" +) + +# CLI files for .aps/bin/ and .aps/lib/ +V2_CLI_FILES=( + "bin/aps" + "bin/aps.ps1" + "lib/output.sh" + "lib/Output.psm1" + "lib/lint.sh" + "lib/Lint.psm1" + "lib/scaffold.sh" + "lib/Scaffold.psm1" + "lib/rules/common.sh" + "lib/rules/Common.psm1" + "lib/rules/module.sh" + "lib/rules/Module.psm1" + "lib/rules/index.sh" + "lib/rules/Index.psm1" + "lib/rules/workitem.sh" + "lib/rules/WorkItem.psm1" + "lib/rules/issues.sh" + "lib/rules/Issues.psm1" + "lib/rules/design.sh" + "lib/rules/Design.psm1" +) + +# Agent files (Claude Code) +V2_AGENT_FILES=( + "scaffold/agents/claude-code/aps-planner.md" + "scaffold/agents/claude-code/aps-librarian.md" +) + +# --- v1 file lists (backward compat for update) --- + PLAN_FILES=( "scaffold/plans/aps-rules.md" "scaffold/plans/modules/.module.template.md" @@ -15,7 +82,6 @@ PLAN_FILES=( "scaffold/plans/execution/.steps.template.md" ) -# Files to download for the planning skill SKILL_FILES=( "scaffold/aps-planning/SKILL.md" "scaffold/aps-planning/reference.md" @@ -35,13 +101,11 @@ SKILL_FILES=( "scaffold/aps-planning/scripts/enforce-plan-update.ps1" ) -# Files to download for slash commands COMMAND_FILES=( "scaffold/commands/plan.md" "scaffold/commands/plan-status.md" ) -# CLI files (bin/ and lib/) CLI_FILES=( "bin/aps" "bin/aps.ps1" @@ -65,13 +129,32 @@ CLI_FILES=( "lib/rules/Design.psm1" ) -# Download a file from GitHub +# Canonical tool identifiers +TOOL_NAMES=("claude-code" "copilot" "codex" "opencode" "gemini" "generic") +TOOL_LABELS=("Claude Code" "GitHub Copilot" "Codex" "OpenCode" "Gemini" "None / manual only") + +# --- Utility functions --- + +# Download a file from GitHub (or copy locally if APS_LOCAL is set) download() { local src="$1" local dest="$2" - local url="$APS_BASE_URL/$src" mkdir -p "$(dirname "$dest")" + + # Local mode: copy from source repo instead of downloading + if [[ -n "${APS_LOCAL:-}" ]]; then + local local_path="$APS_LOCAL/$src" + if [[ -f "$local_path" ]]; then + cp "$local_path" "$dest" + return 0 + else + error "Local file not found: $local_path" + exit 1 + fi + fi + + local url="$APS_BASE_URL/$src" if ! curl -fsSL "$url" -o "$dest"; then error "Failed to download: $url" echo " Check your network and ensure APS_VERSION='$APS_VERSION' is valid." >&2 @@ -80,7 +163,6 @@ download() { } # Prompt user with a yes/no question. Returns 0 for yes, 1 for no. -# Non-interactive defaults to the provided default. ask_yn() { local prompt="$1" local default="${2:-n}" @@ -97,14 +179,415 @@ ask_yn() { fi } +# Single-select prompt. Returns the 1-based selection number. +prompt_select() { + local prompt="$1" + shift + local options=("$@") + local count=${#options[@]} + + echo "" >&2 + echo "$prompt" >&2 + echo "" >&2 + for i in "${!options[@]}"; do + printf " %d) %s\n" $((i + 1)) "${options[$i]}" >&2 + done + echo "" >&2 + + if [[ -t 0 ]]; then + while true; do + printf "Choice [1-%d]: " "$count" >&2 + read -r choice + if [[ "$choice" =~ ^[0-9]+$ ]] && (( choice >= 1 && choice <= count )); then + echo "$choice" + return + fi + echo " Please enter a number between 1 and $count" >&2 + done + else + echo "1" + fi +} + +# Multi-select prompt. Returns comma-separated 1-based indices. +prompt_multi() { + local prompt="$1" + shift + local options=("$@") + local count=${#options[@]} + + echo "" >&2 + echo "$prompt" >&2 + echo "" >&2 + for i in "${!options[@]}"; do + printf " %d) %s\n" $((i + 1)) "${options[$i]}" >&2 + done + echo "" >&2 + + if [[ -t 0 ]]; then + while true; do + printf "Choice (comma-separated, e.g. 1,2,4): " >&2 + read -r choices + # Validate all choices + local valid=true + IFS=',' read -ra parts <<< "$choices" + for part in "${parts[@]}"; do + part="${part// /}" + if ! [[ "$part" =~ ^[0-9]+$ ]] || (( part < 1 || part > count )); then + valid=false + break + fi + done + if $valid && [[ ${#parts[@]} -gt 0 ]]; then + echo "$choices" + return + fi + echo " Please enter numbers between 1 and $count, separated by commas" >&2 + done + else + echo "1" + fi +} + # Check if APS hooks are already configured has_aps_hooks() { local target="${1:-.}" local settings="$target/.claude/settings.local.json" - [[ -f "$settings" ]] && grep -q 'aps-planning/scripts\|\[APS\]' "$settings" 2>/dev/null + [[ -f "$settings" ]] && grep -q 'aps-planning/scripts\|\.aps/scripts\|\[APS\]' "$settings" 2>/dev/null +} + +# Detect v1 layout — require APS-specific markers to avoid false positives +# on repos that happen to have bin/aps for unrelated purposes. +is_v1_layout() { + local target="${1:-.}" + local markers=0 + + [[ -f "$target/bin/aps" ]] && ((markers++)) + [[ -d "$target/aps-planning" ]] && ((markers++)) + [[ -f "$target/.claude/commands/plan.md" ]] && ((markers++)) + [[ -f "$target/lib/output.sh" ]] && ((markers++)) + [[ -f "$target/plans/aps-rules.md" ]] && ((markers++)) + + # Require at least 2 markers to confidently identify a v1 install + (( markers >= 2 )) +} + +# Detect v2 layout +is_v2_layout() { + local target="${1:-.}" + [[ -f "$target/.aps/config.yml" ]] +} + +# Detect monorepo tool +detect_monorepo_tool() { + local target="${1:-.}" + if [[ -f "$target/pnpm-workspace.yaml" ]]; then echo "pnpm" + elif [[ -f "$target/turbo.json" ]]; then echo "turbo" + elif [[ -f "$target/lerna.json" ]]; then echo "lerna" + elif [[ -f "$target/nx.json" ]]; then echo "nx" + else echo "" + fi +} + +# --- v2 install functions --- + +# Write config.yml +write_config() { + local target="$1" + local profile="$2" + local scope="$3" + shift 3 + local tools=("$@") + + local config_dir="$target/.aps" + mkdir -p "$config_dir" + + local project_type="simple" + local monorepo_tool="~" + if [[ "$scope" == "monorepo" ]]; then + project_type="monorepo" + monorepo_tool="$(detect_monorepo_tool "$target")" + [[ -z "$monorepo_tool" ]] && monorepo_tool="~" + fi + + local today + today="$(date +%Y-%m-%d)" + + { + echo "# .aps/config.yml — written by installer, read by updater" + echo "aps:" + echo " version: \"0.3.0\"" + echo " config_schema: 1" + echo " installed: \"$today\"" + echo " updated: \"$today\"" + echo "" + echo "project:" + echo " type: $project_type" + echo " monorepo_tool: $monorepo_tool" + echo " profile: $profile" + echo "" + echo "tools:" + for tool in "${tools[@]}"; do + echo " - name: $tool" + case "$tool" in + claude-code) + echo " skill: .claude/skills/aps-planning" + echo " hooks: full" + echo " agents:" + echo " - aps-planner" + echo " - aps-librarian" + ;; + copilot) + echo " skill: .claude/skills/aps-planning" + echo " instruction_file: AGENTS.md" + ;; + codex) + echo " skill: .agents/skills/aps-planning" + echo " instruction_file: AGENTS.md" + ;; + opencode) + echo " skill: .claude/skills/aps-planning" + ;; + gemini) + echo " skill: .agents/skills/aps-planning" + echo " instruction_file: GEMINI.md" + ;; + generic) + echo " # No tool integration" + ;; + esac + done + } > "$config_dir/config.yml" +} + +# Install v2 plans +v2_install_plans() { + local target="$1" + local plans_dir="$target/plans" + + mkdir -p "$plans_dir/modules" "$plans_dir/execution" "$plans_dir/decisions" "$plans_dir/designs" + echo "0.2.0" > "$plans_dir/.aps-version" + + for f in "${V2_PLAN_FILES[@]}"; do + local rel="${f#scaffold/plans/}" + local dest="$plans_dir/$rel" + # Rename aps-rules-v2.md to aps-rules.md at destination + if [[ "$rel" == "aps-rules-v2.md" ]]; then + dest="$plans_dir/aps-rules.md" + fi + # Don't overwrite project-context.md or issues.md if they exist + if [[ "$rel" == "project-context.md" || "$rel" == "issues.md" ]] && [[ -f "$dest" ]]; then + continue + fi + download "$f" "$dest" + done +} + +# Install v2 index (init only) +v2_install_index() { + local target="$1" + download "scaffold/plans/index.aps.md" "$target/plans/index.aps.md" + touch "$target/plans/decisions/.gitkeep" + touch "$target/plans/designs/.gitkeep" +} + +# Install v2 CLI to .aps/ +v2_install_cli() { + local target="$1" + local aps_dir="$target/.aps" + + for f in "${V2_CLI_FILES[@]}"; do + download "$f" "$aps_dir/$f" + done + chmod +x "$aps_dir/bin/aps" +} + +# Install v2 skill files to .claude/skills/aps-planning/ +v2_install_skill() { + local target="$1" + local skill_dir="$target/.claude/skills/aps-planning" + + mkdir -p "$skill_dir" + for f in "${V2_SKILL_FILES[@]}"; do + local rel="${f#scaffold/aps-planning/}" + download "$f" "$skill_dir/$rel" + done +} + +# Install v2 hook scripts to .aps/scripts/ +v2_install_scripts() { + local target="$1" + local scripts_dir="$target/.aps/scripts" + + mkdir -p "$scripts_dir" + for f in "${V2_SCRIPT_FILES[@]}"; do + local rel="${f#aps-planning/scripts/}" + download "$f" "$scripts_dir/$rel" + done + chmod +x "$scripts_dir/"*.sh 2>/dev/null || true +} + +# Install Claude Code agents to .claude/agents/ +v2_install_agents() { + local target="$1" + local agents_dir="$target/.claude/agents" + + mkdir -p "$agents_dir" + for f in "${V2_AGENT_FILES[@]}"; do + local rel="${f#scaffold/agents/claude-code/}" + download "$f" "$agents_dir/$rel" + done +} + +# Install Copilot agents to .github/agents/ +v2_install_copilot_agents() { + local target="$1" + local agents_dir="$target/.github/agents" + + mkdir -p "$agents_dir" + download "scaffold/agents/copilot/aps-planner.md" "$agents_dir/aps-planner.md" + download "scaffold/agents/copilot/aps-librarian.md" "$agents_dir/aps-librarian.md" +} + +# Install OpenCode agents to .opencode/agents/ +v2_install_opencode_agents() { + local target="$1" + local agents_dir="$target/.opencode/agents" + + mkdir -p "$agents_dir" + download "scaffold/agents/opencode/aps-planner.md" "$agents_dir/aps-planner.md" + download "scaffold/agents/opencode/aps-librarian.md" "$agents_dir/aps-librarian.md" +} + +# Install Codex agents to .codex/agents/ + skill to .agents/skills/ +v2_install_codex() { + local target="$1" + + # Agents + local agents_dir="$target/.codex/agents" + mkdir -p "$agents_dir" + download "scaffold/agents/codex/aps-planner.toml" "$agents_dir/aps-planner.toml" + download "scaffold/agents/codex/aps-librarian.toml" "$agents_dir/aps-librarian.toml" + download "scaffold/agents/codex/codex-config-snippet.toml" "$agents_dir/codex-config-snippet.toml" + + # Skill at .agents/skills/ (shared with Gemini) + v2_install_agents_skill "$target" +} + +# Install skill to .agents/skills/aps-planning/ (for Codex/Gemini) +v2_install_agents_skill() { + local target="$1" + local skill_dir="$target/.agents/skills/aps-planning" + + mkdir -p "$skill_dir" + for f in "${V2_SKILL_FILES[@]}"; do + local rel="${f#scaffold/aps-planning/}" + download "$f" "$skill_dir/$rel" + done +} + +# Install Gemini skills to .gemini/skills/ +v2_install_gemini() { + local target="$1" + + mkdir -p "$target/.gemini/skills/aps-planner" "$target/.gemini/skills/aps-librarian" + download "scaffold/agents/gemini/aps-planner/SKILL.md" "$target/.gemini/skills/aps-planner/SKILL.md" + download "scaffold/agents/gemini/aps-librarian/SKILL.md" "$target/.gemini/skills/aps-librarian/SKILL.md" + + # Also place skill at .agents/skills/ (shared path) + v2_install_agents_skill "$target" +} + +# Set up PATH for .aps/bin +v2_setup_path() { + local target="$1" + + echo "" + if command -v direnv &>/dev/null; then + local envrc="$target/.envrc" + if [[ -f "$envrc" ]] && grep -q 'PATH_add .aps/bin' "$envrc" 2>/dev/null; then + info "PATH already configured in .envrc" + elif ask_yn "Set up direnv so you can run 'aps' without .aps/bin/ prefix?" "y"; then + # Remove old bin/ PATH if present + if [[ -f "$envrc" ]]; then + sed -i '/^PATH_add bin$/d' "$envrc" + echo 'PATH_add .aps/bin' >> "$envrc" + else + echo 'PATH_add .aps/bin' > "$envrc" + fi + info "Added 'PATH_add .aps/bin' to .envrc" + echo " Run 'direnv allow' to activate" + else + info "To run aps without the path prefix, add to your .envrc:" + echo " PATH_add .aps/bin" + fi + else + info "To run 'aps' without .aps/bin/ prefix, either:" + echo " - Install direnv and add 'PATH_add .aps/bin' to .envrc" + echo " - Or add 'export PATH=\"./.aps/bin:\$PATH\"' to your shell config" + fi +} + +# Install tool-specific files based on selections +v2_install_tools() { + local target="$1" + shift + local tools=("$@") + + local post_install_msgs=() + + for tool in "${tools[@]}"; do + case "$tool" in + claude-code) + v2_install_skill "$target" + v2_install_agents "$target" + info ".claude/skills/aps-planning/ (skill)" + info ".claude/agents/ (planner, librarian)" + ;; + copilot) + # Copilot reads .claude/skills/ too + v2_install_skill "$target" + v2_install_copilot_agents "$target" + info ".claude/skills/aps-planning/ (skill — Copilot auto-discovers)" + info ".github/agents/ (planner, librarian)" + ;; + opencode) + # OpenCode reads .claude/skills/ too + v2_install_skill "$target" + v2_install_opencode_agents "$target" + info ".claude/skills/aps-planning/ (skill — OpenCode auto-discovers)" + info ".opencode/agents/ (planner, librarian)" + ;; + codex) + v2_install_codex "$target" + info ".codex/agents/ (planner, librarian TOML configs)" + info ".agents/skills/aps-planning/ (skill)" + post_install_msgs+=("Codex: merge .codex/agents/codex-config-snippet.toml into .codex/config.toml") + post_install_msgs+=(" then run: codex skills install .agents/skills/aps-planning") + ;; + gemini) + v2_install_gemini "$target" + info ".gemini/skills/ (planner, librarian)" + info ".agents/skills/aps-planning/ (skill)" + post_install_msgs+=("Gemini: run: gemini skills link . --scope workspace") + ;; + generic) + info "No tool integration (plans/ and CLI only)" + ;; + esac + done + + if [[ ${#post_install_msgs[@]} -gt 0 ]]; then + echo "" + warn "Post-install steps required:" + for msg in "${post_install_msgs[@]}"; do + echo " $msg" + done + fi } -# Download plan templates to target +# --- v1 install functions (backward compat) --- + install_plans() { local target="$1" local plans_dir="$target/plans" @@ -112,45 +595,38 @@ install_plans() { mkdir -p "$plans_dir/modules" "$plans_dir/execution" "$plans_dir/decisions" for f in "${PLAN_FILES[@]}"; do - # Strip "scaffold/plans/" prefix → destination under plans/ local rel="${f#scaffold/plans/}" download "$f" "$plans_dir/$rel" done } -# Download the index template (init only, not update) install_index() { local target="$1" download "scaffold/plans/index.aps.md" "$target/plans/index.aps.md" touch "$target/plans/decisions/.gitkeep" } -# Download skill files to target install_skill() { local target="$1" for f in "${SKILL_FILES[@]}"; do - # Strip "scaffold/" prefix → destination under aps-planning/ local rel="${f#scaffold/}" download "$f" "$target/$rel" done chmod +x "$target/aps-planning/scripts/"*.sh } -# Download slash commands to .claude/commands/ install_commands() { local target="$1" local commands_dir="$target/.claude/commands" mkdir -p "$commands_dir" for f in "${COMMAND_FILES[@]}"; do - # Strip "scaffold/commands/" prefix local rel="${f#scaffold/commands/}" download "$f" "$commands_dir/$rel" done } -# Download the CLI (bin/aps + lib/) to target install_cli() { local target="$1" @@ -160,7 +636,6 @@ install_cli() { chmod +x "$target/bin/aps" } -# Set up PATH so `aps` works without ./bin/ prefix setup_path() { local target="$1" @@ -188,7 +663,6 @@ setup_path() { fi } -# Two-step hook prompt prompt_hooks() { local target="$1" @@ -211,10 +685,15 @@ prompt_hooks() { cmd_init() { local target="." + local opt_profile="" opt_scope="" opt_tools="" non_interactive=false while [[ $# -gt 0 ]]; do case $1 in --help|-h) cmd_init_help; exit 0 ;; + --profile) opt_profile="$2"; shift 2 ;; + --scope) opt_scope="$2"; shift 2 ;; + --tools) opt_tools="$2"; shift 2 ;; + --non-interactive) non_interactive=true; shift ;; *) target="$1"; shift ;; esac done @@ -222,98 +701,188 @@ cmd_init() { local plans_dir="$target/plans" if [[ -d "$plans_dir" ]]; then - error "plans/ directory already exists at $target" - echo "" - echo "To update an existing project:" - echo " aps update" - echo "" - echo "To reinstall from scratch:" - echo " rm -rf $plans_dir && aps init" + if is_v1_layout "$target"; then + error "Existing v1 APS installation detected." + echo "" + echo "To migrate to v2 layout:" + echo " aps migrate" + echo "" + echo "To update in-place (v1 layout):" + echo " aps update" + else + error "plans/ directory already exists at $target" + echo "" + echo "To update an existing project:" + echo " aps update" + fi exit 1 fi echo "" - info "Initialising APS in $target" + info "Initialising APS v2 in $target" + + # --- Step 1: Profile --- + local profile + if [[ -n "$opt_profile" ]]; then + profile="$opt_profile" + elif $non_interactive || ! [[ -t 0 ]]; then + profile="solo" + else + local choice + choice=$(prompt_select "What are you using APS for?" \ + "Solo dev — personal project" \ + "Team adoption — rolling out for a team" \ + "AI agent setup — planning layer for AI tools") + case "$choice" in + 1) profile="solo" ;; + 2) profile="team" ;; + 3) profile="agent" ;; + esac + fi + + # --- Step 2: Scope --- + local scope + if [[ -n "$opt_scope" ]]; then + scope="$opt_scope" + elif $non_interactive || ! [[ -t 0 ]]; then + scope="small" + else + local choice + choice=$(prompt_select "What's the scope of your first plan?" \ + "Small feature (1-3 work items)" \ + "Module with boundaries" \ + "Multi-module initiative" \ + "Monorepo (multiple packages/apps)") + case "$choice" in + 1) scope="small" ;; + 2) scope="module" ;; + 3) scope="multi" ;; + 4) scope="monorepo" ;; + esac + fi + + # --- Step 3: AI Tooling --- + local selected_tools=() + if [[ -n "$opt_tools" ]]; then + IFS=',' read -ra selected_tools <<< "$opt_tools" + elif $non_interactive || ! [[ -t 0 ]]; then + selected_tools=("generic") + else + local choices + choices=$(prompt_multi "Which AI tools do you use? (comma-separated, e.g. 1,2,4)" \ + "${TOOL_LABELS[@]}") + IFS=',' read -ra indices <<< "$choices" + for idx in "${indices[@]}"; do + idx="${idx// /}" + selected_tools+=("${TOOL_NAMES[$((idx - 1))]}") + done + fi + echo "" - # CLI (bin/aps + lib/) - install_cli "$target" - info "bin/aps + lib/ (CLI)" + # --- Step 4: Scaffold --- - # Templates and rules - install_plans "$target" - install_index "$target" - info "plans/ (templates, rules, index)" + # CLI + v2_install_cli "$target" + info ".aps/bin/aps + .aps/lib/ (CLI)" - # Skill - install_skill "$target" - info "aps-planning/ (skill, reference, examples, hooks, scripts)" + # Plans + v2_install_plans "$target" + v2_install_index "$target" + info "plans/ (templates, rules, project-context, designs)" - # Commands - install_commands "$target" - info ".claude/commands/ (plan, plan-status)" + # Hook scripts + v2_install_scripts "$target" + info ".aps/scripts/ (hook scripts)" + # Tool-specific files + v2_install_tools "$target" "${selected_tools[@]}" + + # Config + write_config "$target" "$profile" "$scope" "${selected_tools[@]}" + info ".aps/config.yml (install configuration)" + + # Print layout echo "" - echo " bin/" - echo " └── aps <- CLI (lint, init, update)" + echo " .aps/" + echo " ├── config.yml <- Install configuration" + echo " ├── bin/aps <- CLI (lint, init, update, migrate)" + echo " ├── lib/ <- CLI internals" + echo " └── scripts/ <- Hook scripts" echo "" echo " plans/" - echo " ├── aps-rules.md <- Agent guidance (READ THIS)" - echo " ├── index.aps.md <- Your main plan (edit this)" - echo " ├── modules/" - echo " │ ├── .module.template.md <- Template for modules" - echo " │ ├── .simple.template.md <- Template for small features" - echo " │ └── .index-monorepo.template.md <- Index for monorepos" - echo " ├── execution/" - echo " │ └── .steps.template.md <- Template for steps" - echo " └── decisions/" - echo "" - echo " aps-planning/" - echo " ├── SKILL.md <- Planning skill (core rules)" - echo " ├── reference.md <- APS format reference" - echo " ├── examples.md <- Real-world examples" - echo " ├── hooks.md <- Hook configuration guide" - echo " └── scripts/ <- Hook install + session scripts" + echo " ├── aps-rules.md <- Agent guidance (APS-managed)" + echo " ├── project-context.md <- Your project context (edit this)" + echo " ├── index.aps.md <- Your main plan (edit this)" + echo " ├── issues.md <- Issue & question tracker" + echo " ├── modules/ <- Module specs" + echo " ├── execution/ <- Action plans" + echo " ├── decisions/ <- ADRs" + echo " └── designs/ <- Technical designs" + + # --- Step 5: Agent context bootstrap --- echo "" - echo " .claude/commands/" - echo " ├── plan.md <- /plan command" - echo " └── plan-status.md <- /plan-status command" + local has_claude=false + for tool in "${selected_tools[@]}"; do + [[ "$tool" == "claude-code" ]] && has_claude=true + done - # Hooks - prompt_hooks "$target" + if $has_claude; then + info "Next: run /plan in Claude Code to populate project-context.md" + else + info "Next: edit plans/project-context.md with your project details" + fi # PATH setup - setup_path "$target" + v2_setup_path "$target" + # --- Step 6: Verify --- echo "" - info "Next steps:" - echo " 1. Edit plans/index.aps.md to define your plan" - echo " 2. Copy templates to create modules (remove leading dot)" - echo " 3. Use /plan in Claude Code to start planning" + info "Verifying scaffold..." + if command -v aps &>/dev/null || [[ -x "$target/.aps/bin/aps" ]]; then + local aps_cmd + if [[ -x "$target/.aps/bin/aps" ]]; then + aps_cmd="$target/.aps/bin/aps" + else + aps_cmd="aps" + fi + if "$aps_cmd" lint "$target/plans/" 2>/dev/null; then + info "Scaffold validated successfully" + else + warn "Scaffold validation found issues (this is normal for a fresh install)" + fi + else + info "Run 'aps lint plans/' after setting up PATH to validate" + fi + echo "" } cmd_init_help() { cat < v2 in $target" + echo "" + + local moves=() + local creates=() + local removes=() + local backups=() + + # Plan file moves + if [[ -f "$target/bin/aps" ]]; then + moves+=("bin/aps -> .aps/bin/aps") + fi + if [[ -d "$target/lib" ]]; then + moves+=("lib/ -> .aps/lib/") + fi + if [[ -d "$target/aps-planning/scripts" ]]; then + moves+=("aps-planning/scripts/ -> .aps/scripts/") + fi + if [[ -f "$target/aps-planning/SKILL.md" ]]; then + moves+=("aps-planning/SKILL.md -> .claude/skills/aps-planning/SKILL.md") + fi + if [[ -f "$target/aps-planning/reference.md" ]]; then + moves+=("aps-planning/reference.md -> .claude/skills/aps-planning/reference.md") + fi + if [[ -f "$target/aps-planning/examples.md" ]]; then + moves+=("aps-planning/examples.md -> .claude/skills/aps-planning/examples.md") + fi + if [[ -d "$target/designs" ]]; then + moves+=("designs/ -> plans/designs/") + fi + + # Backup and remove deprecated files + if [[ -f "$target/.claude/commands/plan.md" ]]; then + backups+=(".claude/commands/plan.md -> .aps/backup/commands/plan.md") + removes+=(".claude/commands/plan.md") + fi + if [[ -f "$target/.claude/commands/plan-status.md" ]]; then + backups+=(".claude/commands/plan-status.md -> .aps/backup/commands/plan-status.md") + removes+=(".claude/commands/plan-status.md") + fi + if [[ -f "$target/aps-planning/hooks.md" ]]; then + removes+=("aps-planning/hooks.md (hook scripts are the source of truth)") + fi + + # New files + creates+=(".aps/config.yml (inferred from existing install)") + if [[ ! -f "$target/plans/project-context.md" ]]; then + creates+=("plans/project-context.md (template)") + fi + if [[ ! -f "$target/plans/issues.md" ]]; then + creates+=("plans/issues.md (template)") + fi + + # Display plan + if [[ ${#moves[@]} -gt 0 ]]; then + echo " Files to move:" + for m in "${moves[@]}"; do echo " $m"; done + echo "" + fi + if [[ ${#backups[@]} -gt 0 ]]; then + echo " Files to back up:" + for b in "${backups[@]}"; do echo " $b"; done + echo "" + fi + if [[ ${#removes[@]} -gt 0 ]]; then + echo " Files to remove:" + for r in "${removes[@]}"; do echo " $r"; done + echo "" + fi + if [[ ${#creates[@]} -gt 0 ]]; then + echo " Files to create:" + for c in "${creates[@]}"; do echo " $c"; done + echo "" + fi + + if $dry_run; then + info "Dry run complete. No files were modified." + exit 0 + fi + + if ! ask_yn "Proceed with migration?" "y"; then + info "Migration cancelled." + exit 0 + fi + + echo "" + + # Create directories + mkdir -p "$target/.aps/bin" "$target/.aps/lib/rules" "$target/.aps/scripts" \ + "$target/.aps/backup/commands" \ + "$target/.claude/skills/aps-planning" \ + "$target/plans/designs" + + # Install fresh v2 CLI (don't copy stale v1 binaries) + v2_install_cli "$target" + info "Installed v2 CLI to .aps/bin/" + + # Install fresh hook scripts (don't copy old versions) + v2_install_scripts "$target" + info "Installed v2 hook scripts to .aps/scripts/" + + # Move skill files + for f in SKILL.md reference.md examples.md; do + if [[ -f "$target/aps-planning/$f" ]]; then + cp -a "$target/aps-planning/$f" "$target/.claude/skills/aps-planning/$f" + fi + done + info "Moved skill files to .claude/skills/aps-planning/" + + # Move designs (use /. to include dotfiles) + if [[ -d "$target/designs" ]] && [[ "$(ls -A "$target/designs" 2>/dev/null)" ]]; then + cp -a "$target/designs/." "$target/plans/designs/" + info "Moved designs/ to plans/designs/" + fi + + # Back up and remove deprecated commands + for cmd_file in plan.md plan-status.md; do + if [[ -f "$target/.claude/commands/$cmd_file" ]]; then + cp -a "$target/.claude/commands/$cmd_file" "$target/.aps/backup/commands/$cmd_file" + rm "$target/.claude/commands/$cmd_file" + fi + done + rmdir "$target/.claude/commands" 2>/dev/null || true + info "Backed up and removed deprecated commands" + + # Create new files + if [[ ! -f "$target/plans/project-context.md" ]]; then + download "scaffold/plans/project-context.md" "$target/plans/project-context.md" + info "Created plans/project-context.md" + fi + if [[ ! -f "$target/plans/issues.md" ]]; then + download "scaffold/plans/issues.md" "$target/plans/issues.md" + info "Created plans/issues.md" + fi + + # Update aps-rules.md to v2 version (back up existing first) + if [[ -f "$target/plans/aps-rules.md" ]]; then + cp -a "$target/plans/aps-rules.md" "$target/.aps/backup/aps-rules.md" + info "Backed up existing plans/aps-rules.md to .aps/backup/" + fi + download "scaffold/plans/aps-rules-v2.md" "$target/plans/aps-rules.md" + info "Updated plans/aps-rules.md to v2" + echo "0.2.0" > "$target/plans/.aps-version" + info "Updated plans/.aps-version to 0.2.0" + + # Infer config.yml + local inferred_tools=() + if [[ -d "$target/.claude/agents" ]] && [[ -f "$target/.claude/agents/aps-planner.md" ]]; then + inferred_tools+=("claude-code") + elif [[ -d "$target/.claude/skills/aps-planning" ]]; then + inferred_tools+=("claude-code") + fi + if [[ -f "$target/.github/agents/aps-planner.md" ]]; then + inferred_tools+=("copilot") + fi + if [[ -f "$target/.codex/agents/aps-planner.toml" ]]; then + inferred_tools+=("codex") + fi + if [[ -f "$target/.opencode/agents/aps-planner.md" ]]; then + inferred_tools+=("opencode") + fi + if [[ ${#inferred_tools[@]} -eq 0 ]]; then + inferred_tools=("generic") + fi + + local scope="small" + if [[ -f "$target/plans/index.aps.md" ]] && grep -q '^\| \[' "$target/plans/index.aps.md"; then + scope="multi" + fi + + write_config "$target" "solo" "$scope" "${inferred_tools[@]}" + # Add inference comment + sed -i '1s/^/# Inferred by aps migrate — review and adjust if needed\n/' "$target/.aps/config.yml" + info "Created .aps/config.yml (inferred)" + + # Update hook paths in settings.local.json + if [[ -f "$target/.claude/settings.local.json" ]]; then + if grep -q 'aps-planning/scripts' "$target/.claude/settings.local.json"; then + sed -i 's|aps-planning/scripts|.aps/scripts|g' "$target/.claude/settings.local.json" + info "Updated hook paths in .claude/settings.local.json" + fi + fi + + # Clean up old directories + # Back up custom hook scripts before removing aps-planning/ + if [[ -d "$target/aps-planning/scripts" ]]; then + mkdir -p "$target/.aps/backup/scripts" + cp -a "$target/aps-planning/scripts/." "$target/.aps/backup/scripts/" + info "Backed up aps-planning/scripts/ to .aps/backup/scripts/" + fi + # Remove aps-planning/ entirely (skill files moved to .claude/skills/, scripts to .aps/scripts/) + if [[ -d "$target/aps-planning" ]]; then + rm -rf "$target/aps-planning" + info "Removed old aps-planning/" + fi + # Remove only known APS files from bin/, then remove dir if empty + if [[ -f "$target/bin/aps" ]]; then + rm -f "$target/bin/aps" "$target/bin/aps.ps1" + rmdir "$target/bin" 2>/dev/null && info "Removed old bin/" || \ + warn "bin/ contains non-APS files — removed only bin/aps" + fi + # Remove only known APS files from lib/, then remove dir if empty + if [[ -d "$target/lib" ]] && [[ -f "$target/lib/output.sh" ]]; then + local aps_lib_files=(output.sh Output.psm1 lint.sh Lint.psm1 scaffold.sh Scaffold.psm1) + local aps_rule_files=(common.sh Common.psm1 module.sh Module.psm1 index.sh Index.psm1 + workitem.sh WorkItem.psm1 issues.sh Issues.psm1 design.sh Design.psm1) + for f in "${aps_lib_files[@]}"; do rm -f "$target/lib/$f"; done + for f in "${aps_rule_files[@]}"; do rm -f "$target/lib/rules/$f"; done + rmdir "$target/lib/rules" 2>/dev/null + rmdir "$target/lib" 2>/dev/null && info "Removed old lib/" || \ + warn "lib/ contains non-APS files — removed only APS files" + fi + # Remove designs/ at root (contents copied to plans/designs/) + if [[ -d "$target/designs" ]]; then + rm -rf "$target/designs" + info "Removed old designs/ (contents in plans/designs/)" + fi + + # PATH update + v2_setup_path "$target" + + echo "" + info "Migration complete. Your specs in plans/ were NOT modified." + info "Review .aps/config.yml and adjust if needed." + echo "" +} + +cmd_migrate_help() { + cat < "Executing AUTH-002 (platform, anvil-api): Implement token refresh" + +If no Ready work item exists for what you're asked to do: +- Create Draft work item first +- Ask human to mark Ready before proceeding +- OR if trivial fix, note in session end summary +``` + +Key principle: Agents don't freelance. They either execute authorized work or surface that authorization is missing. + +### Session End Ritual + +```markdown +### 1. Update Work Item Status +For each work item touched: +- `In Progress` → if work started but not complete +- `Complete: YYYY-MM-DD` → if checkpoint passes +- `Blocked: [reason]` → if stuck on dependency/question + +### 2. Capture Discovered Work +Any new work uncovered during execution: +- Add as Draft work item to appropriate module +- Tag with affected packages +- Note dependency on current work if relevant + +Example: +### AUTH-003: Handle token refresh edge case (Draft) +| Discovered during | Packages | Status | +|-------------------|----------|--------| +| AUTH-002 | platform | Draft | + +Intent: Handle expired refresh tokens gracefully + +### 3. Update "What's Next" +In `plans/index.aps.md`: +- Remove completed items +- Add any new Ready items +- Re-sequence if priorities shifted + +### 4. Session Summary +Leave a brief note (in commit message or plan file): +> "Session: Completed AUTH-002. Discovered AUTH-003 (draft). +> Next recommended: CLI-001 or review AUTH-003 for Ready status." +``` + +Key principle: The next agent (or human) should be able to pick up exactly where you left off without archaeology. + +--- + +## Spec Placement + +Where this guidance lives in APS: + +| Location | Content | +|----------|---------| +| `docs/monorepo.md` | Dedicated guide (new) | +| `docs/getting-started.md` | Add "Monorepo Setup" section | +| `templates/index-monorepo.template.md` | Index with package views (new) | +| `templates/module.template.md` | Add Packages field | +| `plans/aps-rules.md` | Add session rituals | + +### aps-rules.md additions + +```markdown +## Monorepo Conventions + +### Package Tagging +Every module declares `Packages: pkg1, pkg2` in metadata. +Work items inherit or narrow the package scope. + +### Session Rituals +See Session Start Ritual and Session End Ritual sections. +``` + +--- + +## Summary + +| Component | Purpose | +|-----------|---------| +| Package tags on modules | "Where does this live?" | +| "What's Next" table | "What should I work on?" | +| Package views in index | Navigation by package | +| Session start ritual | Orient before coding | +| Session end ritual | Update state, capture discoveries | + +--- + +## Implementation + +To implement this design: + +1. Create `docs/monorepo.md` with full guidance +2. Create `templates/index-monorepo.template.md` +3. Update `templates/module.template.md` with Packages field +4. Update `plans/aps-rules.md` with session rituals +5. Update `docs/getting-started.md` with monorepo section diff --git a/plans/designs/2026-02-21-agents-design.md b/plans/designs/2026-02-21-agents-design.md new file mode 100644 index 0000000..f3b2b8b --- /dev/null +++ b/plans/designs/2026-02-21-agents-design.md @@ -0,0 +1,61 @@ +# APS Agents Design — Wave 1 + 2 + +**Date:** 2026-02-21 +**Scope:** AGENT-001, AGENT-002, AGENT-005 (partial) +**Branch:** feat/agents + +## Architecture + +Single source + build. Core prompts in `scaffold/agents/core/` as plain +markdown. Tool variants generated by wrapping core in tool-specific frontmatter. + +```text +scaffold/agents/ +├── core/ +│ ├── planner-core.md +│ └── librarian-core.md +├── claude-code/ +│ ├── aps-planner.md +│ └── aps-librarian.md +└── build.sh +``` + +## Planner Agent (AGENT-001) + +Derived from code-env `anvil-plan-spec.md`, adapted for distribution: + +- Strip personal assumptions and code-env paths +- Reference `plans/` (per D-017) +- Model: opus | Tools: Read, Write, Edit, Glob, Grep, Bash, Task +- Covers: install/update, hierarchy, decision tree, templates, status, + wave execution, validation + +## Librarian Agent (AGENT-002) + +Derived from code-env `librarian.md`, adapted for distribution: + +- Same adaptation as planner +- Model: sonnet | Tools: Read, Write, Edit, Glob, Grep, Bash +- Covers: audit, archive, orphan detection, cross-refs, filing + +## Build Script + +`scaffold/agents/build.sh` concatenates frontmatter + core per tool. +Wave 1+2 generates Claude Code only. Other tools added in Waves 3-4. + +## Documentation (AGENT-005 partial) + +`docs/agents.md` — what each agent does, when to use, how to invoke in +Claude Code, model cost implications. + +## Install Integration + +Deferred to INSTALL-003. For now, agent files are manually copied to +`.claude/agents/`. Documented in agents.md. + +## Decisions + +- D-016: Planner = planning + execution + status + waves. + Librarian = archiving + cross-refs + orphans. No overlap. +- D-017: Agents reference `plans/` and `aps-planning/scripts/`. +- D-018: Shared core prompt, tool-specific wrappers. diff --git a/plans/index.aps.md b/plans/index.aps.md new file mode 100644 index 0000000..2655d2e --- /dev/null +++ b/plans/index.aps.md @@ -0,0 +1,109 @@ +# APS Roadmap + +| Field | Value | +|-------|-------| +| Status | Active | +| Owner | @aneki | +| Created | 2025-12-31 | +| Updated | 2026-02-19 | + +## Problem + +APS needs continued development to: + +1. **Lower adoption barriers** — New users should get value in minutes, not hours +2. **Improve tooling** — Validation, search, and integration with existing workflows +3. **Build ecosystem** — Examples, templates, and community contributions + +## Success Criteria + +- [x] New user can try APS in under 5 minutes +- [x] CLI validates APS documents in CI pipelines +- [x] Documentation covers common workflows with examples +- [ ] Knowledge compounds across projects via solution library + +## Constraints + +- No runtime dependencies — APS remains pure markdown +- No vendor lock-in — Specs stay portable across tools +- No breaking changes without migration path + +## Modules + +### Current (v0.2 — Usability) + +| Module | Purpose | Status | +|--------|---------|--------| +| [scaffold](./modules/scaffold.aps.md) | One-command setup for new projects | Complete | +| [templates](./modules/templates.aps.md) | Reduce friction, mark optional fields | Complete | +| [docs](./modules/docs.aps.md) | Workflow guide, improved onboarding | Complete | +| [validation](./modules/validation.aps.md) | CLI tool to validate APS documents | Complete | + +### Current (v0.3 — Distribution) + +| Module | Purpose | Status | +|--------|---------|--------| +| [install](./modules/install.aps.md) | Interactive install, `.aps/` layout, multi-tool | Complete | +| [agents](./modules/agents.aps.md) | APS Planner + Librarian agents, multi-harness | Complete | + +### Near Term + +| Module | Purpose | Status | +|--------|---------|--------| +| [orchestrate](./modules/orchestrate.aps.md) | CLI orchestration, dependency resolution, state machine | Ready | +| [tui](./modules/tui.aps.md) | Ratatui TUI customization wizard for project setup | Ready | +| [tasks](./modules/tasks.aps.md) | Claude Code Tasks integration | Draft | +| [examples](./modules/examples.aps.md) | Additional worked examples | Draft | +| [prompts](./modules/prompts.aps.md) | Tool-specific prompt variants | Draft | +| [compound](./modules/compound.aps.md) | Review/Learn phase tooling | Draft | +| [integrations](./modules/integrations.aps.md) | JSON export, GitHub sync | Draft | + +### Long Term + +| Module | Purpose | Status | +|--------|---------|--------| +| ecosystem | GitHub Action, VS Code extension | Proposed | +| spec | Formal versioning, JSON Schema | Proposed | + +## Non-Goals + +These are explicitly out of scope: + +- **Execution engines** — APS describes intent; it doesn't run code +- **Vendor plugins** — No Jira/Linear/Notion plugins (specs are portable markdown) +- **AI training** — Not a dataset for model fine-tuning +- **Hosted services** — No cloud component; everything runs locally + +## Risks + +| Risk | Impact | Mitigation | +|------|--------|------------| +| Scope creep into PM territory | High | Maintain non-goals, reject out-of-scope requests | +| Template changes break existing specs | Medium | Keep field names stable, add optional markers | +| Tooling complexity undermines simplicity | Medium | CLI stays optional; markdown-first always | + +## Decisions + +- **D-001:** Rename "Leaf" to "Module" — *decided: yes, improves clarity* +- **D-002:** Use `ID` instead of `SCOPE` in templates — *decided: yes, less confusing* +- **D-003:** Add aps-rules.md as portable agent guide — *decided: yes, travels with templates* +- **D-004:** Adopt compound engineering philosophy — *decided: yes, planning lifecycle* +- **D-005:** Quickstart as default entry point — *decided: no, keep template choices* +- **D-006:** Tool-specific prompt variants — *decided: yes, need variants or stubs pointing to generic AGENTS.md* +- **D-007:** Validation approach — *decided: standalone CLI first, then GitHub Action wrapper* +- **D-008:** Solution docs organization — *decided: per-project with monorepo support* +- **D-009:** npm init module — *decided: merged into scaffold module, no separate npm package* +- **D-010:** Claude Code Tasks integration — *decided: yes, APS as planning layer + Tasks as execution layer* +- **D-011:** `.aps/` as tooling root — *decided: yes, CLI + scripts + config + ephemeral under `.aps/`* +- **D-012:** CLI location — *decided: `.aps/bin/aps` with PATH hint (direnv or shell)* +- **D-013:** Skill format per tool — *decided: `.claude/skills/` as cross-tool path (Claude Code + Copilot + OpenCode auto-discover), `.agents/skills/` for Codex + Gemini (both require explicit install/link cmd); instruction files per tool (AGENTS.md, GEMINI.md)* +- **D-014:** Agent model defaults — *decided: Planner on Opus, Librarian on Sonnet* +- **D-015:** Commands deprecated — *decided: yes, fold `/plan` and `/plan-status` into skill* +- **D-016:** Agent scope split — *decided: Planner = planning + execution + status + waves; Librarian = archiving + cross-refs + orphans* +- **D-017:** Agent path references — *decided: agents reference `plans/` and `.aps/scripts/`, not `.aps/config.yml`* +- **D-018:** Shared core vs per-tool rewrite — *decided: shared core prompt, tool-specific frontmatter/packaging* +- **D-019:** Agent format per tool — *decided: 4/5 tools have native agent mechanisms (Claude Code `.claude/agents/`, Copilot `.github/agents/`, OpenCode `.opencode/agents/`, Codex `.codex/config.toml` + TOML overlays); Gemini is skill-only. Port to each tool's native format, not just skills.* +- **D-022:** External planning repo reversed — *decided: plans move back to main repo* +- **D-023:** Commands fully dropped — *decided: skills only, no `.claude/commands/` shipped* +- **D-024:** aps-rules.md split — *decided: `aps-rules.md` (APS-managed) + `project-context.md` (user-owned)* +- **D-025:** designs/ and issues.md into plans/ — *decided: single planning content root* diff --git a/plans/modules/agents.aps.md b/plans/modules/agents.aps.md new file mode 100644 index 0000000..ccb68ed --- /dev/null +++ b/plans/modules/agents.aps.md @@ -0,0 +1,307 @@ +# Agents Module + +| ID | Owner | Priority | Status | +|----|-------|----------|--------| +| AGENT | @aneki | high | Complete | + +## Purpose + +Build distributable APS agents for each AI tool harness. The core agent +logic (planning lifecycle, repo hygiene) is the same across tools — what +changes is the packaging format. Claude Code, Copilot, and OpenCode use agent +markdown files with frontmatter. Codex uses a multi-agent system with TOML +configuration. Gemini is skill-only (no agent mechanism). + +## Background + +APS defines five conceptual roles (AGENTS.md): Planner, Implementer, Executor, +Reviewer, Librarian. Two exist as personal agents in code-env: + +- `anvil-plan-spec.md` — Planner + Executor (planning, status, execution, + wave coordination) +- `librarian.md` — Librarian (archiving, cross-refs, orphan detection) + +These need to be: + +1. Refined for distribution (strip personal assumptions, adapt to `.aps/`) +2. Ported to other tool harnesses (same capability, different packaging) + +### Agent Mechanism Per Tool + +| Tool | Agent Mechanism | Format | +|------|----------------|--------| +| **Claude Code** | `.claude/agents/.md` | Frontmatter (name, description, model, tools) + system prompt | +| **Codex** | Multi-agent TOML + skills | `[agents.]` in `.codex/config.toml` with `config_file` overlay; also `.agents/skills/` for passive guidance | +| **Copilot** | `.github/agents/.md` | Frontmatter (name, description) + system prompt — very similar to Claude Code format | +| **Gemini** | `.gemini/skills//SKILL.md` | SKILL.md activated via `activate_skill` tool | +| **OpenCode** | `.opencode/agents/.md` + skills | Frontmatter (description, mode, model, tools, permission) + system prompt; also skills at `.opencode/skills/` or `.claude/skills/` | + +The agent *content* (system prompt, decision tree, APS knowledge) is largely +shared. What differs is frontmatter, file location, and tool-specific +affordances. + +**Codex Multi-Agent Detail (Researched 2026-02-19)** + +Codex has a richer agent mechanism beyond skills. The multi-agent system uses +TOML configuration in `.codex/config.toml`: + +```toml +[agents.aps-planner] +model = "o4-mini" +config_file = ".codex/agents/aps-planner.toml" + +[agents.aps-librarian] +model = "o4-mini" +config_file = ".codex/agents/aps-librarian.toml" +``` + +Each agent role gets a TOML overlay file with `developer_instructions`, +`sandbox_mode`, and other config. Agent threads run concurrently and are +managed via `/agent spawn`, `/agent route`, `/agent close` commands. Built-in +roles include `default`, `worker`, and `explorer`. + +For APS, the Codex port should produce BOTH: + +1. A skill (`.agents/skills/aps-planning/`) for passive guidance +2. Agent role configs (`.codex/config.toml` entries + `.codex/agents/*.toml`) + for active dispatch + +**Copilot Custom Agent Detail (Researched 2026-02-19)** + +Copilot supports custom agents stored at `.github/agents/.md` (repo +level) or in the `.github-private` repo (org level). Format is YAML +frontmatter (name, description, optional tools list) with a system prompt body +— structurally identical to Claude Code's agent files. This means the Claude +Code agent can be adapted with minimal changes: different file location, +frontmatter adjusted for Copilot's supported fields. + +**OpenCode Agent Detail (Researched 2026-02-19)** + +OpenCode has a rich agent system with two categories: primary agents (switched +via Tab) and subagents (invoked via `@mention` or Task tool). Agent files live +at `.opencode/agents/.md` (project) or `~/.config/opencode/agents/` +(global). Format is markdown with YAML frontmatter: + +```yaml +--- +description: Agent purpose +mode: subagent # primary | subagent | all +model: anthropic/claude-opus-4-20250514 +steps: 50 +tools: + write: true + bash: true +permission: + edit: "ask" # ask | allow | deny +--- +System prompt here. +``` + +Key differences from Claude Code: `mode` field (primary vs subagent), `steps` +limit, granular `tools` and `permission` maps (per-tool allow/ask/deny), and +`model` uses `provider/model-id` format. The APS port should produce subagent +mode agents (users invoke them deliberately, not as the default primary agent). + +## In Scope + +- APS Planner agent for Claude Code (`.claude/agents/` format) +- APS Librarian agent for Claude Code +- Codex agent roles (`.codex/config.toml` + `.codex/agents/*.toml`) +- Copilot custom agents (`.github/agents/` format) +- OpenCode agents (`.opencode/agents/` format) +- Gemini skill equivalents (skills only — no agent mechanism) +- Shared core prompt that all harness variants derive from +- Documentation on when/how to use each agent per tool +- Testing in fresh projects + +## Out of Scope + +- Implementer/Reviewer agents (general-purpose, not APS-specific) +- Agent-to-agent communication protocols +- MCP server integration (separate TASKS module) +- Tool-specific UI integrations beyond skill/agent files + +## Interfaces + +**Depends on:** + +- INSTALL (Ready) — agents are packaged and distributed by the installer + +**Exposes:** + +- `scaffold/agents/claude-code/aps-planner.md` — Claude Code agent +- `scaffold/agents/claude-code/aps-librarian.md` — Claude Code agent +- `scaffold/agents/codex/aps-planner.toml` — Codex agent role config +- `scaffold/agents/codex/aps-librarian.toml` — Codex agent role config +- `scaffold/agents/copilot/aps-planner.md` — Copilot custom agent +- `scaffold/agents/copilot/aps-librarian.md` — Copilot custom agent +- `scaffold/agents/opencode/aps-planner.md` — OpenCode agent +- `scaffold/agents/opencode/aps-librarian.md` — OpenCode agent +- `scaffold/agents/gemini/aps-planner/SKILL.md` — Gemini skill (no agent mechanism) +- `scaffold/agents/gemini/aps-librarian/SKILL.md` — Gemini skill + +## Decisions + +- **D-016:** Agent scope — Planner covers planning + execution + status + + waves. Librarian covers archiving + cross-refs + orphans. No overlap. + *decided: yes* +- **D-017:** Should agents reference `.aps/` paths or `plans/` paths? + *decided: agents reference `plans/` (user content) and `.aps/scripts/` + (tooling). They don't need to know about `.aps/config.yml`.* +- **D-018:** Shared core vs per-tool rewrite — *decided: write a shared core + prompt, then wrap it in tool-specific frontmatter/packaging. Minimises + drift between harness variants.* + +## Ready Checklist + +- [x] Purpose and scope are clear +- [x] Dependencies identified +- [x] Decisions resolved +- [x] Work items defined with validation + +## Work Items + +### AGENT-001: Build APS Planner agent (Claude Code) — Complete 2026-02-21 + +- **Intent:** Create the primary Planner agent for Claude Code +- **Expected Outcome:** `scaffold/agents/claude-code/aps-planner.md` with + frontmatter (name, description, model: opus, tools) and system prompt + covering: project init, index/module/work-item creation, status tracking, + work item execution, wave-based parallel coordination. Derived from + code-env's `anvil-plan-spec.md`, adapted for `.aps/` layout. +- **Validation:** Place agent in test project with `plans/`; dispatch via Task + tool; agent reads plans, reports status, creates a module spec +- **Confidence:** high +- **Files:** scaffold/agents/claude-code/aps-planner.md + +### AGENT-002: Build APS Librarian agent (Claude Code) — Complete 2026-02-21 + +- **Intent:** Create the primary Librarian agent for Claude Code +- **Expected Outcome:** `scaffold/agents/claude-code/aps-librarian.md` with + frontmatter (name, description, model: sonnet, tools) and system prompt + covering: archiving completed modules, orphan detection, cross-reference + maintenance, stale doc flagging. Derived from code-env's `librarian.md`, + adapted for `.aps/` layout. +- **Validation:** Place agent in test project with completed modules; dispatch + via Task tool; agent identifies archivable modules and orphaned files +- **Confidence:** high +- **Files:** scaffold/agents/claude-code/aps-librarian.md + +### AGENT-003: Port agents to Codex format — Complete 2026-02-21 + +- **Intent:** Make APS agents available to Codex users via multi-agent roles +- **Expected Outcome:** Two deliverables per agent: + 1. Agent role TOML configs — `scaffold/agents/codex/aps-planner.toml` and + `scaffold/agents/codex/aps-librarian.toml` containing + `developer_instructions` (derived from shared core prompt), + `sandbox_mode`, and model config. Installer merges `[agents.aps-planner]` + and `[agents.aps-librarian]` entries into user's `.codex/config.toml` + with `config_file` pointing to the TOML overlays. + 2. Codex config snippet — example `[agents.*]` blocks for documentation and + installer to use when writing `.codex/config.toml`. + Core planning/librarian logic identical to Claude versions, adapted for + Codex's `developer_instructions` field and TOML format. +- **Validation:** Agent role appears in Codex; `/agent spawn aps-planner` + starts agent thread; agent reads plans and reports status. Fallback: skill + at `.agents/skills/aps-planning/` still works as passive guidance. +- **Confidence:** medium +- **Dependencies:** AGENT-001, AGENT-002 + +### AGENT-004: Port agents to Copilot, OpenCode, and Gemini formats — Complete 2026-02-21 + +- **Intent:** Make APS agents available to Copilot, OpenCode, and Gemini users + using each tool's native agent or skill format +- **Expected Outcome:** Three format variants: + 1. **Copilot** — `scaffold/agents/copilot/aps-planner.md` and + `scaffold/agents/copilot/aps-librarian.md` with YAML frontmatter (name, + description). Nearly identical to Claude Code format; installs to + `.github/agents/`. Minimal adaptation needed. + 2. **OpenCode** — `scaffold/agents/opencode/aps-planner.md` and + `scaffold/agents/opencode/aps-librarian.md` with frontmatter (description, + mode: subagent, model, tools, permission). Installs to + `.opencode/agents/`. Planner gets `mode: subagent` so users invoke it + deliberately via `@aps-planner`. + 3. **Gemini** — `scaffold/agents/gemini/aps-planner/SKILL.md` and + `scaffold/agents/gemini/aps-librarian/SKILL.md`. Skill format only + (Gemini has no agent mechanism). Installs to `.gemini/skills/` or + `.agents/skills/` with post-install `gemini skills link` instruction. + Core logic identical to Claude versions across all three. +- **Validation:** Copilot agent discoverable at `.github/agents/`; OpenCode + agent appears as subagent; Gemini skill links correctly +- **Confidence:** high +- **Dependencies:** AGENT-001, AGENT-002 + +### AGENT-005: Create agent documentation — Complete 2026-03-24 + +- **Intent:** Help users understand what each agent does and how to use it in + their tool of choice +- **Expected Outcome:** Documentation covering: what each agent does, per-tool + usage (dispatch command for Claude Code, skill invocation for Codex, + activation for Gemini), when to use agent vs. passive skill, model cost + implications +- **Validation:** Documentation exists with per-tool examples +- **Confidence:** high +- **Dependencies:** AGENT-001, AGENT-002, AGENT-003, AGENT-004 + +### AGENT-006: Test agents across harnesses — Complete 2026-03-28 + +- **Intent:** Verify agents work correctly in each tool's environment +- **Expected Outcome:** Test plan covering: Claude Code Task dispatch, Codex + `/agent spawn`, Copilot agent discovery, OpenCode `@mention` invocation, + Gemini skill link. Each agent performs its core function (planner creates + plan, librarian audits repo) without errors in the tool's native format. +- **Validation:** Tests pass on clean projects per tool +- **Confidence:** medium +- **Dependencies:** AGENT-001, AGENT-002, AGENT-003, AGENT-004, INSTALL-003 +- **Results:** Automated format/content validation complete for all 5 harnesses. + build.sh idempotent, all 14 files correct. Fixed stale OpenCode model IDs + (→ claude-opus-4-6 / claude-sonnet-4-6) and added Codex vendor comments. + Manual end-to-end tests documented in docs/agent-testing.md — require + respective tool installs. Claude Code agents validated live. + +## Execution Strategy + +### Wave 1: Claude Code agents (parallel, no dependencies) + +- AGENT-001: APS Planner (Claude Code) +- AGENT-002: APS Librarian (Claude Code) + +### Wave 2: Documentation (depends on Wave 1) + +- AGENT-005: Agent documentation (partial — Claude Code section) + +### Wave 3: Port to other harnesses (depends on Wave 1) + +- AGENT-003: Codex multi-agent port (TOML config) +- AGENT-004: Copilot + OpenCode agents, Gemini skill + +### Wave 4: Final docs + testing (depends on Wave 3) + +- AGENT-005: Agent documentation (complete — all tools) +- AGENT-006: Cross-harness testing + +## Notes + +- The key architectural decision is **shared core, tool-specific wrapper**. + The APS knowledge (hierarchy, templates, workflow, decision tree) lives + in a shared core. Each harness variant wraps it in appropriate frontmatter + and adjusts for tool-specific features. +- **Four tools now have real agent mechanisms** (Claude Code, Codex, Copilot, + OpenCode). Only Gemini is skill-only. This is a significant finding — the + original assumption was that only Claude Code had agents. +- **Adaptation effort varies by tool:** + - Copilot: minimal — nearly identical to Claude Code (`.md` + frontmatter) + - OpenCode: moderate — same `.md` format but richer frontmatter (mode, + tools map, permission map, model as `provider/id`) + - Codex: significant — entirely different format (TOML config, agent roles, + `developer_instructions` field, concurrent thread model) + - Gemini: minimal — skill only, no agent adaptation needed +- The Planner is the heavier agent (Opus for Claude Code, model varies per + tool). The Librarian is lighter (Sonnet). Tools with model selection: + Claude Code (model field), OpenCode (model field), Codex (model in TOML). + Copilot and Gemini don't expose model choice in agent/skill config. +- Agents should NOT duplicate the SKILL.md content. The passive skill handles + behavioral guidance (plan-before-code, update specs). The agents handle + active dispatch (create a plan for me, audit the repo). +- OpenCode agents should use `mode: subagent` so they're invoked deliberately + (via `@aps-planner`) rather than being the default primary agent. diff --git a/plans/modules/install.aps.md b/plans/modules/install.aps.md new file mode 100644 index 0000000..16cbb92 --- /dev/null +++ b/plans/modules/install.aps.md @@ -0,0 +1,445 @@ +# Install v2 Module + +| ID | Owner | Priority | Status | +|----|-------|----------|--------| +| INSTALL | @aneki | high | Complete | + +## Purpose + +Overhaul how APS gets distributed to user projects. Replace the current +scattered install footprint (`aps-planning/`, `bin/`, `lib/`, +`.claude/commands/`) with a clean `.aps/` tooling root, an interactive +installer that adapts to project type and AI tooling, and optional agent +packages. + +## Background + +The current install (v1) was built for Claude Code-only, single-project use. +Since then: + +- Claude Code commands are being deprecated in favour of skills +- Users work across multiple AI tools (Claude Code, Codex, Copilot) +- APS has agents (Planner, Librarian) that live in personal configs but + aren't distributable +- The `aps-planning/` directory clutters project roots with non-obvious naming +- `bin/` + `lib/` scatter 18+ files across two top-level directories +- No project type detection (monorepo vs simple gets identical install) + +## In Scope + +- `.aps/` directory as single tooling root +- `config.yml` to record install choices (profile, scope, tools, options) +- Shell-prompt install wizard (profile, scope, AI tools) with non-interactive + fallback +- Skill file generation replacing deprecated commands +- Optional agent packaging (APS Planner, Librarian) +- Multi-tool support: Claude Code, Codex, Copilot, Gemini, OpenCode, generic +- Migration path from v1 layout to v2 +- Update script respecting `config.yml` +- `aps-rules.md` split: APS-managed rules + user-owned `project-context.md` +- `plans/designs/` and `plans/issues.md` as scaffold artifacts +- Agent context bootstrap for `project-context.md` + +## Out of Scope + +- Changing APS spec format or templates +- MCP server (separate TASKS module concern) +- Tool-specific plugin/extension development +- TUI wizard (future replacement for shell-prompt wizard) + +## Interfaces + +**Depends on:** + +- SCAFFOLD (Complete) — evolves the existing scaffold +- VAL (Complete) — CLI moves into `.aps/` but linting logic unchanged + +**Exposes:** + +- `scaffold/install` — new interactive installer (replaces current) +- `scaffold/update` — migration-aware updater +- `.aps/config.yml` — project configuration schema +- `.claude/skills/aps-planning/` — skill files (cross-tool compatible) +- `.agents/skills/aps-planning/` — Codex/Gemini-compatible copy (optional) +- `.claude/agents/aps-planner.md` — optional agent (Claude Code) +- `.claude/agents/aps-librarian.md` — optional agent (Claude Code) + +## Decisions + +- **D-011:** `.aps/` as tooling root — *decided: yes, consolidate all + APS-owned files (CLI, scripts, config, ephemeral) under `.aps/`* +- **D-012:** CLI location — *decided: `.aps/bin/aps` with PATH hint* +- **D-013:** Skill/instruction format per tool — *decided, see below* +- **D-014:** Agent model defaults — *decided: Planner on Opus, Librarian on + Sonnet* +- **D-022:** External planning repo reversed — *decided: plans move back to + main repo* +- **D-023:** Commands fully dropped — *decided: skills only, no + `.claude/commands/` shipped* +- **D-024:** aps-rules.md split — *decided: `aps-rules.md` (APS-managed) + + `project-context.md` (user-owned)* +- **D-025:** designs/ and issues.md into plans/ — *decided: single planning + content root* + +**D-013 Detail: Multi-Tool Skill Compatibility (Researched 2026-02-19)** + +Five target tools support a `/SKILL.md` skill format with identical +frontmatter (name + description). The differences are discovery paths and +whether skills require explicit installation. + +| Tool | Skill Paths (project) | Auto-discover? | Install Cmd? | +|------|-----------------------|----------------|--------------| +| **Claude Code** | `.claude/skills/` | Yes | No | +| **Codex** | `.agents/skills/` | No | `codex skills install ` | +| **Copilot** | `.github/skills/`, `.claude/skills/` | Yes | No | +| **OpenCode** | `.opencode/skills/`, `.claude/skills/`, `.agents/skills/` | Yes | No | +| **Gemini** | `.gemini/skills/`, `.agents/skills/` | No | `gemini skills install ` or `link` | + +**Convergence points:** + +- `.claude/skills/` — auto-discovered by Claude Code, Copilot, OpenCode (3/5) +- `.agents/skills/` — used by Codex, Gemini, OpenCode (3/5) but Codex and + Gemini require explicit install/link + +**Install-required tools (Codex, Gemini):** Just dropping files into +`.agents/skills/` is NOT enough. Users must run an install or link command. +The APS installer should: + +1. Place skill files at `.agents/skills/aps-planning/` (shared location) +2. Print post-install instructions for tools that need them: + - Codex: `codex skills install .agents/skills/aps-planning` + - Gemini: `gemini skills link . --scope workspace` (links project skills) +3. Or attempt to run the install command automatically if the tool CLI is + detected on PATH + +Instruction files (project-level guidance, not skills): + +| Tool | Instruction File | +|------|-----------------| +| **Claude Code** | `CLAUDE.md` | +| **Codex** | `AGENTS.md` (hierarchical, concatenated root→cwd) | +| **Copilot** | `AGENTS.md`, `.github/copilot-instructions.md` | +| **Gemini** | `GEMINI.md` | +| **OpenCode** | N/A (uses skills) | + +**Strategy:** Primary skill install to `.claude/skills/aps-planning/` +(auto-discovered by 3 tools). Copy to `.agents/skills/aps-planning/` for +Codex/Gemini users (with post-install instructions for their CLIs). For +instruction files, append an APS section to `AGENTS.md` (shared by Codex + +Copilot) and/or `GEMINI.md`. Agents are Claude Code-specific +(`.claude/agents/`). + +## Ready Checklist + +- [x] Purpose and scope are clear +- [x] Dependencies identified +- [x] D-011 confirmed (.aps/ as tooling root) +- [x] D-012 confirmed (.aps/bin/aps with PATH hint) +- [x] D-013 resolved (multi-tool research complete) +- [x] D-014 confirmed (Planner=Opus, Librarian=Sonnet) +- [x] Work items defined with validation + +## Work Items + +### INSTALL-001: Define `.aps/` directory structure + +- **Intent:** Establish the canonical layout for all APS-owned tooling files +- **Expected Outcome:** Documented directory structure showing where CLI, + scripts, config, and ephemeral files live under `.aps/`. Skills install to + `.claude/skills/aps-planning/` (cross-tool compatible) with optional copy + to `.agents/skills/aps-planning/` for Codex. Agents install to + `.claude/agents/`. Hook scripts live under `.aps/scripts/`. +- **Validation:** Structure documented in this spec; team agrees on layout +- **Confidence:** high +- **Non-scope:** `plans/` directory (unchanged) +- **Status:** Complete: 2026-02-19 — canonical layout documented in Notes + section of this spec with full project layout diagram + +### INSTALL-002: Create `config.yml` schema + +- **Intent:** Record install-time choices so update script can refresh without + re-asking questions +- **Expected Outcome:** YAML schema covering: APS version, project type + (simple/monorepo), selected AI tools (multi-value), skill install flag, + hooks preference (full/minimal/none), optional agents list +- **Validation:** Example config.yml in this spec; schema covers all install + choices +- **Confidence:** high +- **Status:** Complete: 2026-02-19 — schema documented below + +#### config.yml Schema + +```yaml +# .aps/config.yml — written by installer, read by updater +aps: + version: "0.3.0" # APS release version installed + config_schema: 1 # config.yml schema version + installed: "2026-02-19" # date of initial install + updated: "2026-02-19" # date of last aps update + +project: + type: simple # simple | monorepo + monorepo_tool: ~ # pnpm | turbo | lerna | nx (null if simple) + profile: solo # solo | team | agent + +tools: # Multi-select — one or more entries + - name: claude-code + skill: .claude/skills/aps-planning + hooks: full # full | minimal | none + agents: # Optional list + - aps-planner + - aps-librarian + - name: codex + skill: .agents/skills/aps-planning + instruction_file: AGENTS.md + - name: gemini + skill: .agents/skills/aps-planning + instruction_file: GEMINI.md + - name: copilot + skill: .claude/skills/aps-planning + instruction_file: AGENTS.md + - name: opencode + skill: .claude/skills/aps-planning + - name: generic # No tool integration +``` + +Notes on schema: + +- `tools` is a list — multi-select produces multiple entries +- Each tool entry records where its files were placed +- `hooks` and `agents` only apply to claude-code +- `instruction_file` records which file got an APS section appended +- Updater reads this to know what to refresh without re-asking +- `profile` determines template defaults and guidance tone +- Canonical tool identifiers: `claude-code`, `copilot`, `codex`, `opencode`, + `gemini`, `generic` + +### INSTALL-003: Build shell-prompt install wizard — Complete 2026-03-28 + +- **Intent:** Replace the current non-interactive install with a guided + shell-prompt wizard that adapts to the project +- **Expected Outcome:** Install script with three prompts: + 1. **Profile** (single-select): solo dev / team adoption / AI agent setup + 2. **Scope** (single-select): small feature / module / multi-module / monorepo + 3. **AI Tooling** (multi-select): Claude Code / Copilot / Codex / OpenCode / + Gemini / None + Followed by scaffold, agent context bootstrap message, and `aps lint` + verification. Non-interactive fallback via flags: + `--profile solo --scope small --tools claude-code,copilot`. Writes choices + to `.aps/config.yml`. +- **Validation:** Run install in test dir; script asks questions, creates + `.aps/config.yml` with answers, installs correct files per selection; + non-interactive mode works with flags +- **Confidence:** medium +- **Dependencies:** INSTALL-001, INSTALL-002 +- **Results:** Implemented in `lib/scaffold.sh` cmd_init with prompt_select, + prompt_multi, and full non-interactive flag support. Tested with single-tool + and multi-tool selections. APS_LOCAL env var for local development. + +### INSTALL-004: Convert commands to skill — Complete 2026-03-28 + +- **Intent:** Replace deprecated `.claude/commands/` with skill format +- **Expected Outcome:** `/plan` and `/plan-status` behaviours merged into the + SKILL.md at `.claude/skills/aps-planning/SKILL.md`. Supporting files + (reference.md, examples.md) go alongside it. `hooks.md` moves to docs + (human reference, not agent content). No `.claude/commands/` created. +- **Validation:** Skill triggers on "plan this project" and "what's the plan + status" intent; no `.claude/commands/` directory created +- **Confidence:** high +- **Non-scope:** Skill content rewrite (just repackaging) +- **Results:** v2 init installs skill to `.claude/skills/aps-planning/`. + No `.claude/commands/` created. Migration backs up old commands to + `.aps/backup/commands/`. + +### INSTALL-005: Package APS Planner agent — Complete 2026-03-28 + +- **Intent:** Ship a dispatchable APS planning agent that users can opt into +- **Expected Outcome:** `.claude/agents/aps-planner.md` derived from the + existing `anvil-plan-spec.md` agent in code-env, adapted for + distribution. Install places it when user selects the option. +- **Validation:** Agent file installs to `.claude/agents/` when selected; + agent can be dispatched via Task tool +- **Confidence:** high +- **Dependencies:** INSTALL-003 (needs interactive install to offer it) +- **Results:** Agent installed automatically when claude-code tool selected. + Agent files from scaffold/agents/claude-code/. + +### INSTALL-006: Package Librarian agent — Complete 2026-03-28 + +- **Intent:** Ship an optional repo hygiene agent alongside the planner +- **Expected Outcome:** `.claude/agents/aps-librarian.md` derived from the + existing `librarian.md` agent in code-env, scoped to APS-relevant + concerns (archiving, cross-refs, orphan detection) +- **Validation:** Agent file installs to `.claude/agents/` when selected; + agent scans plans/ and reports findings +- **Confidence:** high +- **Dependencies:** INSTALL-003 +- **Results:** Installed alongside planner when claude-code tool selected. + +### INSTALL-007: Add multi-tool instruction generation — Complete 2026-03-28 + +- **Intent:** Support all major AI coding tools with appropriate skill and + instruction files +- **Expected Outcome:** Install generates tool-appropriate files per selection: + - **Claude Code:** skill at `.claude/skills/aps-planning/`, agents at + `.claude/agents/`, hooks in `settings.local.json` + - **Codex:** skill at `.agents/skills/aps-planning/`, agents at + `.codex/agents/*.toml` + config entries in `.codex/config.toml`, + APS section appended to `AGENTS.md`. Post-install: print + `codex skills install` command + - **Copilot:** skill at `.claude/skills/aps-planning/`, agents at + `.github/agents/`, APS section appended to `AGENTS.md` + - **Gemini:** skill at `.agents/skills/aps-planning/`, APS section appended + to `GEMINI.md`. Post-install: print `gemini skills link` command + - **OpenCode:** skill at `.claude/skills/aps-planning/`, agents at + `.opencode/agents/` + - **Generic:** just `plans/` + CLI, no tool integration + Multi-select means a single install can target multiple tools (e.g. Claude + Code + Codex installs to both `.claude/skills/` and `.agents/skills/`). +- **Validation:** Install with each tool selection produces the expected files + in the expected locations; install-required tools get printed instructions +- **Confidence:** medium +- **Dependencies:** INSTALL-003 +- **Results:** All 6 tool targets implemented with correct file placement. + Multi-select tested with claude-code,codex,copilot combo. Post-install + instructions printed for Codex and Gemini. v2_install_tools dispatches + per tool. + +### INSTALL-008: Build migration from v1 to v2 — Complete 2026-03-28 + +- **Intent:** Existing APS users can update without manual restructuring +- **Expected Outcome:** `aps migrate` detects v1 layout (presence of + `aps-planning/`, `bin/aps`, `.claude/commands/plan.md`), moves files to + `.aps/`, updates hook paths in `settings.local.json`, removes old dirs, + creates `config.yml` (inferring choices from what was installed), splits + `aps-rules.md` into APS-managed + `project-context.md`, moves `designs/` + to `plans/designs/`, backs up removed files to `.aps/backup/`. Supports + `--dry-run` to preview without modifying. +- **Validation:** Run migrate in a v1 project; old directories removed, `.aps/` + created, hooks still work, plans/ untouched, backup exists, dry-run mode + previews without changes +- **Confidence:** medium +- **Dependencies:** INSTALL-001, INSTALL-002, INSTALL-003, INSTALL-009 +- **Risks:** Edge cases in hook path rewriting; users with custom + modifications to scaffolded files; aps-rules.md split heuristic +- **Results:** cmd_migrate implemented with dry-run, confirmation prompt, + file moves, backup, cleanup, hook path rewriting, and config inference. + Tested end-to-end on simulated v1 layout. + +### INSTALL-009: Split aps-rules.md and add project-context.md — Complete 2026-03-28 + +- **Intent:** Separate APS-managed format rules from user-owned project context +- **Expected Outcome:** New `aps-rules.md` template containing only APS format + rules (hierarchy, naming, status flows, work item structure, action plan + format). New `project-context.md` template with sections for overview, team, + tech stack, conventions, and active decisions. Agent bootstrap contract: + planner agent populates `project-context.md` on first run if it contains + TODO markers. +- **Validation:** Fresh install produces both files; `aps-rules.md` contains no + project-specific content; `project-context.md` has TODO markers; planner + agent can detect and populate it +- **Confidence:** high +- **Dependencies:** INSTALL-001 +- **Results:** `aps-rules-v2.md` template created with v2 file locations + (plans/designs/, project-context.md). `project-context.md` template with + HTML comment TODO markers. Both installed by v2 init and migrate. + +## Execution Strategy + +### Wave 1: Foundations (no dependencies) + +- INSTALL-001: Directory structure (Complete) +- INSTALL-002: Config schema (Complete) +- INSTALL-009: aps-rules.md split + project-context.md + +### Wave 2: Core installer (depends on Wave 1) + +- INSTALL-003: Shell-prompt install wizard +- INSTALL-004: Commands → skills + +### Wave 3: Optional packages (depends on Wave 2) + +- INSTALL-005: APS Planner agent +- INSTALL-006: Librarian agent + +### Wave 4: Stretch (depends on Wave 2) + +- INSTALL-007: Multi-tool support +- INSTALL-008: v1 → v2 migration + +## Notes + +- The current `aps-planning/` contains: SKILL.md, reference.md, examples.md, + hooks.md, and scripts/. Under the new layout: + - SKILL.md + reference.md + examples.md → `.claude/skills/aps-planning/` + - scripts/ → `.aps/scripts/` + - hooks.md → repo docs (human reference, not installed to projects) +- Skills go to `.claude/skills/` (not `.aps/`) because that's the cross-tool + compatible path (Claude Code, Copilot, OpenCode all check it). Codex users + get an additional copy at `.agents/skills/`. +- Agents install to `.claude/agents/` (Claude Code convention). No equivalent + exists for Codex/Copilot — their "agents" are skills with more capability. +- The Planner agent defaults to Opus (deep reasoning for planning); the + Librarian defaults to Sonnet (fast, cheaper for repo scanning). +- `config.yml` enables the update script to be non-interactive — it reads + existing choices and refreshes the appropriate files. +- The multi-select includes: Claude Code, Codex, Copilot, Gemini, OpenCode, + Other/Generic. OpenCode and Copilot are "free" if Claude Code is selected + (they read `.claude/skills/`). Codex and Gemini share `.agents/skills/` but + both require explicit install commands after file placement. + +### Resulting Project Layout (full install, all options) + +``` +.aps/ +├── config.yml # Install choices +├── bin/aps # CLI linter +├── lib/ # CLI internals +├── scripts/ # Hook scripts +│ ├── init-session.sh +│ ├── check-complete.sh +│ ├── pre-tool-check.sh +│ ├── post-tool-nudge.sh +│ └── enforce-plan-update.sh +└── .session-baseline # Ephemeral (gitignored) + +.claude/ +├── skills/ +│ └── aps-planning/ # Skill (Claude Code, Copilot, OpenCode) +│ ├── SKILL.md +│ ├── reference.md +│ └── examples.md +└── agents/ # Optional (Claude Code) + ├── aps-planner.md + └── aps-librarian.md + +.github/ +└── agents/ # Optional (Copilot) + ├── aps-planner.md + └── aps-librarian.md + +.opencode/ +└── agents/ # Optional (OpenCode) + ├── aps-planner.md + └── aps-librarian.md + +.codex/ +├── config.toml # Agent entries merged (Codex) +└── agents/ + ├── aps-planner.toml + └── aps-librarian.toml + +.agents/ +└── skills/ + └── aps-planning/ # Codex + Gemini (requires install/link) + ├── SKILL.md + ├── reference.md + └── examples.md + +plans/ # User content (unchanged) +├── aps-rules.md +├── index.aps.md +├── modules/ +├── execution/ +└── decisions/ +``` diff --git a/plans/modules/orchestrate.aps.md b/plans/modules/orchestrate.aps.md new file mode 100644 index 0000000..b3403af --- /dev/null +++ b/plans/modules/orchestrate.aps.md @@ -0,0 +1,333 @@ +# Orchestrate Module + +| ID | Owner | Status | +|----|-------|--------| +| ORCH | @aneki | Ready | + +> **Note:** This is an exploratory "or" spec — an alternative to the TASKS +> module for providing programmatic plan navigation. TASKS focuses on Claude +> Code Tasks integration specifically. ORCH provides tool-agnostic CLI + +> optional MCP orchestration on top of existing APS markdown. The two could +> coexist (TASKS as one integration, ORCH as the general layer) or one may +> absorb the other. Decision deferred until both are better understood. + +## Purpose + +Provide programmatic orchestration on top of APS markdown specs — dependency +resolution, state-machine enforcement, context packaging, and learning +propagation — without introducing a database or breaking APS's +portable-markdown philosophy. + +## Background + +APS specs already contain everything needed for orchestration: work items with +dependencies, status fields, modules with scope boundaries. What's missing is +a programmatic interface for agents to navigate the plan without manually +scanning markdown. + +Research into BMAD Method and Overseer (see +[docs/research/orchestration-patterns.md](../../docs/research/orchestration-patterns.md)) +identified a synthesis: use BMAD's pattern (LLM as orchestrator, files as +truth) with Overseer's pattern (programmatic `nextReady()`, state enforcement) +by building CLI tools that read from and write back to markdown. + +### Key Design Principles + +1. **Markdown is the database** — no SQLite, no separate state store. The CLI + parses `.aps.md` files directly and writes changes back to them. +2. **Progressive enhancement** — the CLI is optional. Agents and humans can + always work directly with markdown. The CLI just makes it faster and less + error-prone. +3. **Tool-agnostic** — the CLI works in any shell. An optional MCP server wraps + it for agents that support MCP. A Conductor agent wraps it in prompts for + agents that don't. +4. **No drift** — there is no second source of truth that can get out of sync. + +## In Scope + +- CLI commands for plan navigation (`next`, `start`, `complete`, `status`, + `learn`) +- Dependency resolution from work item `Dependencies` fields +- State-machine enforcement (prevent invalid status transitions) +- Context packaging (assemble focused briefing when starting a work item) +- Learning capture and propagation (attach insights to work items/modules) +- Optional MCP server wrapping CLI operations +- Optional Conductor agent definition for prompt-based orchestration +- Optional VCS integration (branch-per-work-item) + +## Out of Scope + +- Replacing direct markdown editing (CLI is additive, not required) +- Real-time sync daemons +- Hosted services or cloud components +- Vendor-specific integrations (those belong in TASKS or INTEGRATIONS) +- Automated agent-to-agent communication (agents are dispatched by humans or + by the Conductor agent, not by each other) + +## Interfaces + +**Depends on:** + +- VAL (validation) — reuse markdown parser for reading APS documents +- AGENT (agents) — Conductor agent is a variant of the Planner agent + +**Exposes:** + +- `aps next [module]` — resolve next-ready work item (DFS through deps) +- `aps start ` — mark In Progress, optionally create VCS branch, assemble + context package +- `aps complete ` — validate state transition, mark Complete, prompt for + learnings +- `aps learn "insight"` — attach learning to work item, propagate to + module +- `aps graph [module]` — show dependency graph with status coloring +- Optional: MCP server with codemode (single `execute` tool, natural language + routing à la Overseer) +- Optional: Conductor agent (`.claude/agents/aps-conductor.md` etc.) +- Optional: Context package generator + +## Concept Design + +### CLI Operations + +``` +$ aps next +→ AUTH-003: Implement token refresh + Module: auth | Dependencies: AUTH-001 ✓, AUTH-002 ✓ | Status: Ready + +$ aps start AUTH-003 +→ Marked AUTH-003 as In Progress +→ Context package: .aps/context/AUTH-003.md (assembled from module scope, + parent decisions, dependency learnings) +→ Branch: work/AUTH-003 (created, checked out) + +$ aps complete AUTH-003 +→ Validated: AUTH-003 was In Progress → Complete ✓ +→ Learning? (optional): "Token refresh needs retry logic for network failures" +→ Marked AUTH-003 as Complete +→ Learning attached and propagated to auth module + +$ aps graph auth +→ AUTH-001 [Complete] ──→ AUTH-003 [Complete] + AUTH-002 [Complete] ──┘ + AUTH-004 [Ready] ←── AUTH-003 + AUTH-005 [Draft] (blocked by AUTH-004) +``` + +### Context Packaging + +When `aps start` is called, it assembles a context package: + +```markdown +# Context: AUTH-003 — Implement token refresh + +## Work Item +[Pulled from auth.aps.md — intent, outcome, validation, files] + +## Module Scope +[Pulled from auth.aps.md — purpose, in-scope, interfaces] + +## Decisions +[Pulled from auth.aps.md — relevant decisions] + +## Dependency Learnings +- AUTH-001: "JWT library requires explicit algorithm whitelist" +- AUTH-002: "Session store must handle concurrent access" + +## Related Files +[From work item Files field, expanded to actual paths] +``` + +This is analogous to BMAD's story files — a self-contained context that lets +an agent start fresh with everything it needs. + +### State Machine + +``` +Work Item States: + Draft ──→ Ready ──→ In Progress ──→ Complete + ↑ │ + └─────────┘ (reset if blocked) + +Module States: + Draft ──→ Ready ──→ In Progress ──→ Complete +``` + +The CLI enforces valid transitions. `aps complete` rejects items not In +Progress. `aps start` rejects items whose dependencies aren't Complete. + +### MCP Server (Optional) + +Wraps CLI operations as a single MCP codemode tool: + +```json +{ + "name": "aps", + "description": "APS plan orchestration", + "inputSchema": { + "type": "object", + "properties": { + "command": { "type": "string" } + } + } +} +``` + +Agent sends: `"What's the next ready work item in the auth module?"` +Server parses intent, runs `aps next auth`, returns structured result. + +### Conductor Agent (Optional) + +A rich agent definition (like BMAD's BMad Master) that: + +- Knows the full APS lifecycle and rules +- Has a decision tree: assess plan → pick next item → dispatch to agent → + validate checkpoint → capture learnings +- Uses CLI commands internally when available, falls back to direct markdown + reading when not +- Works on any platform as a prompt file + +## Ready Checklist + +- [x] Purpose and scope are clear +- [x] Dependencies identified +- [x] Decisions resolved (D-001 through D-005) +- [x] Work items defined (ORCH-001 through ORCH-006) + +## Work Items + +### ORCH-001: Implement `aps next` command + +- **Intent:** Enable programmatic dependency resolution from APS markdown +- **Expected Outcome:** `aps next [module]` parses work items from `.aps.md` + files, resolves dependency chains, returns next Ready item whose deps are + all Complete. Reuses VAL module's markdown parser. +- **Validation:** `aps next` returns correct item in a project with mixed + statuses and cross-module dependencies +- **Confidence:** high +- **Dependencies:** VAL (parser) + +### ORCH-002: Implement `aps start` and `aps complete` + +- **Intent:** Enforce state transitions and capture learnings +- **Expected Outcome:** `aps start ` marks In Progress in markdown, + suggests branch name (`work/`), assembles context package. `aps complete + ` validates transition (must be In Progress), marks Complete, prompts + for optional learning (`- **Learning:** "..."`). Both reject invalid + transitions with clear error messages. +- **Validation:** Status fields update in-place; invalid transitions rejected; + learning appended when provided +- **Confidence:** high +- **Dependencies:** ORCH-001 + +### ORCH-003: Implement context packaging + +- **Intent:** Assemble focused context when starting a work item +- **Expected Outcome:** `aps start` generates `.aps/context/.md` + (gitignored, ephemeral) with: work item details, module scope and + interfaces, relevant decisions, dependency learnings, related file paths +- **Validation:** Context file contains all expected sections; regeneration + produces fresh output +- **Confidence:** medium +- **Dependencies:** ORCH-002 + +### ORCH-004: Implement `aps graph` + +- **Intent:** Visualize dependency graph with status +- **Expected Outcome:** ASCII graph showing work items, dependency arrows, + and status indicators (color or symbols). Optionally scoped to a module. +- **Validation:** Graph renders correctly for example project with 5+ items + and cross-module deps +- **Confidence:** medium +- **Dependencies:** ORCH-001 + +### ORCH-005: Create Conductor agent + +- **Intent:** Provide prompt-based orchestration for any tool +- **Expected Outcome:** Agent definition (multi-harness via scaffold/agents/) + that can drive APS workflows: assess plan state, pick next item, dispatch + to implementer agent, validate checkpoint, capture learnings. Uses CLI + commands when available, falls back to direct markdown reading. +- **Validation:** Agent dispatched via Task tool navigates a plan correctly + across 2+ work items +- **Confidence:** medium +- **Dependencies:** ORCH-001, AGENT-001 + +### ORCH-006: Create MCP server + +- **Intent:** Expose orchestration to MCP-capable agents +- **Expected Outcome:** TypeScript MCP server (using MCP SDK) wrapping CLI + operations. Single codemode tool with natural language routing. Agents + send requests like "next ready item in auth" and get structured results. +- **Validation:** MCP tool discovery succeeds; agent can call `aps next` + through MCP; server handles malformed input gracefully +- **Confidence:** low +- **Dependencies:** ORCH-001, ORCH-002 + +## Decisions + +- **D-001:** Should ORCH absorb TASKS or coexist? — *decided: coexist. ORCH + is the tool-agnostic CLI layer (dependency resolution, state machine, + context packaging). TASKS is a Claude Code-specific integration that can + leverage ORCH's foundation. Revisit if TASKS never matures.* +- **D-002:** Learning storage format — *decided: inline in work item metadata + (`- **Learning:** "..."` after Validation field). Simpler, keeps everything + in one place, no sync issues. Learnings are per-work-item, not per-module.* +- **D-003:** VCS integration scope — *decided: advisory only. `aps start` + suggests a branch name (`work/AUTH-003`) but does not create it. APS manages + planning, not git workflow. Users have their own branching strategies.* +- **D-004:** MCP server language — *decided: TypeScript using MCP SDK (Phase 3, + optional). The MCP protocol requires JSON-RPC over stdio which shell can't + handle cleanly. CLI stays pure bash. MCP server is an optional wrapper for + agents that support MCP.* +- **D-005:** Context package location — *decided: ephemeral at `.aps/context/` + (gitignored). Context packages are assembled fresh on `aps start` from + versioned source data (work items, modules, decisions). No need to version + the assembled output — it would just be clutter.* + +## Execution Strategy + +### Phase 1: CLI Foundation + +- ORCH-001: `aps next` (dependency resolution) +- ORCH-002: `aps start` / `aps complete` (state machine) + +### Phase 2: Context and Visualization + +- ORCH-003: Context packaging +- ORCH-004: `aps graph` + +### Phase 3: Agent Integration + +- ORCH-005: Conductor agent +- ORCH-006: MCP server + +## Relationship to Other Modules + +| Module | Relationship | +|--------|-------------| +| **TASKS** | Alternative/complement — TASKS is Claude Code-specific; ORCH is tool-agnostic. Could coexist or merge. | +| **AGENT** | ORCH's Conductor agent extends the Planner agent concept | +| **VAL** | ORCH reuses VAL's markdown parser | +| **COMPOUND** | ORCH's learning capture feeds into COMPOUND's solution docs | +| **INSTALL** | ORCH CLI commands and MCP server need installation support | + +## Notes + +- This module is explicitly exploratory. It captures patterns from BMAD Method + (prompt-based orchestration, step-file architecture, context packaging) and + Overseer (programmatic `nextReady()`, state enforcement, learning + propagation) and synthesizes them for APS. +- The core bet: **markdown can be both human-readable AND machine-queryable** + if you build a thin CLI layer that parses it. No database needed. +- The CLI should be implementable as an extension of the existing `./bin/aps` + script, reusing the VAL module's parser. +- Phase 1 (CLI foundation) is achievable quickly — it's essentially `grep + + parse + sed` on structured markdown. +- Phases 2-3 are progressive enhancements that add value but aren't required + for basic use. + +## Research + +- [Orchestration Patterns: BMAD, Overseer, and APS](../../docs/research/orchestration-patterns.md) +- [BMAD Plugin Feasibility](../../docs/research/bmad-plugin-feasibility.md) diff --git a/plans/modules/tui.aps.md b/plans/modules/tui.aps.md new file mode 100644 index 0000000..4e985f3 --- /dev/null +++ b/plans/modules/tui.aps.md @@ -0,0 +1,260 @@ +# TUI Onboarding Module + +| ID | Owner | Status | +|----|-------|--------| +| TUI | @aneki | Ready | + +## Purpose + +Provide a customization frontend for APS project setup. The shell-prompt wizard +(INSTALL module) proved the concept but is limited to a few coarse presets. +The TUI wizard unlocks granular configuration — users choose exactly what to +deploy rather than getting a one-size-fits-all scaffold. + +Built with Rust/Ratatui via the shared `eddacraft/eddacraft-tui` crate, +matching the Anvil product family's visual identity. + +## Background + +The INSTALL module (v0.3) shipped a shell-prompt wizard with 3 prompts: +profile, scope, and AI tooling. This covers the basics but forces broad +presets — you get "small feature" or "multi-module initiative" with little +control over what actually gets installed. + +Users need finer-grained choices: + +- **What to deploy:** pick individual agents, specific hooks, opt in/out of + lint, rules, context docs +- **Where things go:** custom paths for plans directory, docs location +- **Project shape:** monorepo vs single-project, with monorepo-specific + options (workspace detection, per-package plans) +- **Templates:** choose from available templates or bring your own, not just + the 4 scope presets +- **Tool configuration:** per-tool hook verbosity, model preferences, which + skills to install + +Shell prompts can't scale to this many options without becoming painful. A +TUI with sections, back-navigation, and sensible defaults makes granular +customization accessible. + +The base TUI framework lives at `eddacraft/eddacraft-tui` (Ratatui widgets, +shared theme, keyboard conventions). APS consumes this as a crate dependency. + +### Why Now + +- Shell-prompt wizard is complete and stable — the interim step served its + purpose +- Users are asking for more control over what gets scaffolded +- `eddacraft/eddacraft-tui` provides shared widgets (select, multi-select, + spinner, results dashboard) ready for consumption +- Anvil already uses the same TUI library — proven patterns exist +- Single static binary distribution simplifies install (`curl` downloads binary + instead of bash scripts) + +## In Scope + +- Rust CLI binary (`aps-cli`) with `init` subcommand implementing the TUI + wizard +- Wizard sections: Profile, Project Shape, Templates, AI Tooling, Paths, + Scaffold, Summary +- Granular customization within each section: + - **Project shape:** monorepo vs single, workspace detection, per-package + plans + - **Templates:** choose from available templates, custom template paths + - **AI tooling:** per-tool agent selection, hook verbosity, model preferences + - **Paths:** custom plans directory, docs location, tooling root + - **Components:** opt in/out of individual features (lint, rules, + project-context, agents, hooks) +- Consume `eddacraft/eddacraft-tui` for widgets and theme +- Non-interactive fallback via flags and config file +- Cross-compiled static binaries for 5 targets (linux-x64, linux-arm64, + darwin-arm64, darwin-x64, windows-x64) +- GitHub release asset publishing +- Port `aps lint` to native Rust (shared parser with ORCH module) + +## Out of Scope + +- Removing the shell-prompt wizard (kept as lightweight alternative) +- MCP server or orchestration commands (separate ORCH module) +- Developing `eddacraft/eddacraft-tui` itself (consumed as dependency) +- Runtime configuration changes (wizard is for initial setup; `config.yml` + handles updates) + +## Interfaces + +**Depends on:** + +- INSTALL (Complete) — defines what gets scaffolded; TUI replaces the + shell-prompt frontend while reusing scaffold logic +- `eddacraft/eddacraft-tui` (external) — shared Ratatui widgets and theme + +**Exposes:** + +- `aps init` — TUI wizard (replaces shell-prompt wizard as default interactive + path) +- `aps init --non-interactive` — flag-based fallback for CI +- `aps lint` — optional native port of bash linter +- GitHub release binaries per platform + +## Decisions + +- **D-026:** Where does `aps-cli` source live? — *decided: in this repo under + `cli/`. Keeps everything together. Acknowledged trade-off: APS grows from + pure templates/docs into a repo with deployable code — increased scope and + CI complexity.* +- **D-027:** Shared TUI components — *decided: consume `eddacraft/eddacraft-tui` + as git dependency for now. Publish as crate later if needed.* +- **D-028:** Should `aps lint` be ported to Rust? — *decided: yes. The Rust + markdown parser serves TUI, ORCH (`aps next`), and lint from a single + codebase. Also provides a reference implementation portable to + `eddacraft/anvil-001` (currently TS). Trade-off: reimplements working bash + code, but the shared parser justifies the cost.* + +## Ready Checklist + +- [x] Purpose and scope are clear +- [x] Dependencies identified +- [x] D-026 resolved (in this repo under `cli/`) +- [x] D-027 resolved (git dependency) +- [x] D-028 resolved (yes, port lint to Rust) +- [x] Work items defined with validation + +## Work Items + +### TUI-001: Project setup and eddacraft-tui integration + +- **Intent:** Establish the Rust project structure and confirm `eddacraft-tui` + crate integration works +- **Expected Outcome:** `cli/` directory (or separate repo per D-026) with + `Cargo.toml` depending on `eddacraft-tui`, clap for CLI parsing, and a + minimal `aps --version` command that compiles and runs +- **Validation:** `cargo build --release` produces a static binary; binary + prints version; `eddacraft-tui` widgets render in a test harness +- **Confidence:** high +- **Dependencies:** D-026, D-027 + +### TUI-002: Implement core wizard sections (Profile, Project Shape, AI Tooling) + +- **Intent:** Build the primary selection screens that determine what gets + scaffolded +- **Expected Outcome:** Wizard sections using eddacraft-tui widgets: + 1. **Profile** (single-select): solo dev / team / AI agent operator + 2. **Project shape** (single-select + conditional): monorepo vs single + project. Monorepo selection exposes workspace tool detection (pnpm, turbo, + nx, lerna) and per-package plan options. + 3. **AI tooling** (multi-select + per-tool config): select tools, then + configure each — which agents to install, hook verbosity + (full/minimal/none), model preferences where applicable. + Back-navigation via Esc. Keyboard conventions match Anvil. Selections stored + in wizard state. +- **Validation:** User can navigate forward and back through all sections; + monorepo options only appear when monorepo selected; per-tool config only + shows for selected tools; q/Ctrl+C exits cleanly +- **Confidence:** high +- **Dependencies:** TUI-001 + +### TUI-003: Implement template and path customization sections + +- **Intent:** Let users control what templates get installed and where files go +- **Expected Outcome:** Two additional wizard sections: + 1. **Templates** (multi-select): choose from available plan templates + (quickstart, module, index, monorepo-index), option to specify custom + template path. Profile and project shape inform defaults but user can + override. + 2. **Paths** (text inputs with defaults): plans directory (default: + `plans/`), docs location, tooling root (default: `.aps/`). Preview of + resulting directory structure updates live as paths change. + 3. **Components** (checkbox): opt in/out of individual features — lint rules, + aps-rules.md, project-context.md, designs/ directory, decisions/ directory +- **Validation:** Custom paths produce valid scaffold at specified locations; + template selection matches scaffolded output; component toggles respected +- **Confidence:** medium +- **Dependencies:** TUI-001 + +### TUI-004: Implement scaffold and summary steps + +- **Intent:** Execute scaffold with visual progress and show results +- **Expected Outcome:** Two final wizard steps: + 1. **Scaffold** — spinner/progress widget showing each action (create dirs, + install templates, install skills, install agents, configure hooks, run + lint). Scaffold logic reimplemented in Rust (not shelling out to bash). + Errors shown inline. + 2. **Summary** — results dashboard showing installed components, per-tool + post-install instructions (e.g., `codex skills install`), custom paths + used, next steps, doc links. Matches EddaCraft visual style. +- **Validation:** Scaffold produces correct file structure for all selection + combinations; summary accurately reflects what was installed; progress + renders without flicker +- **Confidence:** medium +- **Dependencies:** TUI-002, TUI-003 + +### TUI-005: Non-interactive fallback and config-driven init + +- **Intent:** Support CI, piped environments, and repeatable setups +- **Expected Outcome:** Two non-interactive paths: + 1. **Flags:** `aps init --non-interactive --profile solo --shape monorepo + --tools claude-code,copilot --plans-dir docs/plans` — all wizard options + available as CLI flags. + 2. **Config file:** `aps init --from .aps/config.yml` — replay a previous + configuration (enables team-wide standardization: commit config, teammates + run `aps init --from`). + Auto-detects non-TTY and falls back to flag mode with smart defaults. +- **Validation:** Both paths produce valid scaffold; config-driven init matches + TUI-driven init for same selections; exit code 0/non-zero +- **Confidence:** high +- **Dependencies:** TUI-004 + +### TUI-006: Cross-compilation and release + +- **Intent:** Distribute as pre-built binaries via GitHub releases +- **Expected Outcome:** CI workflow (GitHub Actions) that cross-compiles for 5 + targets using `cross` or `cargo-zigbuild`, creates GitHub release with + binaries as assets. `curl | bash` installer updated to optionally download + binary instead of bash scripts. +- **Validation:** Binaries run on each target platform; GitHub release has all + 5 assets; `curl` installer can fetch and install the binary +- **Confidence:** medium +- **Dependencies:** TUI-005 + +## Execution Strategy + +### Wave 1: Foundation + +- TUI-001: Project setup + eddacraft-tui integration + +### Wave 2: Wizard sections (depends on Wave 1, parallel) + +- TUI-002: Core sections (profile, project shape, AI tooling) +- TUI-003: Template and path customization sections + +### Wave 3: Scaffold + fallback (depends on Wave 2) + +- TUI-004: Scaffold execution + summary dashboard +- TUI-005: Non-interactive fallback + config-driven init + +### Wave 4: Distribution (depends on Wave 3) + +- TUI-006: Cross-compilation and GitHub releases + +## Relationship to Other Modules + +| Module | Relationship | +|--------|-------------| +| **INSTALL** | TUI replaces INSTALL's shell-prompt frontend; scaffold logic stays | +| **ORCH** | Shared markdown parser opportunity if lint is ported to Rust (D-028) | +| **VAL** | Native lint port would subsume VAL's bash linter | + +## Notes + +- The shell-prompt wizard (`scaffold/install`) remains as the lightweight, + zero-dependency alternative. Both paths produce the same file structure. +- `eddacraft/eddacraft-tui` provides: Select, MultiSelect, Confirm, Spinner, + Header, ResultsDashboard widgets plus the shared EddaCraft theme. APS should + not duplicate these. +- Keyboard conventions are shared across the Anvil product family — arrows/j-k + for navigation, Enter to confirm, Space to toggle, Esc to go back, q to quit. +- The binary replaces `bin/aps` (bash) as the primary CLI. The bash version + remains for users who don't want to download a binary. +- Cross-compilation target list: `x86_64-unknown-linux-gnu`, + `aarch64-unknown-linux-gnu`, `aarch64-apple-darwin`, + `x86_64-apple-darwin`, `x86_64-pc-windows-gnu`. diff --git a/plans/research/orchestration-patterns.md b/plans/research/orchestration-patterns.md new file mode 100644 index 0000000..436977d --- /dev/null +++ b/plans/research/orchestration-patterns.md @@ -0,0 +1,447 @@ +# Orchestration Patterns: BMAD, Overseer, and APS + +> Research conducted: 2026-02-25 +> Status: Complete +> Context: Exploring whether APS should offer native orchestration as an +> optional capability, informed by how BMAD and Overseer approach the problem. + +## Executive Summary + +BMAD Method and Overseer represent two fundamentally different approaches to +AI-agent orchestration. BMAD uses **prompt engineering** — the LLM itself is +the execution engine, guided by structured files it reads at runtime. Overseer +uses a **programmatic engine** — a Rust binary with SQLite state, exposed via +MCP. APS currently sits closer to BMAD's philosophy (markdown is truth, no +runtime dependencies) but lacks the programmatic affordances that would let +agents self-drive through a plan. + +**Recommendation:** Offer an optional ORCHESTRATE module that layers +lightweight CLI tooling on top of existing APS markdown specs — giving agents +programmatic `next`, `start`, `complete` operations without introducing a +database or breaking APS's portable-markdown philosophy. + +--- + +## 1. BMAD Method v6 — Deep Analysis + +### What BMAD Actually Is + +BMAD is a **prompt engineering framework**, not a software orchestration system. +The entire "orchestration" works by loading files into the LLM context window: + +1. **Agent definitions** (YAML → compiled to XML-wrapped markdown) give the LLM + a persona, menu, and behavioral constraints +2. **`workflow.xml`** is the "core OS" — XML instructions telling the LLM how + to process YAML workflow configs step-by-step +3. **Handoffs are manual** — the user invokes each slash command; the LLM reads + the next file and follows instructions +4. **State is `sprint-status.yaml`** — a flat YAML file updated by agents as + instructed by their workflow steps +5. **IDE integration** generates platform-native command files (slash commands + for Claude Code, rules for Cursor, etc.) that instruct the LLM to read + specific files from `_bmad/` + +Key repository: + +### BMAD Orchestration Mechanics + +**The BMad Master Agent** (`src/core/agents/bmad-master.agent.yaml`) is a +meta-agent that greets the user, lists available tasks/workflows from CSV +manifests, and routes to specialized agents. It does not execute code — it is +a prompt personality loaded into an LLM context window. + +**The Workflow Engine** (`src/core/tasks/workflow.xml`) processes every YAML +workflow through a 3-step flow: + +1. Load and initialize — resolve config references, system variables, ask user + for unknowns +2. Process each instruction step — handles `action`, `check`, `ask`, `goto`, + `invoke-workflow`, `invoke-task`, `invoke-protocol`, `template-output` tags +3. Completion — confirm outputs saved, report status + +**Handler dispatch** (not automated agent-to-agent handoffs): + +- `workflow="path.yaml"` → load workflow.xml, pass the YAML as config +- `exec="path.md"` → read the markdown file and follow all instructions +- `action` → inline operations (list files, etc.) + +**The `/bmad-help` router** (`src/core/tasks/help.md`) reads a CSV catalog and +uses phase/sequence ordering to recommend what the user should do next, checking +which artifacts already exist. + +### BMAD State Management + +**`sprint-status.yaml`** is the central state file: + +```yaml +development_status: + epic-1: in-progress + 1-1-user-authentication: done + 1-2-account-management: ready-for-dev + 1-3-plant-data-model: backlog + epic-2: backlog + 2-1-personality-system: backlog +``` + +Status machines: + +- **Epic:** backlog → in-progress → done +- **Story:** backlog → ready-for-dev → in-progress → review → done + +Each workflow agent updates this file as part of its instructions. There is no +programmatic enforcement — the LLM follows instructions to update YAML fields. + +### BMAD Agent Architecture + +Every agent YAML has: `metadata` (id, name, title, icon, module, capabilities), +`persona` (role, identity, communication_style, principles), optional +`critical_actions`, and `menu` items. The compiler (`tools/cli/lib/agent/compiler.js`) +converts YAML to XML-wrapped markdown, injecting activation steps and handler +logic from shared components. + +Notable: the Dev agent has strict `critical_actions` enforcing TDD, sequential +task execution, and honest reporting — behavioral constraints enforced purely +through prompting. + +### BMAD Context Packaging (Epic Sharding) + +Large documents (PRD, Architecture, Epics) can be split into smaller files via +`shard-doc.xml` (splits on `##` headings, generates `index.md`). The +`discover_inputs` protocol handles both formats transparently: + +- `FULL_LOAD` — load all files in sharded directory +- `SELECTIVE_LOAD` — load specific shard by template variable +- `INDEX_GUIDED` — load index, analyze structure, intelligently select docs + +Story files are "ultimate context engines" — self-contained docs aggregating +context from epics, architecture, previous stories, git history, and web +research so a Dev agent can implement without other documents. + +### BMAD v6 Key Changes + +1. **Step-file architecture** — each workflow step is a separate `.md` file + loaded just-in-time (saves tokens) +2. **Direct slash command invocation** — workflows invocable without agent menus +3. **Smart input discovery** — `discover_inputs` protocol with 3 load strategies +4. **Cross-file reference validation** — ~483 references across ~217 files +5. **Module system** — core + extension modules (bmm, tea, bmgd, cis) +6. **20+ IDE/CLI platform support** — Claude Code, Cursor, Gemini CLI, etc. + +### BMAD's Key Insight + +The LLM itself is the best orchestrator — give it structured prompts, file +conventions, and behavioral constraints, and it will execute a complex agile +workflow. No daemon, no database, no API needed. The "integration" is just +where to put the command files so the IDE discovers them. + +--- + +## 2. Overseer — Deep Analysis + +### What Overseer Is + +Overseer is a **programmatic task execution engine** — a Rust binary with +SQLite state management, exposed to LLM agents via MCP (Model Context Protocol). + +Repository: + +### Overseer Architecture + +``` +┌─────────────────────────────────────────┐ +│ MCP Interface │ +│ (codemode: single "execute" tool) │ +├─────────────────────────────────────────┤ +│ TaskExecutionEngine │ +│ nextReady() → start() → complete() │ +├─────────────────────────────────────────┤ +│ PlanRepository │ +│ plans/milestones/tasks (SQLite) │ +├─────────────────────────────────────────┤ +│ GitIntegration │ +│ branch-per-task, auto-commit │ +└─────────────────────────────────────────┘ +``` + +### Overseer State Management + +State lives in SQLite with a strict lifecycle: + +``` +Plan: Draft → Active → Completed → Archived +Milestone: Pending → Active → Completed +Task: Pending → Ready → InProgress → Completed → Verified +``` + +The engine enforces transitions programmatically. `nextReady()` resolves +dependencies and returns the next task to execute. + +### Overseer's MCP Codemode Pattern + +Overseer exposes a **single MCP tool** called `execute` that accepts natural +language commands. The LLM sends requests like: + +``` +"List all ready tasks" +"Start task 5" +"Complete task 5 with summary: implemented auth flow" +``` + +The server parses intent and routes to the appropriate operation. This +"codemode" pattern reduces the tool surface area while keeping natural language +flexibility. + +### Overseer Context System + +Each task gets **progressive context**: its own description, parent milestone +context, plan-level context, and relevant milestone learnings. Learnings are +captured at task completion and propagated to related milestones. + +### Overseer VCS Integration + +Branch-per-task with auto-commit: + +- Starting a task creates `task/plan-/task-` branch +- Completing a task commits and optionally merges +- Clean separation of work streams + +### Overseer's Key Insight + +Programmatic `nextReady()` and state enforcement catch mistakes the LLM won't. +When agents can call `next()` to self-drive through a dependency graph, they +need less human intervention between steps. + +--- + +## 3. Comparison Matrix + +| Dimension | BMAD | Overseer | APS (current) | +|-----------|------|----------|---------------| +| **Engine** | LLM reads files | Rust binary + SQLite | LLM reads markdown specs | +| **State store** | `sprint-status.yaml` | SQLite database | Markdown Status fields | +| **State enforcement** | Prompt instructions | Programmatic | None (human reviews) | +| **Dispatch** | User picks slash command | Agent calls `nextReady()` | Human-directed | +| **Dependencies** | Implicit (phase ordering) | Explicit (DAG in SQLite) | Explicit (Dependencies field) | +| **Context** | Epic sharding → story files | Progressive (parent + learnings) | Re-read spec (5-Op Rule) | +| **VCS** | None | Branch-per-task | None | +| **Portability** | Any LLM that reads files | MCP-capable tools only | Any tool (pure markdown) | +| **Runtime deps** | None | Rust binary + SQLite | None | +| **Learning** | Previous story intelligence | Milestone learnings | Compound (solution docs) | +| **Platform support** | 20+ IDEs via command files | MCP clients | Any tool via AGENTS.md/skills | + +--- + +## 4. The Gap APS Could Fill + +### What BMAD gets right and wrong + +BMAD nails the philosophy: no runtime dependencies, files are truth, any LLM +can participate. But it has no programmatic safety net. When the Dev agent is +told "pick the next story from sprint-status.yaml," it reads a YAML file and +makes a judgment call. If it misreads a dependency, skips a blocked story, or +marks something done that isn't — nothing catches it. The entire workflow +depends on prompt quality and the LLM paying attention. At scale (19+ agents, +50+ workflows), this is a real fragility. BMAD compensates with extremely +detailed prompts and `critical_actions` constraints, but it's guardrails on +guardrails with no ground truth check. + +### What Overseer gets right and wrong + +Overseer nails the programmatic layer: `nextReady()` resolves a real dependency +graph, state transitions are enforced, learnings propagate. But it introduces +a database that becomes the real source of truth, with markdown as a lossy +export. If the SQLite state and the plan description drift, you have two +sources of truth and no clear winner. It also requires a Rust binary and MCP — +not portable, not inspectable by humans, not versionable in git. The database +solves the "LLM makes mistakes" problem but creates a "humans can't see the +state" problem. + +### Where APS sits today + +APS has the specs right — modules, work items, dependencies, status fields, +action plans. All in portable markdown, all git-versioned. But there's a +practical gap when an agent is actually executing: + +1. **"What's next?" requires scanning.** An agent starting a session has to + read every module, find items where status=Ready, check each item's + dependencies against other items' statuses, and pick one. That's 3-5 file + reads and a mental join across them. LLMs do this unreliably — they miss + items, misread statuses, or pick something whose dependency isn't actually + complete yet. + +2. **State transitions aren't enforced.** Nothing prevents an agent from + marking AUTH-003 as Complete when AUTH-002 (its dependency) is still Draft. + Nothing prevents skipping "In Progress" and going straight to Complete. + APS describes valid states in aps-rules.md, but the LLM has to remember + and follow the rules every time. + +3. **Context is scattered.** When starting AUTH-003, an agent needs: the work + item intent, the module scope, relevant decisions, what was learned from + AUTH-001 and AUTH-002, and the file paths involved. Today the agent has to + manually assemble this from multiple files. BMAD solved this with + self-contained "story files." Overseer solved it with progressive context + injection. APS has no equivalent. + +4. **Learnings don't compound.** When an agent finishes a work item and + discovers something useful ("the token library requires explicit algorithm + whitelisting"), there's nowhere structured to capture that insight so the + next work item benefits. The Compound module proposes solution docs, but + that's for cross-project knowledge — there's no in-plan learning loop. + +### The gap in one sentence + +**APS has the data for orchestration but no programmatic interface to it.** The +dependency graph exists in markdown. The state machine exists in aps-rules.md. +The context exists across module files. But there's no `nextReady()` to query +the graph, no `start()` to enforce transitions, no `context()` to assemble +a briefing, and no `learn()` to capture insights. + +Neither BMAD nor Overseer fills this gap well. BMAD doesn't have the +programmatic layer at all. Overseer has it but abandons markdown as truth. + +### Recommendation: CLI on markdown + +The synthesis is to build a thin CLI that treats markdown as a queryable +database. The parser already exists (VAL module). The data model already exists +(APS spec format). The gap is a handful of commands that parse the specs and +return structured answers. + +``` +┌──────────────────────┐ +│ APS Markdown Specs │ Source of truth (always, git-versioned) +└──────────┬───────────┘ + │ parse + write back + ┌─────┼─────────────────┐ + │ │ │ +┌────▼───┐ ┌──▼────┐ ┌──────▼───┐ +│Conductor│ │aps CLI│ │MCP Server│ +│ Agent │ │(shell)│ │(optional)│ +│(prompt) │ │ │ │ │ +└─────────┘ └───────┘ └──────────┘ + │ │ │ + └──────────┼────────────┘ + │ + ┌──────────▼───────────┐ + │ Agent Execution │ + │ (any tool, any LLM) │ + └──────────────────────┘ +``` + +What this gives you: + +- **`aps next`** — resolves the dependency graph and returns the next ready + item. No more scanning. No more missed dependencies. An agent or human calls + one command and gets a definitive answer. +- **`aps start `** — enforces the Ready → In Progress transition, rejects + invalid moves, optionally assembles a context package and creates a VCS + branch. The agent gets everything it needs in one call. +- **`aps complete `** — enforces In Progress → Complete, rejects skipped + states, prompts for an optional learning. The state machine is now real, not + aspirational. +- **`aps learn "insight"`** — attaches a learning to the work item and + propagates it to the module. When the next item starts, its context package + includes prior learnings. +- **`aps graph`** — renders the dependency graph with status. Humans get + visibility; agents get structure. + +What this preserves: + +- **Markdown stays canonical.** The CLI reads `.aps.md` files and writes + changes back to them. There is no database, no separate state store, nothing + that can drift. `git diff` shows every state change. +- **Fully optional.** The CLI is additive. Agents and humans can always work + directly with markdown. The CLI just makes it faster and less error-prone. + Projects that don't want the CLI lose nothing. +- **Tool-agnostic.** The CLI runs in any shell. An optional MCP server wraps + it for MCP-capable agents. A Conductor agent wraps it in prompts for tools + that don't have MCP. Every tool gets something. +- **Progressive enhancement.** Phase 1 is `next` + `start` + `complete` + (the core loop). Phase 2 adds context packaging and graph visualization. + Phase 3 adds MCP and the Conductor agent. Each phase is independently + useful. + +What this avoids: + +- **No database.** Overseer's SQLite is powerful but creates drift risk. We + skip it entirely — markdown is structured enough to query directly. +- **No daemon.** BMAD's event-driven proposals (agents listening for file + changes) add complexity APS doesn't need. Explicit commands are simpler. +- **No lock-in.** The CLI doesn't require MCP, doesn't require a specific + AI tool, doesn't require a specific LLM. It's shell commands that parse + markdown. + +--- + +## 5. Applicable Patterns from BMAD + +These BMAD patterns could enhance APS without changing its philosophy: + +### 5.1 Step-File Architecture + +BMAD's step-files load one step at a time into the LLM context, saving tokens. +APS action plans already do this (actions are sequential), but the pattern +could be more explicit — each action could reference external files for detailed +context rather than inlining everything. + +### 5.2 Context Packaging + +BMAD's story files are "ultimate context engines" — self-contained docs that +let an agent start fresh. APS could generate similar context packages when +starting a work item: pulling the item's intent, module scope, parent +decisions, and relevant learnings into a focused briefing. + +### 5.3 Smart Input Discovery + +BMAD's `discover_inputs` protocol handles both whole docs and sharded docs +with three load strategies. APS could use similar patterns when modules grow +large — sharding by section and loading selectively. + +### 5.4 Platform-Native Command Generation + +BMAD generates command files for 20+ platforms. APS already does this via +the AGENT module (Claude Code, Codex, Copilot, OpenCode, Gemini). The BMAD +approach confirms this is the right pattern for tool-agnostic distribution. + +### 5.5 Behavioral Constraints via Prompting + +BMAD's `critical_actions` (Dev agent must follow TDD, never skip tasks, never +lie about tests) are enforced purely through prompting. APS's aps-rules.md +serves the same purpose. The BMAD pattern validates that prompt-based +behavioral constraints work at scale. + +--- + +## 6. Applicable Patterns from Overseer + +### 6.1 Dependency Resolution (`nextReady()`) + +The most valuable Overseer pattern. APS work items already have `Dependencies` +fields — a CLI could parse these and return the next item whose dependencies +are all Complete and whose status is Ready. This removes guesswork from agents. + +### 6.2 Learning Propagation + +Overseer captures learnings at task completion and propagates them to related +milestones. APS could capture learnings in work item metadata and surface them +when starting related items — similar to BMAD's "previous story intelligence." + +### 6.3 State Machine Enforcement + +Overseer's programmatic state transitions prevent invalid moves (e.g., +completing a task that was never started). A CLI `aps complete` command could +validate transitions before updating the markdown. + +### 6.4 Codemode MCP Pattern + +Overseer's single-tool MCP interface (`execute` with natural language) is +elegant. An APS MCP server could expose similar natural-language-routed +operations rather than a large tool surface area. + +--- + +## Sources + +- [BMAD Method Repository](https://github.com/bmad-code-org/BMAD-METHOD) +- [BMAD Method Documentation](https://docs.bmad-method.org) +- [BMAD Party Mode](https://docs.bmad-method.org/explanation/party-mode/) +- [Overseer Repository](https://github.com/rust-syndicate/overseer) diff --git a/plans/reviews/APS-USABILITY-REVIEW.md b/plans/reviews/APS-USABILITY-REVIEW.md new file mode 100644 index 0000000..4b5bdde --- /dev/null +++ b/plans/reviews/APS-USABILITY-REVIEW.md @@ -0,0 +1,525 @@ +# APS Usability Review + +**Date:** 2025-12-25 +**Reviewer:** Claude (Critical Analysis) +**Scope:** Complete usability assessment of Anvil Plan Spec format, templates, documentation, and examples + +--- + +## Executive Summary + +APS presents a compelling vision for portable, tool-agnostic planning in AI-assisted development. However, several usability barriers may prevent adoption, particularly for new users. This review identifies 15 critical areas for improvement across documentation, templates, terminology, and workflow integration. + +**Severity Ratings:** + +- 🔴 **Critical** - Major barrier to adoption +- 🟡 **Important** - Degrades user experience significantly +- 🟢 **Minor** - Polish and refinement + +--- + +## 1. Terminology & Naming Issues + +### 🔴 "Leaf" is confusing and abstract + +**Problem:** The term "Leaf" doesn't communicate its purpose. Users must understand it's a "module" and that it's called "leaf" because it's the end of the planning tree. + +**Evidence:** + +- README.md:58-60 requires a multi-sentence explanation of why it's called "leaf" +- The table alternates between "Leaf/Module" creating confusion +- File names use "leaf.template.md" but examples use descriptive names like "auth.aps.md" + +**Impact:** New users won't understand what a "leaf" is without reading detailed explanation. The metaphor doesn't match common software terminology. + +**Recommendation:** + +- Rename to "Module Template" or "Work Module" +- Reserve "leaf" as a conceptual note in documentation +- Update all references: `module.template.md` instead of `leaf.template.md` + +### 🟡 "SCOPE" placeholder creates confusion + +**Problem:** Templates use `SCOPE` as a placeholder for module identifiers, but this conflicts with "In Scope / Out of Scope" sections. + +**Evidence:** + +- leaf.template.md:7 uses "SCOPE" in metadata table +- leaf.template.md:14-22 has "In Scope" and "Out of Scope" sections +- Task IDs use pattern "SCOPE-001" which reads awkwardly + +**Impact:** Users may think "SCOPE" has special meaning or unclear what to replace it with. + +**Recommendation:** + +- Use `MODULE-ID` or `{module-name}` as placeholder +- Provide clear examples: "AUTH", "PAYMENTS", "UI" +- Add guidance: "Use 2-6 character uppercase identifier" + +### 🟢 Inconsistent terminology for "execution authority" + +**Problem:** The concept of "execution authority" is used but not consistently explained. + +**Recommendation:** + +- Define clearly in glossary +- Use consistently across all documentation +- Consider simpler phrasing: "tasks authorise implementation" + +--- + +## 2. Template Complexity & Cognitive Load + +### 🔴 Too many required decisions upfront + +**Problem:** Users must understand the entire 4-layer hierarchy before creating their first spec. + +**Evidence:** + +- getting-started.md presents all concepts before letting users try anything +- Decision tree (lines 99-122) shows 7+ decision points +- No "quick start" template for trying APS without commitment + +**Impact:** High activation energy. Users bounce before seeing value. + +**Recommendation:** + +- Create `quickstart.template.md` - single-file, minimal fields +- "Try APS in 5 minutes" tutorial +- Progressive disclosure: start simple, add complexity as needed + +### 🟡 leaf.template.md has too many fields + +**Problem:** The full leaf template has 13+ distinct sections. Unclear which are truly required. + +**Fields count:** + +- Metadata table (4 fields) +- Purpose, In/Out Scope, Interfaces, Boundary Rules, Acceptance Criteria, Risks, Tasks, Execution, Decisions, Notes + +**Evidence:** + +- simple.template.md exists as a "lightweight" alternative, proving leaf is too heavy +- Examples don't fill all sections consistently + +**Impact:** Template feels bureaucratic, intimidating for small projects. + +**Recommendation:** + +- Mark optional sections clearly with *(optional)* in template +- Provide field-by-field guidance in comments +- Create a "minimal leaf" example showing bare essentials + +### 🟡 Task fields feel redundant + +**Problem:** Tasks require: Intent, Expected Outcome, Scope, Non-scope, Files, Dependencies, Validation, Confidence, Risks + +**Overlap:** + +- "Intent" vs "Expected Outcome" - semantic overlap +- "Scope" vs "Non-scope" - inversions of each other +- "Files" - often wrong, becomes stale + +**Impact:** Filling tasks feels repetitive and tedious. + +**Recommendation:** + +- Consolidate "Intent" and "Expected Outcome" into single field +- Make "Non-scope" explicitly optional (use only when clarification needed) +- Make "Files" optional with guidance: "Best effort, don't worry if incomplete" + +--- + +## 3. Documentation & Onboarding + +### 🔴 No minimal "hello world" example + +**Problem:** Users can't quickly try APS. Must set up folder structure, understand templates, etc. + +**Current flow:** + +1. Read README (151 lines) +2. Read getting-started.md (148 lines) +3. Choose template +4. Create folder structure +5. Fill template +6. Hope you did it right + +**Impact:** Hours to first value. High abandonment risk. + +**Recommendation:** + +```markdown +# hello-world.aps.md - Complete minimal example +Copy this file, replace the bracketed parts, and you're using APS! + +## What: [One sentence - what you're building] + +## Why: [One sentence - what problem it solves] + +## Success: +- [ ] [Observable outcome 1] +- [ ] [Observable outcome 2] + +## Tasks: +### Task 001: [First thing to build] +- **Outcome:** [How you know it's done] +- **Test:** `[command to verify]` +``` + +### 🟡 Getting started is comprehensive but overwhelming + +**Problem:** getting-started.md is thorough but front-loads too much information. + +**Flow issues:** + +- Step 1 shows full folder structure before explaining why +- Presents all template choices before user knows which they need +- Decision tree is helpful but comes late (line 99) + +**Recommendation:** + +- Lead with decision tree +- One-page quick start for common cases +- Move comprehensive guide to separate "Complete Guide" doc + +### 🟡 Examples are buried + +**Problem:** Examples (user-auth, opencode-companion) are excellent but not prominently featured. + +**Evidence:** + +- README.md:99-102 mentions them briefly +- getting-started.md:145 references them at the end +- Not shown in context of "when to use each template" + +**Recommendation:** + +- Create "Examples" section in README with screenshots/previews +- Link specific examples next to each template description +- Add "See example: user-auth/modules/auth.aps.md" in template comments + +--- + +## 4. Hierarchy & Structure Clarity + +### 🟡 "Non-executable" vs "Executable if Ready" is confusing + +**Problem:** Index is "non-executable", Leaf is "executable if tasks exist and status is Ready", Tasks are "execution authority" + +**Evidence:** + +- index.template.md:2 "This document is non-executable" +- leaf.template.md:2 "Executable only if tasks exist and status is Ready" +- Not clear what "executable" means in practice + +**Impact:** Users don't understand when to act on documents. + +**Recommendation:** + +- Replace "executable/non-executable" with clearer language: + - Index: "Planning document - describes intent, doesn't authorize work" + - Module: "Work can begin when status=Ready and tasks exist" + - Task: "Authorises implementation" +- Add workflow diagram showing the progression + +### 🟡 Unclear when to change status from Draft to Ready + +**Problem:** No clear criteria for when a module is "Ready" + +**Current guidance:** None explicit + +**Impact:** Users uncertain when to flip status, may start work prematurely or wait too long. + +**Recommendation:** + +- Add checklist to templates: + +```markdown +## Ready Checklist +Mark status as "Ready" when: +- [ ] Purpose and scope are clear +- [ ] Interfaces defined (or confirmed none needed) +- [ ] Dependencies resolved or explicitly blocked +- [ ] At least one task defined +- [ ] Stakeholder approval (if required) +``` + +--- + +## 5. File Organization & Conventions + +### 🟡 Folder structure is prescribed but not enforced + +**Problem:** Documentation shows `plans/` folder structure but examples use different structure. + +**Evidence:** + +- README.md:123-133 shows `plans/` at root +- getting-started.md:14-24 shows same +- examples/user-auth/ doesn't follow this (no `plans/` folder) + +**Impact:** Confusion about "correct" structure. + +**Recommendation:** + +- Either make examples follow the structure OR +- Explicitly state "structure is flexible, adapt to your needs" +- Provide 2-3 structure options (monorepo, standalone, embedded) + +### 🟢 .aps.md extension isn't explained + +**Problem:** Files use `.aps.md` extension but this isn't documented. + +**Recommendation:** + +- Explain in README: "We use .aps.md to distinguish spec files from regular docs" +- Note it's optional: "Plain .md works fine if you prefer" + +--- + +## 6. Workflow & Tool Integration + +### 🔴 Unclear how to actually "execute" tasks + +**Problem:** APS defines tasks but doesn't explain how they connect to actual development workflow. + +**Questions users will have:** + +- Do I create a git branch per task? +- Do I update the APS file as I work? +- When do I mark tasks complete? +- What if implementation reveals the task was wrong? + +**Current guidance:** README.md:79-86 shows "how to use APS" in different tools but not the workflow. + +**Impact:** APS feels like extra work, not workflow enhancement. + +**Recommendation:** + +- Add "Development Workflow" guide: + - How to pick a task + - How to track progress + - How to handle changes + - How to mark completion + - Integration with git/PRs +- Show concrete example: "Day in the life with APS" + +### 🟡 AI prompt usage is unclear + +**Problem:** docs/ai/prompting/ contains great prompts but unclear how to use them. + +**Evidence:** + +- getting-started.md:135-142 says "Reference" the prompts +- No examples of actually doing this in different tools +- OpenCode variants exist but unclear what's different + +**Recommendation:** + +- Add "Using AI Prompts" guide with tool-specific examples: + - Claude/ChatGPT: "Paste this into your conversation: [prompt + spec]" + - Cursor: "Add to .cursorrules: [prompt]" + - Claude Code: "Use slash command: /plan [spec-file]" +- Show before/after of AI assistance with vs without prompts + +### 🟢 No guidance on completion/archival + +**Problem:** What happens to tasks/modules when done? + +**Recommendation:** + +- Add completion guidance: + - Mark completed tasks with ~~strikethrough~~ or `✓ Completed: YYYY-MM-DD` + - Archive old specs to `plans/archive/` or keep as history + - Update Index when modules complete + +--- + +## 7. Validation & Quality + +### 🟡 No validation tooling + +**Problem:** Users can create invalid APS files with no feedback. + +**Evidence:** + +- ROADMAP.md mentions validation tooling (planned) +- Currently only markdownlint (formatting, not structure) + +**Impact:** Users may create malformed specs, miss required fields. + +**Recommendation:** + +- Build `aps validate` CLI tool: + - Check required fields present + - Validate task ID format + - Check dependency references resolve + - Warn on common issues +- JSON Schema for APS structure (enables IDE autocomplete) + +--- + +## 8. Missing Use Cases & Guidance + +### 🟡 Solo developer guidance missing + +**Problem:** Templates assume teams (owner field, stakeholders, etc.) + +**Evidence:** + +- All templates have "Owner: @username" +- Examples reference team scenarios + +**Recommendation:** + +- Add note: "Solo? Use @me or your username. Owner field helps AIs understand responsibility." +- Show solo developer example + +### 🟡 No guidance on evolving/refactoring specs + +**Problem:** Requirements change. How do you handle? + +**Questions:** + +- Can I change a task after starting? +- What if I split a module? +- How to handle scope creep? + +**Recommendation:** + +- Add "Living Documents" guide: + - When to update vs create new task + - How to handle discovered work + - Refactoring specs (splitting modules, etc.) + +### 🟢 No migration guide + +**Problem:** Projects mid-flight can't easily adopt APS. + +**Recommendation:** + +- "Adopting APS Mid-Project" guide: + - Start with Index capturing current state + - Add modules for active work areas only + - Gradually expand coverage + +--- + +## 9. Template-Specific Issues + +### 🟢 steps.template.md: Checkpoint examples needed + +**Problem:** "Observable checkpoint" is abstract. + +**Good checkpoint:** "Migration file exists with users table schema" +**Bad checkpoint:** "Database setup complete" + +**Recommendation:** + +- Add checkpoint guidance to template: + +```markdown + +``` + +### 🟢 index.template.md: System Map often empty + +**Problem:** Mermaid graph placeholder but many projects won't need this. + +**Recommendation:** + +- Mark as optional +- Show alternative: bullet list of module relationships + +--- + +## 10. Content & Clarity Issues + +### 🟢 "Boundary Rules" section is unclear + +**Problem:** leaf.template.md:34-37 has "Boundary Rules" but unclear vs "Out of Scope" + +**Example shows:** "AUTH must not depend on SESSION" + +**This is:** An architectural constraint, not a scope boundary. + +**Recommendation:** + +- Rename to "Architectural Constraints" or "Module Rules" +- Add guidance: "Use for dependency rules, layering, coupling constraints" + +### 🟢 Confidence field lacks guidance + +**Problem:** Tasks have "Confidence: medium" but no definition of low/medium/high. + +**Recommendation:** + +- Add to template comments: + +```markdown + +``` + +--- + +## Positive Findings + +Worth preserving and emphasizing: + +1. **Portability is genuinely valuable** - Markdown specs work everywhere +2. **Examples are excellent** - user-auth shows realistic usage +3. **Separation of planning and execution** - Conceptually sound +4. **Checkpoint-based steps** - Better than time/commit based (per ADR-001) +5. **Tool-agnostic AI prompts** - Smart approach to AI integration +6. **Principle-driven** - Four principles are clear and memorable + +--- + +## Priority Recommendations + +### Quick Wins (1-2 days) + +1. Create `quickstart.template.md` with minimal fields +2. Add "hello world" single-file example to README +3. Mark optional fields in templates with *(optional)* +4. Add checkpoint and confidence guidance to templates +5. Fix terminology: SCOPE → MODULE-ID in examples + +### High Impact (1 week) + +1. Write "Development Workflow" guide with concrete examples +2. Reorganize getting-started.md: decision tree first, details later +3. Create "Using AI Prompts" guide with tool-specific examples +4. Add "Ready Checklist" to module templates +5. Unify folder structure between docs and examples + +### Strategic (2-4 weeks) + +1. Build basic `aps validate` CLI tool +2. Create video walkthrough / interactive tutorial +3. Add JSON Schema for IDE support +4. Write "Solo Developer" and "Mid-Project Adoption" guides +5. Consider renaming "Leaf" to "Module" throughout + +--- + +## Conclusion + +APS has strong conceptual foundations and solves a real problem (planning portability). However, current usability barriers may limit adoption: + +- **Too much upfront investment** - Users need hours to understand before first use +- **Terminology creates confusion** - "Leaf", "SCOPE", "executable" aren't intuitive +- **Missing workflow integration** - Unclear how APS fits into daily development +- **Template complexity** - Heavy templates for simple needs + +**Core recommendation:** Embrace progressive disclosure. Give users a 5-minute path to value, then layer in sophistication. The comprehensive approach is great for power users but needs a gentle on-ramp. + +**Biggest opportunity:** The "hello world" example could become APS's best marketing tool - show don't tell. diff --git a/scaffold/agents/build.sh b/scaffold/agents/build.sh index 3f8d20f..d681ea7 100755 --- a/scaffold/agents/build.sh +++ b/scaffold/agents/build.sh @@ -103,9 +103,9 @@ generate_opencode() { } generate_opencode "aps-planner" "$PLANNER_DESC" \ - "anthropic/claude-opus-4-20250514" 50 "$CORE_DIR/planner-core.md" + "anthropic/claude-opus-4-6" 50 "$CORE_DIR/planner-core.md" generate_opencode "aps-librarian" "$LIBRARIAN_DESC" \ - "anthropic/claude-sonnet-4-20250514" 30 "$CORE_DIR/librarian-core.md" + "anthropic/claude-sonnet-4-6" 30 "$CORE_DIR/librarian-core.md" # --- Codex (.codex/agents/) --- CX_DIR="$SCRIPT_DIR/codex" @@ -149,11 +149,11 @@ cat > "$CX_DIR/codex-config-snippet.toml" << 'SNIPPET' # /agent spawn aps-librarian [agents.aps-planner] -model = "o4-mini" +model = "o4-mini" # OpenAI model — Codex runs on OpenAI infrastructure config_file = ".codex/agents/aps-planner.toml" [agents.aps-librarian] -model = "o4-mini" +model = "o4-mini" # OpenAI model — Codex runs on OpenAI infrastructure config_file = ".codex/agents/aps-librarian.toml" SNIPPET info "wrote $CX_DIR/codex-config-snippet.toml" diff --git a/scaffold/agents/codex/codex-config-snippet.toml b/scaffold/agents/codex/codex-config-snippet.toml index c486957..1abfcec 100644 --- a/scaffold/agents/codex/codex-config-snippet.toml +++ b/scaffold/agents/codex/codex-config-snippet.toml @@ -8,9 +8,9 @@ # /agent spawn aps-librarian [agents.aps-planner] -model = "o4-mini" +model = "o4-mini" # OpenAI model — Codex runs on OpenAI infrastructure config_file = ".codex/agents/aps-planner.toml" [agents.aps-librarian] -model = "o4-mini" +model = "o4-mini" # OpenAI model — Codex runs on OpenAI infrastructure config_file = ".codex/agents/aps-librarian.toml" diff --git a/scaffold/agents/opencode/aps-librarian.md b/scaffold/agents/opencode/aps-librarian.md index 873d2a4..3d12dbf 100644 --- a/scaffold/agents/opencode/aps-librarian.md +++ b/scaffold/agents/opencode/aps-librarian.md @@ -1,7 +1,7 @@ --- description: Repository organizing, cleanup, documentation filing, archiving stale specs, detecting orphaned files, cross-reference maintenance, and general repo hygiene mode: subagent -model: anthropic/claude-sonnet-4-20250514 +model: anthropic/claude-sonnet-4-6 steps: 30 tools: read: true diff --git a/scaffold/agents/opencode/aps-planner.md b/scaffold/agents/opencode/aps-planner.md index 4fe3f06..3125b72 100644 --- a/scaffold/agents/opencode/aps-planner.md +++ b/scaffold/agents/opencode/aps-planner.md @@ -1,7 +1,7 @@ --- description: Create, manage, execute, and review plans following the Anvil Plan Spec (APS) format, including initializing projects, modules, work items, action plans, validation, status tracking, and wave-based parallel execution mode: subagent -model: anthropic/claude-opus-4-20250514 +model: anthropic/claude-opus-4-6 steps: 50 tools: read: true diff --git a/scaffold/aps-planning/SKILL.md b/scaffold/aps-planning/SKILL.md index dc98d03..2afad73 100644 --- a/scaffold/aps-planning/SKILL.md +++ b/scaffold/aps-planning/SKILL.md @@ -55,11 +55,18 @@ Before planning, understand what exists: ``` 1. Check: Does plans/ directory exist? -2. Check: Does plans/index.aps.md exist? -3. Check: Are there module files in plans/modules/? -4. Check: Are there design docs in designs/? -5. Read plans/aps-rules.md if present (agent guidance) -6. Identify: Is this new work or continuing existing work? +2. If plans/ does not exist → run: aps init + (This bootstraps the APS structure. If aps is not on PATH, check bin/aps in the anvil-plan-spec repo or run: curl -fsSL https://raw.githubusercontent.com/EddaCraft/anvil-plan-spec/main/install.sh | sh) + After init completes, continue to step 3. +3. Check: Does plans/.aps-version exist? + If it exists, read the version. Current APS version is 0.2.0. + If the version in .aps-version is lower than 0.2.0 → run: aps update + After update completes, continue to step 4. +4. Check: Does plans/index.aps.md exist? +5. Check: Are there module files in plans/modules/? +6. Check: Are there design docs in designs/? +7. Read plans/aps-rules.md if present (agent guidance) +8. Identify: Is this new work or continuing existing work? ``` ### 2. Plan (pick the right template) diff --git a/scaffold/init.sh b/scaffold/init.sh index e0a04fd..f410340 100755 --- a/scaffold/init.sh +++ b/scaffold/init.sh @@ -246,16 +246,7 @@ if [[ "$UPDATE_MODE" == true ]]; then info "plans/ + designs/ (templates, rules)" - # Skill and commands - install_skill "$TARGET" - - # Hooks: prompt only if not already configured - if ! has_aps_hooks "$TARGET"; then - prompt_hooks "$TARGET" - else - echo "" - info "Hook configuration was NOT modified (run install-hooks.sh to update)." - fi + info "Skill not updated. Run: aps setup claude-code (or codex/opencode) to install/update the planning skill." echo "" info "Your specs (index.aps.md, modules/*.aps.md) were NOT modified." @@ -291,9 +282,6 @@ else info "plans/ + designs/ (templates, rules, index)" - # Skill and commands - install_skill "$TARGET" - echo "" echo " bin/" echo " └── aps <- CLI (lint, init, update)" @@ -319,20 +307,15 @@ else echo " ├── hooks.md <- Hook configuration guide" echo " └── scripts/ <- Hook install + session scripts" echo "" - echo " .claude/commands/" - echo " ├── plan.md <- /plan command" - echo " └── plan-status.md <- /plan-status command" - - # Hooks - prompt_hooks "$TARGET" - - # PATH setup - setup_path "$TARGET" + echo " Harness skill not installed." + echo " Run: aps setup claude-code (Claude Code)" + echo " aps setup codex (Codex)" + echo " aps setup opencode (OpenCode)" echo "" step "Next steps" echo " 1. Edit plans/index.aps.md to define your plan" echo " 2. Copy templates to create modules (remove leading dot)" - echo " 3. Use /plan in Claude Code to start planning" + echo " 3. Run: aps setup to install the planning skill for your tool" echo "" fi diff --git a/scaffold/plans/aps-rules-v2.md b/scaffold/plans/aps-rules-v2.md new file mode 100644 index 0000000..bf2a8e8 --- /dev/null +++ b/scaffold/plans/aps-rules-v2.md @@ -0,0 +1,312 @@ +# APS Rules for AI Agents + +> This file guides AI agents working with APS specs in this repository. +> Keep it in `plans/` so agents discover it when exploring the planning directory. +> **APS-managed** — safe to update via `aps update`. Project-specific context +> lives in `plans/project-context.md` (user-owned, never overwritten). + +## Core Principle + +**Specs describe intent. Tasks authorise execution. Steps are checkpoints, not tutorials.** + +## Hierarchy + +| Layer | Purpose | You Write | You DON'T Write | +|-------|---------|-----------|-----------------| +| Index | Plan overview | Modules, milestones, risks | Implementation details | +| Module | Bounded work area | Interfaces, tasks, boundaries | Code snippets | +| Task | Execution authority | Outcome, validation command | How to implement | +| Step | Checkpoint | Observable state | Implementation steps | + +## Steps: The Lean Rule + +Steps translate task intent into **observable checkpoints**. They are NOT implementation guides. + +### Format + +```markdown +### 1. [Action verb] [target] + +- **Checkpoint:** [Observable state — max 12 words] +- **Validate:** `[command]` (optional) +``` + +### What Goes WHERE + +| Write in Step | Write NOWHERE (emerges from patterns) | +|---------------|---------------------------------------| +| "Auth middleware exists" | Which library to use | +| "Tests pass" | Test implementation details | +| "Migration applied" | SQL schema definition | +| "Function handles errors" | Try/catch structure | + +### Anti-Patterns (NEVER do this) + +```markdown +# BAD: Implementation tutorial disguised as step +### 1. Create authentication middleware + +- **Checkpoint:** Middleware created in src/middleware/auth.ts that: + - Extracts JWT from Authorization header + - Validates token using jsonwebtoken library + - Decodes payload and extracts user ID + - Attaches user object to request context + - Returns 401 if token invalid or expired +- **Validate:** `npm test -- auth.middleware.test.ts` +``` + +```markdown +# GOOD: Observable checkpoint only +### 1. Create authentication middleware + +- **Checkpoint:** Auth middleware validates requests, attaches user to context +- **Validate:** `npm test -- auth.middleware.test.ts` +``` + +### Why Lean Steps? + +1. **Implementation emerges** from existing patterns + agent judgment +2. **Specs don't rot** — checkpoints stay valid even when code changes +3. **Agents stay autonomous** — they figure out HOW, you verify WHAT +4. **Review stays fast** — humans scan checkpoints, not implementation plans + +## Task Rules + +Tasks are **execution authority** — permission to make changes. + +### Required Fields + +- **Intent:** One sentence — what outcome this achieves +- **Expected Outcome:** Testable/observable result +- **Validation:** Command to verify completion + +### Optional Fields + +- **Scope/Non-scope:** What will and won't change +- **Dependencies:** Other task IDs that must complete first +- **Confidence:** low/medium/high +- **Files:** Best-effort list (not exhaustive) + +### Task Anti-Patterns + +| Don't | Do | +|-------|-----| +| "Implement JWT auth using jsonwebtoken" | "Add token-based authentication" | +| "Create UserService class with methods..." | "User operations are encapsulated" | +| "Add try/catch blocks to all handlers" | "API errors return consistent format" | + +## Action Plans: Waves and Parallel Execution + +Action plans can optionally group actions into **waves** for parallel execution. +Actions in the same wave are independent — they can run concurrently. Each wave +completes before the next begins. + +### Wave Table Format + +```markdown +## Waves + +| Wave | Actions | Gate | +|------|---------|------| +| 1 | 1, 2 | Both checkpoints pass | +| 2 | 3 | Checkpoint passes | +``` + +### Action-Level Fields + +Actions support optional execution metadata: + +- **Wave** N — which wave this action belongs to +- **Depends on** 1, 2 — action numbers that must complete first +- **Agent** type — agent type for dispatch (e.g., general-purpose, tdd-coach) + +### When to Use Waves + +| Use Waves | Stay Sequential | +|-----------|-----------------| +| 3+ actions with independent work | Each action depends on the previous | +| Multi-agent dispatch needed | Single-agent linear execution | +| Work item has natural parallel boundaries | Actions share mutable state | + +### When NOT to Use Waves + +- Simple work items (< 4 actions) +- All actions modify the same files +- Actions are inherently sequential (schema -> migration -> seed) + +## Naming Conventions + +### Module Files + +Name module files with a numeric prefix based on dependency order: + +```text +modules/ +├── 01-core.aps.md # Foundation, no dependencies +├── 02-auth.aps.md # Depends on core +├── 03-payments.aps.md # Depends on auth +└── 04-ui.aps.md # Depends on all above +``` + +- Use zero-padded numbers (`01-`, `02-`, not `1-`, `2-`) +- Order matches dependency flow (foundational -> dependent) +- Order should reflect the Modules table in `index.aps.md` + +### Task IDs + +Tasks use the module's ID prefix: `AUTH-001`, `AUTH-002`, `CORE-001`, etc. + +## Creating APS Documents + +### When Asked to Plan + +1. Read existing `plans/index.aps.md` if present +2. Identify which template fits (index, module, simple) +3. Fill sections with **intent**, not implementation +4. Mark assumptions explicitly +5. Leave tasks empty until module is Ready + +### When Asked to Execute + +1. Find the task in the relevant `.aps.md` file +2. Check task has **Ready** status +3. Create steps file in `plans/execution/` if complex +4. Execute one step at a time, validate checkpoint +5. Mark task complete when validation passes + +## File Locations + +```text +plans/ +├── aps-rules.md # This file (APS-managed agent guidance) +├── project-context.md # Project-specific context (user-owned) +├── index.aps.md # Root plan +├── issues.md # Development-time discoveries +├── modules/ # Module specs (numbered by dependency order) +│ ├── 01-core.aps.md +│ └── 02-auth.aps.md +├── execution/ # Step files +│ ├── [TASK-ID].steps.md # Per-task (complex projects) +│ └── [MODULE].steps.md # Per-module (simple projects) +├── decisions/ # ADRs (optional) +│ └── [NNN]-[title].md +└── designs/ # Technical designs (optional) + └── YYYY-MM-DD-slug.design.md +``` + +## Design Documents + +Design docs live in `plans/designs/`. They capture architectural thinking +**before** committing to modules and work items. + +### When to Create + +- Multi-module work with non-obvious architecture +- Multiple viable approaches that need comparison +- Work that needs review before defining work items +- Cross-cutting concerns that span several modules + +### When to Skip + +- Straightforward single-module features +- Bug fixes or small enhancements +- Work where the approach is already well established + +### Naming + +`plans/designs/YYYY-MM-DD-slug.design.md` — date-prefixed, descriptive slug. + +### Linking + +Reference designs from the Index or Module metadata: + +```markdown +## Designs +- [Auth Architecture](designs/2025-01-05-auth-architecture.design.md) +``` + +### Accept-Then-Normalise + +If a design doc already exists in free-form (created by another agent or human), +**accept it**. Don't reject it for missing sections. Instead: + +1. Add the minimum fields: `## Problem`, `## Design`, and the Status metadata table +2. Don't rewrite the author's content — append missing sections or infer from + existing content +3. This normalisation can happen in the background, after the main work + +## Monorepo Conventions + +For repositories with multiple packages/apps. See `docs/monorepo.md` for full guidance. + +### Package Tagging + +Every module declares `Packages: pkg1, pkg2` in metadata. Work items inherit or narrow the package scope. + +### Session Start Ritual + +Before touching code: + +1. **Orient** — Read `plans/index.aps.md` "What's Next" section, then relevant module(s) +2. **Confirm authority** — Work item exists, status = Ready, packages are clear +3. **Declare intent** — State: "Executing AUTH-002 (core, api): [description]" + +If no Ready work item exists: + +- Create Draft work item first +- Ask human to mark Ready before proceeding +- OR if trivial fix, note in session end summary + +### Session End Ritual + +After completing work: + +1. **Update status** — Mark work items: `In Progress`, `Complete: YYYY-MM-DD`, or `Blocked: [reason]` +2. **Capture discovered work** — Add as Draft items with package tags +3. **Log discoveries** — Add issues (ISS-NNN) or questions (Q-NNN) to `plans/issues.md` +4. **Update "What's Next"** — Remove completed, add new Ready items, re-sequence if needed +5. **Session summary** — Brief note: what completed, what discovered, what's next + +**Key principle:** The next agent should pick up exactly where you left off without archaeology. + +## Issues & Questions Tracker + +Use `plans/issues.md` to log development-time discoveries: + +- **Issues (ISS-NNN)** — Bugs, limitations, edge cases noticed during development +- **Questions (Q-NNN)** — Unknowns that need answers, deferred decisions + +### When to Log + +| Log as Issue | Log as Question | +|--------------|-----------------| +| "API rate-limits at 100 req/min" | "Should retry logic live in client or transport?" | +| "Login fails intermittently on Safari" | "What's the session expiry policy?" | +| "Edge case: empty array not handled" | "Do we need to support IE11?" | + +### Referencing + +From work items, notes, or commits: + +- `See ISS-001` or `Related: ISS-001, Q-002` +- In commits: `Addresses ISS-001` + +### Not a Bug Tracker + +This is for **planning-level visibility**, not routine bugs. Use your project's bug tracker for: + +- User-reported bugs +- Production incidents +- Detailed reproduction steps + +## Quick Reference + +| If agent is... | Check for... | +|----------------|--------------| +| Writing a design | Problem + Design sections present? No implementation prescriptions? | +| Writing steps | Max 12 words per checkpoint? No implementation detail? | +| Writing tasks | Outcome-focused? Has validation command? | +| Planning module | Boundaries clear? No premature tasks? | +| Executing | Task status is Ready? Prerequisites met? | +| In monorepo | Packages tagged? "What's Next" updated? | +| Found issue/question | Logged in issues.md with proper ID? | diff --git a/scaffold/plans/project-context.md b/scaffold/plans/project-context.md new file mode 100644 index 0000000..a418e54 --- /dev/null +++ b/scaffold/plans/project-context.md @@ -0,0 +1,24 @@ +# Project Context + +> User-owned file. APS will never overwrite this. Populate it manually or let +> your AI agent fill it in on first run. + +## Overview + + + +## Team + + + +## Tech Stack + + + +## Conventions + + + +## Active Decisions + +