@williambeto/ai-workflow 1.19.1 → 2.2.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 -838
- package/PUBLISH_MANIFEST.json +34 -0
- package/README.md +78 -148
- 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/docs/visual-validation-guide.md +76 -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 +43 -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 +114 -0
- package/src/commands/collect-evidence.js +61 -0
- package/src/commands/doctor.js +186 -0
- package/src/commands/execute.js +172 -0
- package/{packages/ai-workflow/src → src}/commands/init.js +119 -20
- package/src/commands/run.js +112 -0
- package/src/core/completion-contract.js +35 -0
- package/src/core/execution-planner.js +59 -0
- package/src/core/gates/branch-gate.js +146 -0
- package/src/core/handoff/handoff-engine.js +104 -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/request-classifier.js +58 -0
- package/src/core/runtime/opencode-adapter.js +94 -0
- 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 +221 -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/src/core/workflow-state-machine.js +46 -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 -276
- 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,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
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { resolveWorkflowProfile, getWorkflowProfile } from "./workflow-profiles.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RequestClassifier - Classifies natural requests into structured, testable contracts.
|
|
5
|
+
*/
|
|
6
|
+
export class RequestClassifier {
|
|
7
|
+
/**
|
|
8
|
+
* Classifies a natural request.
|
|
9
|
+
* @param {string} request - The natural language request string.
|
|
10
|
+
* @returns {Object} Structured classification contract.
|
|
11
|
+
*/
|
|
12
|
+
classify(request = "") {
|
|
13
|
+
const text = String(request).trim();
|
|
14
|
+
if (!text) {
|
|
15
|
+
throw new Error("Cannot classify an empty request.");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 1. Resolve Profile
|
|
19
|
+
const profile = resolveWorkflowProfile({ request: text });
|
|
20
|
+
const profileDef = getWorkflowProfile(profile);
|
|
21
|
+
|
|
22
|
+
// 2. Classify Intent
|
|
23
|
+
const readOnlyPatterns = /\b(analyze|check|inspect|review|find|search|show|list|read|view|verify)\b/i;
|
|
24
|
+
const isReadOnly = readOnlyPatterns.test(text);
|
|
25
|
+
const intent = isReadOnly ? "read-only" : "write";
|
|
26
|
+
|
|
27
|
+
// 3. Classify Mode
|
|
28
|
+
let mode = "standard";
|
|
29
|
+
if (/\b(deep|architectural|migration|major|full|\[deep\])\b/i.test(text)) {
|
|
30
|
+
mode = "full";
|
|
31
|
+
} else if (/\b(tiny|small|quick|simple|only\s+update|typo|comment|\[tiny\])\b/i.test(text)) {
|
|
32
|
+
mode = "quick";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 4. Classify Risk
|
|
36
|
+
let risk = "medium";
|
|
37
|
+
if (mode === "full" || profile === "security-review") {
|
|
38
|
+
risk = "high";
|
|
39
|
+
} else if (mode === "quick" || intent === "read-only") {
|
|
40
|
+
risk = "low";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const specNeeded = mode === "full" && intent === "write";
|
|
44
|
+
const validationNeeded = intent === "write";
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
request: text,
|
|
48
|
+
profile,
|
|
49
|
+
owner: profileDef.owner,
|
|
50
|
+
intent,
|
|
51
|
+
mode,
|
|
52
|
+
risk,
|
|
53
|
+
specNeeded,
|
|
54
|
+
validationNeeded,
|
|
55
|
+
skills: [...profileDef.skills]
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { spawn, execSync } from "node:child_process";
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OpenCodeAdapter - Real runtime integration with the OpenCode CLI.
|
|
6
|
+
*/
|
|
7
|
+
export class OpenCodeAdapter {
|
|
8
|
+
constructor({ cwd = process.cwd() } = {}) {
|
|
9
|
+
this.cwd = cwd;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Runs opencode with a prompt and options.
|
|
14
|
+
* @param {string} message - The message prompt.
|
|
15
|
+
* @param {Object} options - CLI options (e.g. agent, model, dangerouslySkipPermissions).
|
|
16
|
+
* @returns {Promise<{success: boolean, commandsRun: string[], eventCount: number}>}
|
|
17
|
+
*/
|
|
18
|
+
async execute(message, { agent = null, model = null, dangerouslySkipPermissions = false } = {}) {
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
const args = ["run", message, "--format", "json"];
|
|
21
|
+
if (agent) {
|
|
22
|
+
args.push("--agent", agent);
|
|
23
|
+
}
|
|
24
|
+
if (model) {
|
|
25
|
+
args.push("--model", model);
|
|
26
|
+
}
|
|
27
|
+
if (dangerouslySkipPermissions) {
|
|
28
|
+
args.push("--dangerously-skip-permissions");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`[RUNTIME] Delegating to OpenCode: opencode ${args.map(a => a.includes(" ") ? `"${a}"` : a).join(" ")}`);
|
|
32
|
+
|
|
33
|
+
const child = spawn("opencode", args, {
|
|
34
|
+
cwd: this.cwd,
|
|
35
|
+
shell: true,
|
|
36
|
+
stdio: ["ignore", "pipe", "inherit"] // Inherit stderr to show warnings directly
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const rl = readline.createInterface({
|
|
40
|
+
input: child.stdout,
|
|
41
|
+
terminal: false
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const commandsRun = [];
|
|
45
|
+
let eventCount = 0;
|
|
46
|
+
|
|
47
|
+
rl.on("line", (line) => {
|
|
48
|
+
const trimmed = line.trim();
|
|
49
|
+
if (!trimmed) return;
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const event = JSON.parse(trimmed);
|
|
53
|
+
eventCount++;
|
|
54
|
+
|
|
55
|
+
// 1. Stream agent output text in real-time to user
|
|
56
|
+
if (event.type === "text" && event.part?.text) {
|
|
57
|
+
process.stdout.write(event.part.text);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Capture tool executions/commands
|
|
61
|
+
if (event.type === "step_start" && event.part?.toolCalls) {
|
|
62
|
+
for (const call of event.part.toolCalls) {
|
|
63
|
+
if (call.name === "run_command" && call.args?.CommandLine) {
|
|
64
|
+
commandsRun.push(call.args.CommandLine);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
// If a line is not valid JSON (e.g. starting/finishing logs), print it directly
|
|
70
|
+
console.log(trimmed);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
child.on("close", (code) => {
|
|
75
|
+
console.log("\n[RUNTIME] OpenCode finished execution.");
|
|
76
|
+
resolve({
|
|
77
|
+
success: code === 0,
|
|
78
|
+
commandsRun,
|
|
79
|
+
eventCount
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
child.on("error", (err) => {
|
|
84
|
+
console.error(`\n[RUNTIME] Failed to launch opencode: ${err.message}`);
|
|
85
|
+
resolve({
|
|
86
|
+
success: false,
|
|
87
|
+
commandsRun,
|
|
88
|
+
eventCount: 0,
|
|
89
|
+
error: err.message
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SpecValidator - Enforces "No Spec, No Code" rule.
|
|
5
|
+
* Validates existence, structure, and approval status of specifications.
|
|
6
|
+
*/
|
|
7
|
+
export class SpecValidator {
|
|
8
|
+
/**
|
|
9
|
+
* Validates a specification file.
|
|
10
|
+
* @param {string} filePath - Path to the .md specification file.
|
|
11
|
+
* @returns {Promise<{valid: boolean, reason?: string, tier?: string}>}
|
|
12
|
+
*/
|
|
13
|
+
async validate(filePath) {
|
|
14
|
+
try {
|
|
15
|
+
const content = await fs.readFile(filePath, "utf8");
|
|
16
|
+
|
|
17
|
+
// Check for tiered tier identification
|
|
18
|
+
let tier = "unknown";
|
|
19
|
+
if (content.includes("[DEEP]")) tier = "deep";
|
|
20
|
+
else if (content.includes("[STANDARD]")) tier = "standard";
|
|
21
|
+
else if (content.includes("[TINY]")) tier = "tiny";
|
|
22
|
+
|
|
23
|
+
if (tier === "unknown") {
|
|
24
|
+
return { valid: false, reason: "Specification tier [DEEP|STANDARD|TINY] not identified in title." };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check for Metadata section
|
|
28
|
+
if (!content.includes("## Metadata")) {
|
|
29
|
+
return { valid: false, reason: "Missing '## Metadata' section.", tier };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Check for Acceptance Criteria section
|
|
33
|
+
if (!content.includes("## Acceptance Criteria")) {
|
|
34
|
+
return { valid: false, reason: "Missing '## Acceptance Criteria' section.", tier };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Check for Approved status
|
|
38
|
+
const lines = content.split("\n");
|
|
39
|
+
const statusLine = lines.find(l => l.includes("Status:"));
|
|
40
|
+
|
|
41
|
+
if (!statusLine) {
|
|
42
|
+
return { valid: false, reason: "Missing Status field in Metadata section.", tier };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const statusPart = statusLine.split(":")[1]
|
|
46
|
+
.replace(/[\*_]/g, "") // Remove bold/italic markers
|
|
47
|
+
.trim()
|
|
48
|
+
.toUpperCase();
|
|
49
|
+
|
|
50
|
+
// If it contains multiple options separated by |, it's not approved yet
|
|
51
|
+
if (statusPart.includes("|")) {
|
|
52
|
+
return { valid: false, reason: "Specification status is a template list. Must be explicitly set to 'APPROVED'.", tier };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (statusPart !== "APPROVED") {
|
|
56
|
+
return { valid: false, reason: `Specification status is '${statusPart}', but must be 'APPROVED' to proceed.`, tier };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return { valid: true, tier };
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error.code === "ENOENT") {
|
|
62
|
+
return { valid: false, reason: `Specification file not found: ${filePath}` };
|
|
63
|
+
}
|
|
64
|
+
return { valid: false, reason: `Error reading specification: ${error.message}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const COMPLETION_STATUSES = Object.freeze([
|
|
2
|
+
"PASS",
|
|
3
|
+
"PASS_WITH_NOTES",
|
|
4
|
+
"FAIL_DELEGATION_GATE",
|
|
5
|
+
"FAIL_QUALITY_GATE",
|
|
6
|
+
"FAIL",
|
|
7
|
+
"BLOCKED",
|
|
8
|
+
"NOT_RUN"
|
|
9
|
+
]);
|
|
10
|
+
|
|
11
|
+
export const RECOVERABLE_GATE_STATUSES = Object.freeze([
|
|
12
|
+
"FAIL_DELEGATION_GATE",
|
|
13
|
+
"FAIL_QUALITY_GATE"
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
export const TERMINAL_FAILURE_STATUSES = Object.freeze([
|
|
17
|
+
"FAIL",
|
|
18
|
+
"BLOCKED"
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
export function isRecoverableGateFailure(status) {
|
|
22
|
+
return RECOVERABLE_GATE_STATUSES.includes(status);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isTerminalFailure(status) {
|
|
26
|
+
return TERMINAL_FAILURE_STATUSES.includes(status);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const COMPLETION_STATUS_TEXT = COMPLETION_STATUSES.join(" | ");
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
function normalize(p) {
|
|
5
|
+
return p.split(path.sep).join("/");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* For v3.0.0 "Elite Governance", we want an ULTRA-CLEAN root.
|
|
10
|
+
* Only "opencode" is symlinked to the root (required for OpenCode discovery).
|
|
11
|
+
* All other assets stay inside .ai-workflow/.
|
|
12
|
+
*/
|
|
13
|
+
const LINKABLE_ROOTS = new Set([
|
|
14
|
+
"opencode",
|
|
15
|
+
".agents"
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
const LINKABLE_FILES = new Set([]);
|
|
19
|
+
|
|
20
|
+
export function buildSymlinkEntries({ templateFiles, installRoot = ".ai-workflow" }) {
|
|
21
|
+
const entries = new Map();
|
|
22
|
+
|
|
23
|
+
for (const relativePath of Object.keys(templateFiles)) {
|
|
24
|
+
if (relativePath === "opencode.jsonc") continue;
|
|
25
|
+
|
|
26
|
+
const normalized = normalize(relativePath);
|
|
27
|
+
|
|
28
|
+
if (LINKABLE_FILES.has(normalized)) {
|
|
29
|
+
entries.set(normalized, `${installRoot}/${normalized}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Match composite paths in LINKABLE_ROOTS (e.g., "docs/policies")
|
|
34
|
+
for (const rootPath of LINKABLE_ROOTS) {
|
|
35
|
+
if (normalized === rootPath || normalized.startsWith(`${rootPath}/`)) {
|
|
36
|
+
entries.set(rootPath, `${installRoot}/${rootPath}`);
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Array.from(entries.entries()).map(([linkPath, targetPath]) => ({ linkPath, targetPath }));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export async function isSymlinkTo(absoluteLinkPath, absoluteTargetPath) {
|
|
46
|
+
try {
|
|
47
|
+
const stat = await fs.lstat(absoluteLinkPath);
|
|
48
|
+
if (!stat.isSymbolicLink()) return false;
|
|
49
|
+
const currentTarget = await fs.readlink(absoluteLinkPath);
|
|
50
|
+
const resolved = path.resolve(path.dirname(absoluteLinkPath), currentTarget);
|
|
51
|
+
return resolved === absoluteTargetPath;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Internal symlink to satisfy opencode.jsonc paths without polluting the root.
|
|
59
|
+
* Creates .ai-workflow/opencode/skills -> ../.agents/skills
|
|
60
|
+
*/
|
|
61
|
+
export async function setupInternalSymlinks(cwd, installRoot = ".ai-workflow") {
|
|
62
|
+
const skillsLink = path.join(cwd, installRoot, "opencode/skills");
|
|
63
|
+
const skillsTarget = path.join(cwd, installRoot, ".agents/skills");
|
|
64
|
+
|
|
65
|
+
if (!(await exists(skillsTarget))) return;
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const stat = await fs.lstat(skillsLink).catch(() => null);
|
|
69
|
+
if (stat) {
|
|
70
|
+
if (stat.isSymbolicLink()) {
|
|
71
|
+
const current = await fs.readlink(skillsLink);
|
|
72
|
+
if (current === "../.agents/skills") return;
|
|
73
|
+
await fs.unlink(skillsLink);
|
|
74
|
+
} else {
|
|
75
|
+
return; // File exists, skip
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const type = process.platform === "win32" ? "junction" : "dir";
|
|
80
|
+
await fs.symlink("../.agents/skills", skillsLink, type);
|
|
81
|
+
} catch {
|
|
82
|
+
// Silent fail for internal symlink
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function exists(p) {
|
|
87
|
+
try {
|
|
88
|
+
await fs.access(p);
|
|
89
|
+
return true;
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|