@williambeto/ai-workflow 1.19.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -837
- package/PUBLISH_MANIFEST.json +34 -0
- package/README.md +70 -149
- package/{packages/ai-workflow/bin → bin}/ai-workflow.js +0 -0
- package/dist-assets/AGENTS.md +27 -0
- package/dist-assets/agents/astra.md +63 -0
- package/dist-assets/agents/atlas.md +169 -0
- package/dist-assets/agents/nexus.md +42 -0
- package/dist-assets/agents/orion.md +44 -0
- package/dist-assets/agents/phoenix.md +42 -0
- package/dist-assets/agents/sage.md +54 -0
- package/dist-assets/commands/README.md +14 -0
- package/dist-assets/commands/atlas.md +12 -0
- package/dist-assets/commands/audit.md +10 -0
- package/dist-assets/commands/deploy.md +12 -0
- package/dist-assets/commands/discover.md +10 -0
- package/dist-assets/commands/implement.md +28 -0
- package/dist-assets/commands/optimize-tokens.md +10 -0
- package/dist-assets/commands/plan.md +10 -0
- package/dist-assets/commands/release.md +12 -0
- package/dist-assets/commands/run.md +26 -0
- package/dist-assets/commands/spec-create.md +10 -0
- package/dist-assets/commands/spec-implement.md +10 -0
- package/dist-assets/commands/spec-review.md +10 -0
- package/dist-assets/commands/update-memory.md +10 -0
- package/dist-assets/commands/validate.md +12 -0
- package/dist-assets/docs/INDEX.md +21 -0
- package/dist-assets/docs/QUICKSTART.md +23 -0
- package/dist-assets/docs/adr/ADR-0000.md +19 -0
- package/dist-assets/docs/adr/ADR-0001.md +45 -0
- package/dist-assets/docs/adr/ADR-0002.md +62 -0
- package/dist-assets/docs/adr/ADR-0003.md +60 -0
- package/dist-assets/docs/adr/ADR-0004.md +71 -0
- package/dist-assets/docs/adr/ADR-0005.md +22 -0
- package/dist-assets/docs/adr/ADR-0006.md +82 -0
- package/dist-assets/docs/adr/ADR-0007.md +78 -0
- package/dist-assets/docs/api-engine-reference.md +7 -0
- package/{docs → dist-assets/docs}/architecture-policy.md +1 -1
- package/dist-assets/docs/cli-reference.md +27 -0
- package/dist-assets/docs/compatibility/provider-usage.md +38 -0
- package/dist-assets/docs/compatibility/runtime-matrix.md +30 -0
- package/dist-assets/docs/consumer-onboarding.md +17 -0
- package/dist-assets/docs/contributing-guide.md +11 -0
- package/{docs → dist-assets/docs}/design-patterns-policy.md +2 -2
- package/dist-assets/docs/full-documentation.md +113 -0
- package/{docs → dist-assets/docs}/npm-consumer-quickstart.md +18 -46
- package/dist-assets/docs/opencode-readme.md +8 -0
- package/dist-assets/docs/policies/01-BRANCH_GATE.md +63 -0
- package/dist-assets/docs/policies/02-SDD_METHODOLOGY.md +95 -0
- package/dist-assets/docs/policies/03-QUALITY_GATE.md +22 -0
- package/dist-assets/docs/policies/05-AGENT_CONTRACT.md +7 -0
- package/dist-assets/docs/policies/06-FINAL_EVIDENCE_CONTRACT.md +31 -0
- package/dist-assets/docs/policies/07-RELEASE_GATE.md +47 -0
- package/dist-assets/docs/policies/08-PRODUCT_TRUTHFULNESS_AND_PROJECT_DOCS.md +18 -0
- package/dist-assets/docs/policies/09-SPEC_VISIBILITY_AND_PUBLICATION.md +28 -0
- package/dist-assets/docs/policies/10-BEHAVIORAL_CONTRACT_HARDENING.md +9 -0
- package/dist-assets/docs/policies/11-EXECUTABLE_DELEGATION_AND_TRUTHFULNESS.md +7 -0
- package/dist-assets/docs/policies/ORCHESTRATION_PROTOCOL.md +15 -0
- package/dist-assets/docs/policies/PROCEDURE_DELIVERY_ARTIFACTS.md +21 -0
- package/dist-assets/docs/policies/PROCEDURE_DOCUMENTATION_CHECKLIST.md +24 -0
- package/dist-assets/docs/policies/PROCEDURE_UI_CHECKLIST.md +54 -0
- package/dist-assets/docs/profiles/README.md +19 -0
- package/dist-assets/docs/profiles/backend-api.md +5 -0
- package/dist-assets/docs/profiles/documentation.md +3 -0
- package/dist-assets/docs/profiles/frontend-product.md +19 -0
- package/dist-assets/docs/profiles/frontend-utility.md +19 -0
- package/dist-assets/docs/profiles/refactor.md +3 -0
- package/dist-assets/docs/profiles/security-review.md +3 -0
- package/dist-assets/docs/references/frontend-quality/landing-page-quality-checklist.md +11 -0
- package/dist-assets/docs/references/frontend-quality/product-copy-truthfulness.md +7 -0
- package/dist-assets/docs/references/frontend-quality/quality-failure-examples.md +20 -0
- package/dist-assets/docs/references/frontend-quality/visual-composition-patterns.md +10 -0
- package/dist-assets/docs/specs/runtime-operational-contract.md +39 -0
- package/dist-assets/docs/troubleshooting-guide.md +21 -0
- package/dist-assets/examples/README.md +10 -0
- package/dist-assets/examples/autopilot-cycle/00-CONTEXT.md +3 -0
- package/dist-assets/examples/autopilot-cycle/01-requirement.md +16 -0
- package/dist-assets/examples/autopilot-cycle/02-gate-a-check.md +23 -0
- package/dist-assets/examples/autopilot-cycle/03-orion-planning.md +20 -0
- package/dist-assets/examples/autopilot-cycle/04-astra-implementation.md +17 -0
- package/dist-assets/examples/autopilot-cycle/05-sage-validation.md +15 -0
- package/dist-assets/examples/autopilot-cycle/06-phoenix-healing.md +12 -0
- package/dist-assets/examples/autopilot-cycle/07-orchestration-report.md +18 -0
- package/dist-assets/examples/backend-api/00-CONTEXT.md +12 -0
- package/dist-assets/examples/backend-api/01-requirement.md +19 -0
- package/dist-assets/examples/backend-api/02-functional-spec.md +20 -0
- package/dist-assets/examples/backend-api/03-technical-plan.md +15 -0
- package/dist-assets/examples/backend-api/04-pr-breakdown.md +10 -0
- package/dist-assets/examples/backend-api/05-execution-handoff.md +13 -0
- package/dist-assets/examples/backend-api/06-validation-report.md +11 -0
- package/dist-assets/examples/backend-api/07-orchestration-report.md +7 -0
- package/dist-assets/examples/blocked-scenarios/00-CONTEXT.md +9 -0
- package/dist-assets/examples/blocked-scenarios/01-branch-gate-block.md +12 -0
- package/dist-assets/examples/blocked-scenarios/02-quality-gate-block.md +13 -0
- package/dist-assets/examples/blocked-scenarios/03-scope-creep-block.md +13 -0
- package/dist-assets/examples/blocked-scenarios/04-unblock-resolution.md +9 -0
- package/dist-assets/examples/blocked-scenarios/05-orchestration-decision-log.md +11 -0
- package/dist-assets/examples/bugfix-critical/00-CONTEXT.md +12 -0
- package/dist-assets/examples/bugfix-critical/01-bug-report.md +11 -0
- package/dist-assets/examples/bugfix-critical/02-diagnosis-hypothesis.md +11 -0
- package/dist-assets/examples/bugfix-critical/03-technical-plan.md +12 -0
- package/dist-assets/examples/bugfix-critical/04-implementation-handoff.md +8 -0
- package/dist-assets/examples/bugfix-critical/05-validation-report.md +10 -0
- package/dist-assets/examples/bugfix-critical/06-orchestration-report.md +7 -0
- package/dist-assets/examples/cli-package/00-CONTEXT.md +9 -0
- package/dist-assets/examples/cli-package/01-requirement.md +14 -0
- package/dist-assets/examples/cli-package/02-technical-spec.md +16 -0
- package/dist-assets/examples/cli-package/03-technical-plan.md +12 -0
- package/dist-assets/examples/cli-package/04-pr-breakdown.md +9 -0
- package/dist-assets/examples/cli-package/05-release-report.md +15 -0
- package/dist-assets/examples/docs-only-repo/01-requirement.md +31 -0
- package/dist-assets/examples/docs-only-repo/02-functional-spec.md +25 -0
- package/dist-assets/examples/docs-only-repo/03-technical-plan.md +21 -0
- package/dist-assets/examples/docs-only-repo/04-pr-breakdown.md +13 -0
- package/dist-assets/examples/docs-only-repo/05-execution-handoff.md +17 -0
- package/dist-assets/examples/docs-only-repo/06-validation-report.md +16 -0
- package/dist-assets/examples/docs-only-repo/README.md +26 -0
- package/dist-assets/examples/full-stack-checkout/00-CONTEXT.md +9 -0
- package/dist-assets/examples/full-stack-checkout/01-requirement.md +12 -0
- package/dist-assets/examples/full-stack-checkout/02-functional-spec.md +15 -0
- package/dist-assets/examples/full-stack-checkout/03-technical-plan.md +15 -0
- package/dist-assets/examples/full-stack-checkout/04-pr-breakdown.md +8 -0
- package/dist-assets/examples/full-stack-checkout/05-execution-handoff.md +14 -0
- package/dist-assets/examples/full-stack-checkout/06-validation-report.md +12 -0
- package/dist-assets/examples/healing-cycle/00-CONTEXT.md +15 -0
- package/dist-assets/examples/healing-cycle/01-broken-implementation.md +10 -0
- package/dist-assets/examples/healing-cycle/02-sage-fails.md +14 -0
- package/dist-assets/examples/healing-cycle/03-phoenix-diagnosis.md +17 -0
- package/dist-assets/examples/healing-cycle/04-phoenix-fix.md +18 -0
- package/dist-assets/examples/healing-cycle/05-sage-revalidation.md +12 -0
- package/dist-assets/examples/healing-cycle/06-orchestration-log.md +14 -0
- package/dist-assets/examples/infra-deploy/00-CONTEXT.md +9 -0
- package/dist-assets/examples/infra-deploy/01-operational-goal.md +12 -0
- package/dist-assets/examples/infra-deploy/02-architecture-specs.md +15 -0
- package/dist-assets/examples/infra-deploy/03-implementation-plan.md +14 -0
- package/dist-assets/examples/infra-deploy/04-step-breakdown.md +9 -0
- package/dist-assets/examples/infra-deploy/05-execution-handoff.md +13 -0
- package/dist-assets/examples/infra-deploy/06-operational-report.md +11 -0
- package/dist-assets/examples/multi-pr-release/00-CONTEXT.md +9 -0
- package/dist-assets/examples/multi-pr-release/01-requirement.md +13 -0
- package/dist-assets/examples/multi-pr-release/02-strategic-plan.md +13 -0
- package/dist-assets/examples/multi-pr-release/03-pr-breakdown.md +14 -0
- package/dist-assets/examples/multi-pr-release/04-release-plan.md +12 -0
- package/dist-assets/examples/multi-pr-release/05-orchestration-report.md +7 -0
- package/dist-assets/examples/nuxt-dashboard/01-requirement.md +81 -0
- package/dist-assets/examples/nuxt-dashboard/02-functional-spec.md +88 -0
- package/dist-assets/examples/nuxt-dashboard/03-technical-plan.md +76 -0
- package/dist-assets/examples/nuxt-dashboard/04-pr-breakdown.md +219 -0
- package/dist-assets/examples/nuxt-dashboard/05-execution-handoff.md +88 -0
- package/dist-assets/examples/nuxt-dashboard/06-validation-report.md +56 -0
- package/dist-assets/examples/nuxt-dashboard/07-orchestration-report.md +79 -0
- package/dist-assets/examples/nuxt-dashboard/README.md +52 -0
- package/dist-assets/examples/react-dashboard/01-requirement.md +84 -0
- package/dist-assets/examples/react-dashboard/02-functional-spec.md +88 -0
- package/dist-assets/examples/react-dashboard/03-technical-plan.md +76 -0
- package/dist-assets/examples/react-dashboard/04-pr-breakdown.md +218 -0
- package/dist-assets/examples/react-dashboard/05-execution-handoff.md +13 -0
- package/dist-assets/examples/react-dashboard/06-validation-report.md +12 -0
- package/dist-assets/examples/react-dashboard/07-orchestration-report.md +7 -0
- package/dist-assets/examples/react-dashboard/README.md +70 -0
- package/dist-assets/examples/refactoring-service/00-CONTEXT.md +9 -0
- package/dist-assets/examples/refactoring-service/01-debt-report.md +12 -0
- package/dist-assets/examples/refactoring-service/02-behavior-spec.md +11 -0
- package/dist-assets/examples/refactoring-service/03-technical-plan.md +13 -0
- package/dist-assets/examples/refactoring-service/04-pr-breakdown.md +9 -0
- package/dist-assets/examples/refactoring-service/05-execution-handoff.md +14 -0
- package/dist-assets/examples/refactoring-service/06-stability-report.md +12 -0
- package/dist-assets/examples/sdd-cycle/00-CONTEXT.md +12 -0
- package/dist-assets/examples/sdd-cycle/01-raw-request.md +13 -0
- package/dist-assets/examples/sdd-cycle/02-spec-creation.md +18 -0
- package/dist-assets/examples/sdd-cycle/03-spec-review.md +12 -0
- package/dist-assets/examples/sdd-cycle/04-technical-plan.md +16 -0
- package/dist-assets/examples/sdd-cycle/05-pr-breakdown.md +9 -0
- package/dist-assets/examples/sdd-cycle/06-spec-implement.md +13 -0
- package/dist-assets/examples/sdd-cycle/07-validation-against-spec.md +13 -0
- package/dist-assets/examples/wordpress-theme/01-requirement.md +29 -0
- package/dist-assets/examples/wordpress-theme/02-functional-spec.md +22 -0
- package/dist-assets/examples/wordpress-theme/03-technical-plan.md +22 -0
- package/dist-assets/examples/wordpress-theme/04-pr-breakdown.md +14 -0
- package/dist-assets/examples/wordpress-theme/05-execution-handoff.md +17 -0
- package/dist-assets/examples/wordpress-theme/06-validation-report.md +16 -0
- package/dist-assets/examples/wordpress-theme/README.md +32 -0
- package/{harness → dist-assets/harness}/handoffs/HANDOFF.template.md +2 -2
- package/{harness → dist-assets/harness}/workflows/agent-evaluation-checklist.md +5 -5
- package/{harness → dist-assets/harness}/workflows/implement-review-validate.md +24 -0
- package/{harness → dist-assets/harness}/workflows/multi-agent-handoff.md +4 -4
- package/{harness → dist-assets/harness}/workflows/planner-executor-workflow.md +5 -5
- package/{harness → dist-assets/harness}/workflows/requirement-to-pr.md +1 -1
- package/dist-assets/runbooks/agent-delegation-workflow.md +50 -0
- package/dist-assets/runbooks/apply-starter-to-real-project.md +45 -0
- package/dist-assets/runbooks/commands-cheatsheet.md +44 -0
- package/dist-assets/runbooks/how-to-use-skills.md +44 -0
- package/dist-assets/runbooks/private-spec-publication-safety.md +35 -0
- package/{runbooks → dist-assets/runbooks}/spec-driven-development.md +3 -6
- package/dist-assets/runbooks/tutorial-walkthroughs.md +23 -0
- package/dist-assets/runbooks/use-linear-for-operational-planning.md +45 -0
- package/dist-assets/runbooks/use-napkin-project-memory.md +33 -0
- package/dist-assets/skills/architecture/SKILL.md +166 -0
- package/dist-assets/skills/backend-development/SKILL.md +166 -0
- package/dist-assets/skills/deployment/SKILL.md +166 -0
- package/dist-assets/skills/design-principles/SKILL.md +166 -0
- package/dist-assets/skills/documentation/SKILL.md +171 -0
- package/dist-assets/skills/frontend-development/SKILL.md +225 -0
- package/dist-assets/skills/full-stack-development/SKILL.md +166 -0
- package/dist-assets/skills/optimize-tokens/SKILL.md +166 -0
- package/dist-assets/skills/pr-workflow/SKILL.md +166 -0
- package/dist-assets/skills/product-discovery/SKILL.md +166 -0
- package/dist-assets/skills/product-planning/SKILL.md +166 -0
- package/dist-assets/skills/project-memory/SKILL.md +166 -0
- package/dist-assets/skills/prompt-engineer/SKILL.md +166 -0
- package/dist-assets/skills/qa-workflow/SKILL.md +186 -0
- package/dist-assets/skills/refactoring/SKILL.md +166 -0
- package/dist-assets/skills/release-workflow/SKILL.md +166 -0
- package/dist-assets/skills/spec-driven-development/SKILL.md +166 -0
- package/dist-assets/skills/technical-leadership/SKILL.md +166 -0
- package/dist-assets/skills/ui-ux-design/SKILL.md +202 -0
- package/dist-assets/templates/.geminiignore.template +8 -0
- package/dist-assets/templates/CLAUDE.md.template +20 -0
- package/dist-assets/templates/CODEX.md.template +20 -0
- package/dist-assets/templates/GEMINI.md.template +20 -0
- package/dist-assets/templates/HANDOFF.template.md +45 -0
- package/dist-assets/templates/SPEC.template.md +38 -0
- package/dist-assets/templates/change-proposal.template.md +14 -0
- package/dist-assets/templates/owner-evidence/astra-implementation.json +10 -0
- package/dist-assets/templates/owner-evidence/phoenix-remediation.json +8 -0
- package/dist-assets/templates/owner-evidence/sage-revalidation.json +8 -0
- package/dist-assets/templates/owner-evidence/sage-validation.json +8 -0
- package/dist-assets/templates/specs/deep.md +48 -0
- package/dist-assets/templates/specs/standard.md +38 -0
- package/dist-assets/templates/specs/tiny.md +19 -0
- package/package.json +42 -47
- package/src/adapters/index.js +3 -0
- package/src/adapters/platforms/claude.js +126 -0
- package/src/adapters/platforms/codex.js +100 -0
- package/src/adapters/platforms/gemini.js +232 -0
- package/src/cli.js +96 -0
- package/src/commands/collect-evidence.js +61 -0
- package/src/commands/doctor.js +186 -0
- package/{packages/ai-workflow/src → src}/commands/init.js +119 -20
- package/src/commands/run.js +111 -0
- package/src/core/completion-contract.js +35 -0
- package/src/core/gates/branch-gate.js +113 -0
- package/src/core/handoff/handoff-engine.js +78 -0
- package/src/core/healing/cli-remediation-executor.js +151 -0
- package/src/core/healing/healer-engine.js +179 -0
- package/src/core/identity.js +43 -0
- package/{packages/ai-workflow/src → src}/core/install-plan.js +3 -3
- package/src/core/opencode-merge.js +149 -0
- package/{packages/ai-workflow/src → src}/core/package-assets.js +29 -10
- package/src/core/sdd/validator.js +67 -0
- package/src/core/statuses.js +29 -0
- package/src/core/symlink-layout.js +93 -0
- package/src/core/templates.js +218 -0
- package/src/core/validation/canonical-finalization.js +43 -0
- package/src/core/validation/evidence-collector.js +109 -0
- package/src/core/validation/quality-guard.js +243 -0
- package/src/core/workflow-profiles.js +107 -0
- package/.agents/napkin.md +0 -89
- package/.agents/skills/backend-implementer/SKILL.md +0 -490
- package/.agents/skills/build-and-validate/SKILL.md +0 -442
- package/.agents/skills/deploy-engineer/SKILL.md +0 -541
- package/.agents/skills/docs-writer/SKILL.md +0 -430
- package/.agents/skills/frontend-implementer/SKILL.md +0 -488
- package/.agents/skills/interface-design/SKILL.md +0 -428
- package/.agents/skills/interface-design/references/critique.md +0 -67
- package/.agents/skills/interface-design/references/example.md +0 -86
- package/.agents/skills/interface-design/references/principles.md +0 -235
- package/.agents/skills/interface-design/references/validation.md +0 -48
- package/.agents/skills/minimal-context/SKILL.md +0 -177
- package/.agents/skills/napkin/SKILL.md +0 -84
- package/.agents/skills/opencode-agent-design/SKILL.md +0 -77
- package/.agents/skills/playwright-cli/SKILL.md +0 -62
- package/.agents/skills/pr-orchestrator/SKILL.md +0 -366
- package/.agents/skills/product-manager/SKILL.md +0 -519
- package/.agents/skills/seo-audit/SKILL.md +0 -176
- package/.agents/skills/stack-variant-creator/SKILL.md +0 -265
- package/.agents/skills/tech-lead/SKILL.md +0 -453
- package/.agents/skills/tester/SKILL.md +0 -399
- package/.agents/skills/token-economy/SKILL.md +0 -137
- package/.agents/skills/vue-nuxt/SKILL.md +0 -102
- package/.agents/skills/wordpress-engineer/SKILL.md +0 -75
- package/.codex/prompts/README.md +0 -44
- package/.codex/prompts/autopilot.md +0 -50
- package/.codex/prompts/deploy.md +0 -33
- package/.codex/prompts/execute-selected-pr.md +0 -35
- package/.codex/prompts/fix-issue.md +0 -34
- package/.codex/prompts/minimal-context-mode.md +0 -55
- package/.codex/prompts/orchestrate-next.md +0 -33
- package/.codex/prompts/plan-from-requirement.md +0 -37
- package/.codex/prompts/review-implementation.md +0 -33
- package/.codex/prompts/roadmap-audit.md +0 -22
- package/.codex/prompts/specs/create-spec-from-requirement.md +0 -26
- package/.codex/prompts/specs/review-spec.md +0 -29
- package/.codex/prompts/specs/spec-to-pr-breakdown.md +0 -23
- package/.codex/prompts/specs/spec-to-technical-plan.md +0 -28
- package/.codex/prompts/start-project.md +0 -29
- package/.codex/prompts/token-economy-mode.md +0 -48
- package/.codex/prompts/validate-work.md +0 -28
- package/checklists/change-spec-readiness-checklist.md +0 -34
- package/docs/full-documentation.md +0 -661
- package/docs/setup-codex-opencode.md +0 -313
- package/harness/README.md +0 -106
- package/opencode/README.md +0 -84
- package/opencode/agents/README.md +0 -113
- package/opencode/agents/atlas.md +0 -127
- package/opencode/agents/discovery.md +0 -61
- package/opencode/agents/fixer.md +0 -51
- package/opencode/agents/implementer.md +0 -61
- package/opencode/agents/orchestrator.md +0 -145
- package/opencode/agents/planner.md +0 -60
- package/opencode/agents/prompt-engineer.md +0 -50
- package/opencode/agents/release-manager.md +0 -50
- package/opencode/agents/reviewer.md +0 -51
- package/opencode/agents/spec-engineer.md +0 -85
- package/opencode/agents/validator.md +0 -50
- package/opencode/agents/wordpress-engineer.md +0 -49
- package/opencode/commands/README.md +0 -48
- package/opencode/commands/autopilot.md +0 -50
- package/opencode/commands/deploy.md +0 -35
- package/opencode/commands/execute.md +0 -47
- package/opencode/commands/orchestrate.md +0 -37
- package/opencode/commands/plan.md +0 -39
- package/opencode/commands/review.md +0 -33
- package/opencode/commands/roadmap-audit.md +0 -30
- package/opencode/commands/ship.md +0 -48
- package/opencode/commands/specs/create-spec-from-request.md +0 -27
- package/opencode/commands/specs/create-spec-from-requirement.md +0 -25
- package/opencode/commands/specs/review-spec.md +0 -26
- package/opencode/commands/specs/spec-to-pr-breakdown.md +0 -19
- package/opencode/commands/specs/spec-to-tasks.md +0 -26
- package/opencode/commands/specs/spec-to-technical-plan.md +0 -27
- package/opencode/commands/start.md +0 -45
- package/opencode/commands/token-economy.md +0 -29
- package/opencode/commands/validate.md +0 -33
- package/opencode.jsonc +0 -235
- package/packages/ai-workflow/README.md +0 -82
- package/packages/ai-workflow/src/cli.js +0 -70
- package/packages/ai-workflow/src/commands/codex.js +0 -37
- package/packages/ai-workflow/src/commands/doctor.js +0 -168
- package/packages/ai-workflow/src/commands/guide.js +0 -194
- package/packages/ai-workflow/src/core/opencode-merge.js +0 -172
- package/packages/ai-workflow/src/core/symlink-layout.js +0 -54
- package/packages/ai-workflow/src/core/templates.js +0 -275
- package/runbooks/agent-delegation-workflow.md +0 -111
- package/runbooks/apply-starter-to-real-project.md +0 -445
- package/runbooks/commands-cheatsheet.md +0 -71
- package/runbooks/how-to-use-skills.md +0 -713
- package/runbooks/quick-start-guide.md +0 -213
- package/runbooks/tutorial-walkthroughs.md +0 -416
- package/runbooks/use-linear-for-operational-planning.md +0 -185
- package/runbooks/use-napkin-project-memory.md +0 -77
- package/templates/AGENTS.template.md +0 -397
- package/templates/DESIGN.template.md +0 -484
- package/templates/PR-PLAN.template.md +0 -172
- package/templates/README.template.md +0 -293
- package/templates/REQUIREMENT.template.md +0 -165
- package/templates/SPEC.template.md +0 -397
- package/templates/TECH-PLAN.template.md +0 -244
- package/templates/change-proposal.template.md +0 -97
- /package/{checklists/spec-readiness-checklist.md → dist-assets/docs/policies/SPEC_READINESS.md} +0 -0
- /package/{prompts → dist-assets/prompts}/00-bootstrap-project.md +0 -0
- /package/{prompts → dist-assets/prompts}/01-create-requirement.md +0 -0
- /package/{prompts → dist-assets/prompts}/02-create-spec.md +0 -0
- /package/{prompts → dist-assets/prompts}/03-create-tech-plan.md +0 -0
- /package/{prompts → dist-assets/prompts}/04-breakdown-prs.md +0 -0
- /package/{prompts → dist-assets/prompts}/05-implement-pr.md +0 -0
- /package/{prompts → dist-assets/prompts}/06-review-and-fix.md +0 -0
- /package/{prompts → dist-assets/prompts}/07-apply-design.md +0 -0
- /package/{prompts → dist-assets/prompts}/08-validate.md +0 -0
- /package/{prompts → dist-assets/prompts}/09-deploy.md +0 -0
- /package/{prompts → dist-assets/prompts}/commands/implement.md +0 -0
- /package/{prompts → dist-assets/prompts}/commands/requirement.md +0 -0
- /package/{prompts → dist-assets/prompts}/commands/spec.md +0 -0
- /package/{prompts → dist-assets/prompts}/commands/tech-plan.md +0 -0
- /package/{prompts → dist-assets/prompts}/commands/validate.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/branch-cleanup.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/deploy-checklist.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/publication-readiness-checklist.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/publish-package-checklist.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/team-governance-pr-readiness.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/validate-starter-in-real-project.md +0 -0
- /package/{runbooks → dist-assets/runbooks}/validation-checklist.md +0 -0
- /package/{schemas → dist-assets/schemas}/README.md +0 -0
- /package/{schemas → dist-assets/schemas}/functional-spec.schema.json +0 -0
- /package/{schemas → dist-assets/schemas}/handoff.schema.json +0 -0
- /package/{schemas → dist-assets/schemas}/pr-breakdown.schema.json +0 -0
- /package/{schemas → dist-assets/schemas}/requirement.schema.json +0 -0
- /package/{schemas → dist-assets/schemas}/technical-plan.schema.json +0 -0
- /package/{schemas → dist-assets/schemas}/validation-report.schema.json +0 -0
- /package/{packages/ai-workflow/src → src}/core/backup.js +0 -0
- /package/{packages/ai-workflow/src → src}/core/filesystem.js +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { spawnSync, execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Determines which npm scripts are available in the consumer project.
|
|
7
|
+
* @param {string} cwd
|
|
8
|
+
* @returns {Promise<Record<string, string>>}
|
|
9
|
+
*/
|
|
10
|
+
async function readScripts(cwd) {
|
|
11
|
+
try {
|
|
12
|
+
const pkg = JSON.parse(await fs.readFile(path.join(cwd, "package.json"), "utf8"));
|
|
13
|
+
return pkg.scripts || {};
|
|
14
|
+
} catch {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Returns the list of files changed since the last commit.
|
|
21
|
+
* Used to detect whether remediation produced any observable change.
|
|
22
|
+
* @param {string} cwd
|
|
23
|
+
* @returns {string[]}
|
|
24
|
+
*/
|
|
25
|
+
function getChangedFiles(cwd) {
|
|
26
|
+
try {
|
|
27
|
+
const output = execSync("git status --short", { cwd, encoding: "utf8" });
|
|
28
|
+
return output
|
|
29
|
+
.split("\n")
|
|
30
|
+
.filter(Boolean)
|
|
31
|
+
.map((line) => line.slice(3).trim())
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Maps an affectedCheck source string to likely npm script names to re-run.
|
|
40
|
+
* e.g. "check:branchSafety" → [] (no command can fix a branch issue)
|
|
41
|
+
* "evidence" with failed test → ["test"]
|
|
42
|
+
* @param {string[]} affectedChecks
|
|
43
|
+
* @param {Record<string, string>} scripts
|
|
44
|
+
* @returns {string[]} ordered list of script names to retry
|
|
45
|
+
*/
|
|
46
|
+
function resolveRetryScripts(affectedChecks, scripts) {
|
|
47
|
+
const retry = new Set();
|
|
48
|
+
|
|
49
|
+
for (const check of affectedChecks) {
|
|
50
|
+
// Evidence failures → re-run the failing validation scripts
|
|
51
|
+
if (check === "evidence" || check === "result") {
|
|
52
|
+
if (scripts.test) retry.add("test");
|
|
53
|
+
if (scripts.lint) retry.add("lint");
|
|
54
|
+
if (scripts.build) retry.add("build");
|
|
55
|
+
if (scripts.typecheck) retry.add("typecheck");
|
|
56
|
+
}
|
|
57
|
+
// Specific check types
|
|
58
|
+
if (check.includes("test")) retry.add("test");
|
|
59
|
+
if (check.includes("lint")) retry.add("lint");
|
|
60
|
+
if (check.includes("build")) retry.add("build");
|
|
61
|
+
if (check.includes("typecheck")) retry.add("typecheck");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Filter to only scripts that actually exist
|
|
65
|
+
return [...retry].filter((name) => !!scripts[name]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* CLI Remediation Executor — default implementation for `ai-workflow run`.
|
|
70
|
+
*
|
|
71
|
+
* Plugs into HealerEngine as the `remediate` function. On each attempt it:
|
|
72
|
+
* 1. Reads the remediation-request.json to understand what failed
|
|
73
|
+
* 2. Re-runs the affected npm scripts (lint, test, build, typecheck)
|
|
74
|
+
* 3. Reports changed files and whether any script now passes
|
|
75
|
+
*
|
|
76
|
+
* Design constraints:
|
|
77
|
+
* - This executor does NOT modify source code — it only re-runs validation commands.
|
|
78
|
+
* - It is effective for transient failures (e.g. flaky tests, stale build artifacts).
|
|
79
|
+
* - For structural failures (missing tests, broken implementation), it will exhaust
|
|
80
|
+
* its attempt budget and return applied:false, triggering a BLOCKED status.
|
|
81
|
+
* - The user is shown clear output on each attempt.
|
|
82
|
+
*
|
|
83
|
+
* @param {Object} ctx - Context provided by HealerEngine.run()
|
|
84
|
+
* @param {number} ctx.attempt
|
|
85
|
+
* @param {number} ctx.maxAttempts
|
|
86
|
+
* @param {string} ctx.mode
|
|
87
|
+
* @param {string} ctx.taskSlug
|
|
88
|
+
* @param {Object} ctx.result - Current combined validation result
|
|
89
|
+
* @param {string[]} ctx.affectedChecks
|
|
90
|
+
* @param {string} ctx.requestPath - Path to remediation-request.json
|
|
91
|
+
* @param {string} cwd - Consumer project working directory (bound via closure)
|
|
92
|
+
* @returns {Promise<{applied: boolean, changedFiles?: string[], evidenceAdded?: string[], reason?: string}>}
|
|
93
|
+
*/
|
|
94
|
+
export function createCliRemediationExecutor(cwd) {
|
|
95
|
+
return async function remediationExecutor({ attempt, maxAttempts, mode, affectedChecks, requestPath }) {
|
|
96
|
+
console.log(`\n[HEALER] Attempt ${attempt}/${maxAttempts} — mode: ${mode}`);
|
|
97
|
+
console.log(`[HEALER] Affected: ${affectedChecks.join(", ")}`);
|
|
98
|
+
|
|
99
|
+
const scripts = await readScripts(cwd);
|
|
100
|
+
const filesBefore = getChangedFiles(cwd);
|
|
101
|
+
const toRetry = resolveRetryScripts(affectedChecks, scripts);
|
|
102
|
+
|
|
103
|
+
if (toRetry.length === 0) {
|
|
104
|
+
console.log("[HEALER] No retryable scripts found for the affected checks.");
|
|
105
|
+
console.log(`[HEALER] Review ${requestPath} for details.`);
|
|
106
|
+
return {
|
|
107
|
+
applied: false,
|
|
108
|
+
reason: `No npm scripts available to address: ${affectedChecks.join(", ")}. Manual remediation required.`
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log(`[HEALER] Re-running: ${toRetry.map((s) => `npm run ${s}`).join(", ")}`);
|
|
113
|
+
|
|
114
|
+
const results = [];
|
|
115
|
+
let anyPassed = false;
|
|
116
|
+
|
|
117
|
+
for (const scriptName of toRetry) {
|
|
118
|
+
process.stdout.write(` → npm run ${scriptName} ... `);
|
|
119
|
+
const result = spawnSync("npm", ["run", scriptName], {
|
|
120
|
+
cwd,
|
|
121
|
+
shell: true,
|
|
122
|
+
encoding: "utf8",
|
|
123
|
+
timeout: 120000
|
|
124
|
+
});
|
|
125
|
+
const passed = result.status === 0;
|
|
126
|
+
if (passed) anyPassed = true;
|
|
127
|
+
console.log(passed ? "PASS" : "FAIL");
|
|
128
|
+
results.push({ script: scriptName, passed, exitCode: result.status });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const filesAfter = getChangedFiles(cwd);
|
|
132
|
+
const changedFiles = filesAfter.filter((f) => !filesBefore.includes(f));
|
|
133
|
+
|
|
134
|
+
if (!anyPassed && changedFiles.length === 0) {
|
|
135
|
+
console.log("[HEALER] No scripts passed and no files changed — remediation had no effect.");
|
|
136
|
+
return {
|
|
137
|
+
applied: false,
|
|
138
|
+
reason: `Re-ran ${toRetry.join(", ")} — all failed. Structural fix required by the implementing agent.`
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log(`[HEALER] Applied: ${results.filter((r) => r.passed).map((r) => r.script).join(", ") || "none passed"}`);
|
|
143
|
+
if (changedFiles.length) console.log(`[HEALER] Changed files: ${changedFiles.join(", ")}`);
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
applied: true,
|
|
147
|
+
changedFiles,
|
|
148
|
+
evidenceAdded: anyPassed ? ["validation-output"] : []
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
import { isRecoverableGateFailure } from "../statuses.js";
|
|
5
|
+
|
|
6
|
+
const MODE_ATTEMPTS = Object.freeze({ quick: 1, standard: 2, full: 3 });
|
|
7
|
+
|
|
8
|
+
function stableJson(value) {
|
|
9
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
10
|
+
if (value && typeof value === "object") {
|
|
11
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
12
|
+
}
|
|
13
|
+
return JSON.stringify(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function collectBlockingFindings(result = {}) {
|
|
17
|
+
const findings = [];
|
|
18
|
+
const add = (source, value) => {
|
|
19
|
+
if (!value || typeof value !== "object") return;
|
|
20
|
+
const status = value.status || value.overallStatus;
|
|
21
|
+
if (!["FAIL", "FAIL_QUALITY_GATE", "FAIL_DELEGATION_GATE", "BLOCKED"].includes(status)) return;
|
|
22
|
+
findings.push({
|
|
23
|
+
source,
|
|
24
|
+
status,
|
|
25
|
+
missing: Array.isArray(value.missing) ? [...value.missing].sort() : [],
|
|
26
|
+
reason: value.reason || value.summary || ""
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
add("result", result);
|
|
31
|
+
add("evidence", result.evidence);
|
|
32
|
+
add("quality", result.quality);
|
|
33
|
+
const checks = result.quality?.checks || result.policyValidation?.checks || result.checks || {};
|
|
34
|
+
for (const [name, check] of Object.entries(checks)) add(`check:${name}`, check);
|
|
35
|
+
return findings.sort((a, b) => a.source.localeCompare(b.source));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class HealerEngine {
|
|
39
|
+
constructor({ cwd, mode = "standard", taskSlug = "implementation", maxAttempts = null } = {}) {
|
|
40
|
+
this.cwd = cwd;
|
|
41
|
+
this.mode = MODE_ATTEMPTS[mode] ? mode : "standard";
|
|
42
|
+
this.taskSlug = taskSlug;
|
|
43
|
+
this.maxAttempts = maxAttempts ?? MODE_ATTEMPTS[this.mode];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get statePath() {
|
|
47
|
+
return path.join(this.cwd, ".ai-workflow", `healing-state-${this.taskSlug}.json`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fingerprint(result) {
|
|
51
|
+
return crypto.createHash("sha256").update(stableJson(collectBlockingFindings(result))).digest("hex");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
blockingCount(result) {
|
|
55
|
+
return collectBlockingFindings(result).length;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
affectedChecks(result) {
|
|
59
|
+
return collectBlockingFindings(result).map((finding) => finding.source);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
hasProgress(before, after, remediation = {}) {
|
|
63
|
+
if (!isRecoverableGateFailure(after.overallStatus)) return true;
|
|
64
|
+
const beforeCount = this.blockingCount(before);
|
|
65
|
+
const afterCount = this.blockingCount(after);
|
|
66
|
+
if (afterCount < beforeCount) return true;
|
|
67
|
+
if (this.fingerprint(before) !== this.fingerprint(after) && (remediation.changedFiles?.length || remediation.evidenceAdded?.length)) return true;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async writeState(state) {
|
|
72
|
+
await fs.mkdir(path.dirname(this.statePath), { recursive: true });
|
|
73
|
+
await fs.writeFile(this.statePath, JSON.stringify(state, null, 2));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async resetState() {
|
|
77
|
+
try { await fs.unlink(this.statePath); } catch {}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async writeRemediationRequest({ attempt, result }) {
|
|
81
|
+
const requestPath = path.join(this.cwd, ".ai-workflow", "remediation-request.json");
|
|
82
|
+
await fs.mkdir(path.dirname(requestPath), { recursive: true });
|
|
83
|
+
const request = {
|
|
84
|
+
taskSlug: this.taskSlug,
|
|
85
|
+
executionMode: this.mode,
|
|
86
|
+
attempt,
|
|
87
|
+
maxAttempts: this.maxAttempts,
|
|
88
|
+
status: result.overallStatus,
|
|
89
|
+
affectedChecks: this.affectedChecks(result),
|
|
90
|
+
findingsFingerprint: this.fingerprint(result),
|
|
91
|
+
instruction: "Apply the smallest safe correction for the listed gates, then rerun validation. Do not broaden scope."
|
|
92
|
+
};
|
|
93
|
+
await fs.writeFile(requestPath, JSON.stringify(request, null, 2));
|
|
94
|
+
return requestPath;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async run({ initialResult, validate, remediate }) {
|
|
98
|
+
let current = initialResult;
|
|
99
|
+
const history = [];
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
|
|
102
|
+
if (!isRecoverableGateFailure(current.overallStatus)) {
|
|
103
|
+
await this.resetState();
|
|
104
|
+
return { ...current, remediation: { status: "NOT_REQUIRED", attempts: 0, history } };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (let attempt = 1; attempt <= this.maxAttempts; attempt += 1) {
|
|
108
|
+
const fingerprint = this.fingerprint(current);
|
|
109
|
+
if (seen.has(fingerprint)) {
|
|
110
|
+
const blocked = { overallStatus: "BLOCKED", reason: "Repeated unresolved finding", previousResult: current };
|
|
111
|
+
await this.writeState({ status: "BLOCKED", reason: blocked.reason, attempts: attempt - 1, history });
|
|
112
|
+
return { ...blocked, remediation: { status: "BLOCKED", attempts: attempt - 1, history } };
|
|
113
|
+
}
|
|
114
|
+
seen.add(fingerprint);
|
|
115
|
+
|
|
116
|
+
const requestPath = await this.writeRemediationRequest({ attempt, result: current });
|
|
117
|
+
if (typeof remediate !== "function") {
|
|
118
|
+
const blocked = { overallStatus: "BLOCKED", reason: "No remediation executor available", previousResult: current, requestPath };
|
|
119
|
+
await this.writeState({ status: "BLOCKED", reason: blocked.reason, attempts: attempt - 1, history, requestPath });
|
|
120
|
+
return { ...blocked, remediation: { status: "BLOCKED", attempts: attempt - 1, history, requestPath } };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const remediation = await remediate({
|
|
124
|
+
attempt,
|
|
125
|
+
maxAttempts: this.maxAttempts,
|
|
126
|
+
mode: this.mode,
|
|
127
|
+
taskSlug: this.taskSlug,
|
|
128
|
+
result: current,
|
|
129
|
+
affectedChecks: this.affectedChecks(current),
|
|
130
|
+
requestPath
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (!remediation?.applied) {
|
|
134
|
+
const blocked = { overallStatus: "BLOCKED", reason: remediation?.reason || "Remediation was not applied", previousResult: current, requestPath };
|
|
135
|
+
history.push({ attempt, before: current.overallStatus, remediation, after: "NOT_RUN", progress: false });
|
|
136
|
+
await this.writeState({ status: "BLOCKED", reason: blocked.reason, attempts: attempt, history });
|
|
137
|
+
return { ...blocked, remediation: { status: "BLOCKED", attempts: attempt, history } };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const next = await validate({ affectedChecks: this.affectedChecks(current), attempt });
|
|
141
|
+
const progress = this.hasProgress(current, next, remediation);
|
|
142
|
+
history.push({
|
|
143
|
+
attempt,
|
|
144
|
+
before: current.overallStatus,
|
|
145
|
+
after: next.overallStatus,
|
|
146
|
+
progress,
|
|
147
|
+
changedFiles: remediation.changedFiles || [],
|
|
148
|
+
evidenceAdded: remediation.evidenceAdded || [],
|
|
149
|
+
affectedChecks: this.affectedChecks(current)
|
|
150
|
+
});
|
|
151
|
+
await this.writeState({ status: next.overallStatus, attempts: attempt, history });
|
|
152
|
+
|
|
153
|
+
if (!isRecoverableGateFailure(next.overallStatus)) {
|
|
154
|
+
await this.resetState();
|
|
155
|
+
return { ...next, remediation: { status: "RESOLVED", attempts: attempt, history } };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!progress) {
|
|
159
|
+
return {
|
|
160
|
+
overallStatus: "BLOCKED",
|
|
161
|
+
reason: "Remediation made no measurable progress",
|
|
162
|
+
previousResult: next,
|
|
163
|
+
remediation: { status: "BLOCKED", attempts: attempt, history }
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
current = next;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
overallStatus: "BLOCKED",
|
|
172
|
+
reason: `Quality remediation attempts exhausted for ${this.mode} mode`,
|
|
173
|
+
previousResult: current,
|
|
174
|
+
remediation: { status: "BLOCKED", attempts: this.maxAttempts, history }
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export { MODE_ATTEMPTS, collectBlockingFindings };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const AGENT_MAP = {
|
|
2
|
+
"atlas": "Atlas",
|
|
3
|
+
"nexus": "Nexus",
|
|
4
|
+
"orion": "Orion",
|
|
5
|
+
"astra": "Astra",
|
|
6
|
+
"sage": "Sage",
|
|
7
|
+
"phoenix": "Phoenix",
|
|
8
|
+
"architecture": "Architecture-Specialist",
|
|
9
|
+
"backend-development": "Backend-Engineer",
|
|
10
|
+
"deployment": "Deployment-Specialist",
|
|
11
|
+
"design-principles": "Design-Specialist",
|
|
12
|
+
"documentation": "Docs-Engineer",
|
|
13
|
+
"frontend-development": "Frontend-Engineer",
|
|
14
|
+
"full-stack-development": "Full-Stack-Engineer",
|
|
15
|
+
"optimize-tokens": "Token-Economist",
|
|
16
|
+
"pr-workflow": "PR-Manager",
|
|
17
|
+
"product-discovery": "Discovery-Analyst",
|
|
18
|
+
"product-planning": "Product-Planner",
|
|
19
|
+
"project-memory": "Memory-Guardian",
|
|
20
|
+
"prompt-engineer": "Prompt-Engineer",
|
|
21
|
+
"qa-workflow": "QA-Engineer",
|
|
22
|
+
"refactoring": "Refactoring-Specialist",
|
|
23
|
+
"release-workflow": "Release-Specialist",
|
|
24
|
+
"spec-driven-development": "SDD-Specialist",
|
|
25
|
+
"technical-leadership": "Technical-Leader",
|
|
26
|
+
"ui-ux-design": "UI-UX-Engineer"
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the canonical (commercial) name for an agent given its internal slug.
|
|
31
|
+
* Falls back to PascalCase translation if no mapping exists.
|
|
32
|
+
* @param {string} slug
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
export function getCanonicalAgentName(slug) {
|
|
36
|
+
if (AGENT_MAP[slug]) return AGENT_MAP[slug];
|
|
37
|
+
|
|
38
|
+
// Fallback: convert slug-case to PascalCase
|
|
39
|
+
return slug
|
|
40
|
+
.split("-")
|
|
41
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
42
|
+
.join("");
|
|
43
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { getTemplateFiles } from "./templates.js";
|
|
3
3
|
|
|
4
|
-
export async function createInstallPlan({ cwd, exists, profile }) {
|
|
4
|
+
export async function createInstallPlan({ cwd, exists, profile = "standard" }) {
|
|
5
5
|
const actions = [];
|
|
6
6
|
const templateFiles = getTemplateFiles(profile);
|
|
7
7
|
const installRoot = ".ai-workflow";
|
|
@@ -22,10 +22,10 @@ export async function createInstallPlan({ cwd, exists, profile }) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const configPath = path.join(cwd, ".ai-workflow.json");
|
|
25
|
+
const configPath = path.join(cwd, ".ai-workflow/config.json");
|
|
26
26
|
actions.push({
|
|
27
27
|
type: (await exists(configPath)) ? "conflict" : "create",
|
|
28
|
-
relativePath: ".ai-workflow.json",
|
|
28
|
+
relativePath: ".ai-workflow/config.json",
|
|
29
29
|
absolutePath: configPath,
|
|
30
30
|
content: null
|
|
31
31
|
});
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { exists, readJsonc, writeFileSafe } from "./filesystem.js";
|
|
3
|
+
import { createManagedBackup } from "./backup.js";
|
|
4
|
+
import { getTemplateFiles } from "./templates.js";
|
|
5
|
+
|
|
6
|
+
const LEGACY_MARKER = "_aiWorkflowManaged";
|
|
7
|
+
|
|
8
|
+
const AGENTS = {
|
|
9
|
+
Atlas: { description: "Router and workflow coordinator for AI Workflow Kit" },
|
|
10
|
+
Nexus: { description: "Discovery, requirement, scope, and specification owner" },
|
|
11
|
+
Orion: { description: "Planning, PR sequencing, release, and deployment strategy owner" },
|
|
12
|
+
Astra: { description: "Implementation owner for incremental, scoped changes" },
|
|
13
|
+
Sage: { description: "Audit, validation, evidence, and quality gate owner" },
|
|
14
|
+
Phoenix: { description: "Remediation and regression recovery owner" }
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const SUBAGENTS = {
|
|
18
|
+
"Architecture-Specialist": { description: "Select the simplest architecture that safely satisfies current requirements", skill: "architecture" },
|
|
19
|
+
"Backend-Engineer": { description: "Support safe PHP/Node/Python backend changes for APIs and persistence", skill: "backend-development" },
|
|
20
|
+
"Deployment-Specialist": { description: "Plan, review, or validate deployment, release, and production-readiness", skill: "deployment" },
|
|
21
|
+
"Design-Specialist": { description: "Apply practical design principles to keep solutions simple and maintainable", skill: "design-principles" },
|
|
22
|
+
"Docs-Engineer": { description: "Write or improve project documentation, READMEs, guides, and prompts", skill: "documentation" },
|
|
23
|
+
"Frontend-Engineer": { description: "Implement or review frontend changes involving UI, state, routing, and accessibility", skill: "frontend-development" },
|
|
24
|
+
"Full-Stack-Engineer": { description: "Coordinate frontend and backend changes as one coherent, testable increment", skill: "full-stack-development" },
|
|
25
|
+
"Token-Economist": { description: "Reduce context size while preserving information required for safe execution", skill: "optimize-tokens" },
|
|
26
|
+
"PR-Manager": { description: "Plan, implement, review, or validate small pull requests while preserving scope", skill: "pr-workflow" },
|
|
27
|
+
"Discovery-Analyst": { description: "Clarify ambiguous requests into actionable problem statements and success outcomes", skill: "product-discovery" },
|
|
28
|
+
"Product-Planner": { description: "Turn clarified needs into scoped requirements with acceptance-ready outcomes", skill: "product-planning" },
|
|
29
|
+
"Memory-Guardian": { description: "Manage discoverable project memory for durable decisions and recurring corrections", skill: "project-memory" },
|
|
30
|
+
"Prompt-Engineer": { description: "Expert in creating and refining prompts for AI agents and workflows", skill: "prompt-engineer" },
|
|
31
|
+
"QA-Engineer": { description: "Design, review, or improve tests, acceptance criteria, and validation evidence", skill: "qa-workflow" },
|
|
32
|
+
"Refactoring-Specialist": { description: "Improve code/document structure safely while preserving behavior", skill: "refactoring" },
|
|
33
|
+
"Release-Specialist": { description: "Prepare release readiness decisions with explicit gates and evidence", skill: "release-workflow" },
|
|
34
|
+
"SDD-Specialist": { description: "Convert approved requirements into explicit, testable specification artifacts", skill: "spec-driven-development" },
|
|
35
|
+
"Technical-Leader": { description: "Make technical decisions, review architecture, and identify trade-offs", skill: "technical-leadership" },
|
|
36
|
+
"UI-UX-Engineer": { description: "Improve usability and interface clarity without introducing unnecessary complexity", skill: "ui-ux-design" }
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const COMMANDS = {
|
|
40
|
+
atlas: { description: "Decide safest next step and delegate to the appropriate workflow or agent", agent: "Atlas" },
|
|
41
|
+
run: { description: "Execute the master orchestration pipeline (Gates, SDD, Implementation, Validation, Healing)", agent: "Atlas" },
|
|
42
|
+
discover: { description: "Understand the project, gather context, and create initial documentation", agent: "Nexus" },
|
|
43
|
+
"spec-create": { description: "Create a clear specification before implementation", agent: "Nexus" },
|
|
44
|
+
"spec-review": { description: "Review a specification and validate scope, risks, criteria, and gaps", agent: "Nexus" },
|
|
45
|
+
"spec-implement": { description: "Implement an approved specification incrementally", agent: "Astra" },
|
|
46
|
+
plan: { description: "Plan a task or change, defining steps, risks, and validation", agent: "Orion" },
|
|
47
|
+
implement: { description: "Implement a small task with defined scope", agent: "Astra" },
|
|
48
|
+
validate: { description: "Run project validations and collect evidence", agent: "Sage" },
|
|
49
|
+
audit: { description: "Audit the project, identify issues, and suggest prioritized improvements", agent: "Sage" },
|
|
50
|
+
"optimize-tokens": { description: "Analyze workflow and context usage; suggest reductions without losing quality or evidence", agent: "Sage" },
|
|
51
|
+
"update-memory": { description: "Update durable project memory with relevant decisions, constraints, and reusable context", agent: "Nexus" },
|
|
52
|
+
release: { description: "Prepare delivery with commit, push, PR/merge readiness, changelog, and evidence", agent: "Orion" },
|
|
53
|
+
deploy: { description: "Publish the project to the defined environment after validation and release readiness", agent: "Orion" }
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function buildManagedConfig() {
|
|
57
|
+
const agent = {};
|
|
58
|
+
for (const [name, def] of Object.entries(AGENTS)) {
|
|
59
|
+
agent[name] = {
|
|
60
|
+
mode: "primary",
|
|
61
|
+
description: def.description,
|
|
62
|
+
prompt: `{file:./.ai-workflow/opencode/agents/${name.toLowerCase()}.md}`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const [name, def] of Object.entries(SUBAGENTS)) {
|
|
67
|
+
agent[name] = {
|
|
68
|
+
mode: "subagent",
|
|
69
|
+
description: def.description,
|
|
70
|
+
prompt: `{file:./.ai-workflow/opencode/skills/${def.skill}/SKILL.md}`
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const command = {};
|
|
75
|
+
for (const [name, def] of Object.entries(COMMANDS)) {
|
|
76
|
+
command[name] = {
|
|
77
|
+
description: def.description,
|
|
78
|
+
agent: def.agent,
|
|
79
|
+
template: `{file:./.ai-workflow/opencode/commands/${name}.md}`
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
$schema: "https://opencode.ai/config.json",
|
|
85
|
+
default_agent: "Atlas",
|
|
86
|
+
agent,
|
|
87
|
+
skills: {
|
|
88
|
+
paths: ["./.ai-workflow/opencode/skills"]
|
|
89
|
+
},
|
|
90
|
+
command
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function mergeOpencodeConfig(cwd, { force = false, backupRoot = ".ai-workflow-backups" } = {}) {
|
|
95
|
+
const targetPath = path.join(cwd, "opencode.jsonc");
|
|
96
|
+
const managed = buildManagedConfig();
|
|
97
|
+
|
|
98
|
+
if (!(await exists(targetPath))) {
|
|
99
|
+
await writeFileSafe(targetPath, `${JSON.stringify(managed, null, 2)}\n`);
|
|
100
|
+
return { changed: true, reason: "created" };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let current;
|
|
104
|
+
try {
|
|
105
|
+
current = await readJsonc(targetPath);
|
|
106
|
+
} catch {
|
|
107
|
+
if (!force) {
|
|
108
|
+
return { changed: false, reason: "invalid-json (skipped)" };
|
|
109
|
+
}
|
|
110
|
+
await createManagedBackup(targetPath, {
|
|
111
|
+
cwd,
|
|
112
|
+
backupRoot,
|
|
113
|
+
maxPerFile: 20
|
|
114
|
+
});
|
|
115
|
+
await writeFileSafe(targetPath, `${JSON.stringify(managed, null, 2)}\n`);
|
|
116
|
+
return { changed: true, reason: "invalid-json (replaced with --force)" };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const { [LEGACY_MARKER]: _legacyManaged, ...currentWithoutLegacy } = current;
|
|
120
|
+
|
|
121
|
+
const next = {
|
|
122
|
+
...currentWithoutLegacy,
|
|
123
|
+
$schema: current.$schema ?? managed.$schema,
|
|
124
|
+
...(managed.mcp
|
|
125
|
+
? {
|
|
126
|
+
mcp: {
|
|
127
|
+
...(current.mcp ?? {}),
|
|
128
|
+
...managed.mcp
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
: {}),
|
|
132
|
+
agent: {
|
|
133
|
+
...(current.agent ?? {}),
|
|
134
|
+
...managed.agent
|
|
135
|
+
},
|
|
136
|
+
command: {
|
|
137
|
+
...(current.command ?? {}),
|
|
138
|
+
...managed.command
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const changed = JSON.stringify(current) !== JSON.stringify(next);
|
|
143
|
+
if (!changed) {
|
|
144
|
+
return { changed: false, reason: "already-up-to-date" };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
await writeFileSafe(targetPath, `${JSON.stringify(next, null, 2)}\n`);
|
|
148
|
+
return { changed: true, reason: "merged-managed-sections" };
|
|
149
|
+
}
|
|
@@ -14,15 +14,33 @@ let cachedRoot = null;
|
|
|
14
14
|
* Return the absolute path to the installed package root
|
|
15
15
|
* (the directory containing `.agents/skills/`).
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* It dynamically searches for the package.json belonging to @williambeto/ai-workflow
|
|
18
|
+
* by climbing up from the current module location.
|
|
19
19
|
*/
|
|
20
20
|
export function getPackageRoot() {
|
|
21
21
|
if (cachedRoot) return cachedRoot;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
let currentDir = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
while (true) {
|
|
25
|
+
const pkgPath = resolve(currentDir, "package.json");
|
|
26
|
+
try {
|
|
27
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
28
|
+
if (pkg.name === "@williambeto/ai-workflow") {
|
|
29
|
+
cachedRoot = currentDir;
|
|
30
|
+
return cachedRoot;
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// package.json doesn't exist or is invalid, keep climbing
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const parentDir = dirname(currentDir);
|
|
37
|
+
if (parentDir === currentDir) {
|
|
38
|
+
break; // Reached filesystem root
|
|
39
|
+
}
|
|
40
|
+
currentDir = parentDir;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new Error("Failed to resolve @williambeto/ai-workflow package root physically.");
|
|
26
44
|
}
|
|
27
45
|
|
|
28
46
|
/**
|
|
@@ -96,11 +114,11 @@ export function discoverPackageFiles(baseRelativePath) {
|
|
|
96
114
|
|
|
97
115
|
/**
|
|
98
116
|
* Read the SKILL.md for a given skill name, plus any reference files
|
|
99
|
-
* found under a
|
|
117
|
+
* found under a directory.
|
|
100
118
|
* Returns a map of { relativePath: content }.
|
|
101
119
|
*/
|
|
102
120
|
export function getFullSkillFiles(skillName) {
|
|
103
|
-
const skillRelPath =
|
|
121
|
+
const skillRelPath = `dist-assets/skills/${skillName}`;
|
|
104
122
|
const files = discoverPackageFiles(skillRelPath);
|
|
105
123
|
return files;
|
|
106
124
|
}
|
|
@@ -110,7 +128,7 @@ export function getFullSkillFiles(skillName) {
|
|
|
110
128
|
* Returns the content string or null.
|
|
111
129
|
*/
|
|
112
130
|
export function getFullAgentContent(agentName) {
|
|
113
|
-
return readPackageFile(`
|
|
131
|
+
return readPackageFile(`dist-assets/agents/${agentName}.md`);
|
|
114
132
|
}
|
|
115
133
|
|
|
116
134
|
/**
|
|
@@ -118,5 +136,6 @@ export function getFullAgentContent(agentName) {
|
|
|
118
136
|
* Returns the content string or null.
|
|
119
137
|
*/
|
|
120
138
|
export function getFullCommandContent(commandName) {
|
|
121
|
-
return readPackageFile(`
|
|
139
|
+
return readPackageFile(`dist-assets/commands/${commandName}.md`);
|
|
122
140
|
}
|
|
141
|
+
|