@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.
Files changed (397) hide show
  1. package/CHANGELOG.md +56 -838
  2. package/PUBLISH_MANIFEST.json +34 -0
  3. package/README.md +78 -148
  4. package/{packages/ai-workflow/bin → bin}/ai-workflow.js +0 -0
  5. package/dist-assets/AGENTS.md +27 -0
  6. package/dist-assets/agents/astra.md +63 -0
  7. package/dist-assets/agents/atlas.md +169 -0
  8. package/dist-assets/agents/nexus.md +42 -0
  9. package/dist-assets/agents/orion.md +44 -0
  10. package/dist-assets/agents/phoenix.md +42 -0
  11. package/dist-assets/agents/sage.md +54 -0
  12. package/dist-assets/commands/README.md +14 -0
  13. package/dist-assets/commands/atlas.md +12 -0
  14. package/dist-assets/commands/audit.md +10 -0
  15. package/dist-assets/commands/deploy.md +12 -0
  16. package/dist-assets/commands/discover.md +10 -0
  17. package/dist-assets/commands/implement.md +28 -0
  18. package/dist-assets/commands/optimize-tokens.md +10 -0
  19. package/dist-assets/commands/plan.md +10 -0
  20. package/dist-assets/commands/release.md +12 -0
  21. package/dist-assets/commands/run.md +26 -0
  22. package/dist-assets/commands/spec-create.md +10 -0
  23. package/dist-assets/commands/spec-implement.md +10 -0
  24. package/dist-assets/commands/spec-review.md +10 -0
  25. package/dist-assets/commands/update-memory.md +10 -0
  26. package/dist-assets/commands/validate.md +12 -0
  27. package/dist-assets/docs/INDEX.md +21 -0
  28. package/dist-assets/docs/QUICKSTART.md +23 -0
  29. package/dist-assets/docs/adr/ADR-0000.md +19 -0
  30. package/dist-assets/docs/adr/ADR-0001.md +45 -0
  31. package/dist-assets/docs/adr/ADR-0002.md +62 -0
  32. package/dist-assets/docs/adr/ADR-0003.md +60 -0
  33. package/dist-assets/docs/adr/ADR-0004.md +71 -0
  34. package/dist-assets/docs/adr/ADR-0005.md +22 -0
  35. package/dist-assets/docs/adr/ADR-0006.md +82 -0
  36. package/dist-assets/docs/adr/ADR-0007.md +78 -0
  37. package/dist-assets/docs/api-engine-reference.md +7 -0
  38. package/{docs → dist-assets/docs}/architecture-policy.md +1 -1
  39. package/dist-assets/docs/cli-reference.md +27 -0
  40. package/dist-assets/docs/compatibility/provider-usage.md +38 -0
  41. package/dist-assets/docs/compatibility/runtime-matrix.md +30 -0
  42. package/dist-assets/docs/consumer-onboarding.md +17 -0
  43. package/dist-assets/docs/contributing-guide.md +11 -0
  44. package/{docs → dist-assets/docs}/design-patterns-policy.md +2 -2
  45. package/dist-assets/docs/full-documentation.md +113 -0
  46. package/{docs → dist-assets/docs}/npm-consumer-quickstart.md +18 -46
  47. package/dist-assets/docs/opencode-readme.md +8 -0
  48. package/dist-assets/docs/policies/01-BRANCH_GATE.md +63 -0
  49. package/dist-assets/docs/policies/02-SDD_METHODOLOGY.md +95 -0
  50. package/dist-assets/docs/policies/03-QUALITY_GATE.md +22 -0
  51. package/dist-assets/docs/policies/05-AGENT_CONTRACT.md +7 -0
  52. package/dist-assets/docs/policies/06-FINAL_EVIDENCE_CONTRACT.md +31 -0
  53. package/dist-assets/docs/policies/07-RELEASE_GATE.md +47 -0
  54. package/dist-assets/docs/policies/08-PRODUCT_TRUTHFULNESS_AND_PROJECT_DOCS.md +18 -0
  55. package/dist-assets/docs/policies/09-SPEC_VISIBILITY_AND_PUBLICATION.md +28 -0
  56. package/dist-assets/docs/policies/10-BEHAVIORAL_CONTRACT_HARDENING.md +9 -0
  57. package/dist-assets/docs/policies/11-EXECUTABLE_DELEGATION_AND_TRUTHFULNESS.md +7 -0
  58. package/dist-assets/docs/policies/ORCHESTRATION_PROTOCOL.md +15 -0
  59. package/dist-assets/docs/policies/PROCEDURE_DELIVERY_ARTIFACTS.md +21 -0
  60. package/dist-assets/docs/policies/PROCEDURE_DOCUMENTATION_CHECKLIST.md +24 -0
  61. package/dist-assets/docs/policies/PROCEDURE_UI_CHECKLIST.md +54 -0
  62. package/dist-assets/docs/profiles/README.md +19 -0
  63. package/dist-assets/docs/profiles/backend-api.md +5 -0
  64. package/dist-assets/docs/profiles/documentation.md +3 -0
  65. package/dist-assets/docs/profiles/frontend-product.md +19 -0
  66. package/dist-assets/docs/profiles/frontend-utility.md +19 -0
  67. package/dist-assets/docs/profiles/refactor.md +3 -0
  68. package/dist-assets/docs/profiles/security-review.md +3 -0
  69. package/dist-assets/docs/references/frontend-quality/landing-page-quality-checklist.md +11 -0
  70. package/dist-assets/docs/references/frontend-quality/product-copy-truthfulness.md +7 -0
  71. package/dist-assets/docs/references/frontend-quality/quality-failure-examples.md +20 -0
  72. package/dist-assets/docs/references/frontend-quality/visual-composition-patterns.md +10 -0
  73. package/dist-assets/docs/specs/runtime-operational-contract.md +39 -0
  74. package/dist-assets/docs/troubleshooting-guide.md +21 -0
  75. package/dist-assets/docs/visual-validation-guide.md +76 -0
  76. package/dist-assets/examples/README.md +10 -0
  77. package/dist-assets/examples/autopilot-cycle/00-CONTEXT.md +3 -0
  78. package/dist-assets/examples/autopilot-cycle/01-requirement.md +16 -0
  79. package/dist-assets/examples/autopilot-cycle/02-gate-a-check.md +23 -0
  80. package/dist-assets/examples/autopilot-cycle/03-orion-planning.md +20 -0
  81. package/dist-assets/examples/autopilot-cycle/04-astra-implementation.md +17 -0
  82. package/dist-assets/examples/autopilot-cycle/05-sage-validation.md +15 -0
  83. package/dist-assets/examples/autopilot-cycle/06-phoenix-healing.md +12 -0
  84. package/dist-assets/examples/autopilot-cycle/07-orchestration-report.md +18 -0
  85. package/dist-assets/examples/backend-api/00-CONTEXT.md +12 -0
  86. package/dist-assets/examples/backend-api/01-requirement.md +19 -0
  87. package/dist-assets/examples/backend-api/02-functional-spec.md +20 -0
  88. package/dist-assets/examples/backend-api/03-technical-plan.md +15 -0
  89. package/dist-assets/examples/backend-api/04-pr-breakdown.md +10 -0
  90. package/dist-assets/examples/backend-api/05-execution-handoff.md +13 -0
  91. package/dist-assets/examples/backend-api/06-validation-report.md +11 -0
  92. package/dist-assets/examples/backend-api/07-orchestration-report.md +7 -0
  93. package/dist-assets/examples/blocked-scenarios/00-CONTEXT.md +9 -0
  94. package/dist-assets/examples/blocked-scenarios/01-branch-gate-block.md +12 -0
  95. package/dist-assets/examples/blocked-scenarios/02-quality-gate-block.md +13 -0
  96. package/dist-assets/examples/blocked-scenarios/03-scope-creep-block.md +13 -0
  97. package/dist-assets/examples/blocked-scenarios/04-unblock-resolution.md +9 -0
  98. package/dist-assets/examples/blocked-scenarios/05-orchestration-decision-log.md +11 -0
  99. package/dist-assets/examples/bugfix-critical/00-CONTEXT.md +12 -0
  100. package/dist-assets/examples/bugfix-critical/01-bug-report.md +11 -0
  101. package/dist-assets/examples/bugfix-critical/02-diagnosis-hypothesis.md +11 -0
  102. package/dist-assets/examples/bugfix-critical/03-technical-plan.md +12 -0
  103. package/dist-assets/examples/bugfix-critical/04-implementation-handoff.md +8 -0
  104. package/dist-assets/examples/bugfix-critical/05-validation-report.md +10 -0
  105. package/dist-assets/examples/bugfix-critical/06-orchestration-report.md +7 -0
  106. package/dist-assets/examples/cli-package/00-CONTEXT.md +9 -0
  107. package/dist-assets/examples/cli-package/01-requirement.md +14 -0
  108. package/dist-assets/examples/cli-package/02-technical-spec.md +16 -0
  109. package/dist-assets/examples/cli-package/03-technical-plan.md +12 -0
  110. package/dist-assets/examples/cli-package/04-pr-breakdown.md +9 -0
  111. package/dist-assets/examples/cli-package/05-release-report.md +15 -0
  112. package/dist-assets/examples/docs-only-repo/01-requirement.md +31 -0
  113. package/dist-assets/examples/docs-only-repo/02-functional-spec.md +25 -0
  114. package/dist-assets/examples/docs-only-repo/03-technical-plan.md +21 -0
  115. package/dist-assets/examples/docs-only-repo/04-pr-breakdown.md +13 -0
  116. package/dist-assets/examples/docs-only-repo/05-execution-handoff.md +17 -0
  117. package/dist-assets/examples/docs-only-repo/06-validation-report.md +16 -0
  118. package/dist-assets/examples/docs-only-repo/README.md +26 -0
  119. package/dist-assets/examples/full-stack-checkout/00-CONTEXT.md +9 -0
  120. package/dist-assets/examples/full-stack-checkout/01-requirement.md +12 -0
  121. package/dist-assets/examples/full-stack-checkout/02-functional-spec.md +15 -0
  122. package/dist-assets/examples/full-stack-checkout/03-technical-plan.md +15 -0
  123. package/dist-assets/examples/full-stack-checkout/04-pr-breakdown.md +8 -0
  124. package/dist-assets/examples/full-stack-checkout/05-execution-handoff.md +14 -0
  125. package/dist-assets/examples/full-stack-checkout/06-validation-report.md +12 -0
  126. package/dist-assets/examples/healing-cycle/00-CONTEXT.md +15 -0
  127. package/dist-assets/examples/healing-cycle/01-broken-implementation.md +10 -0
  128. package/dist-assets/examples/healing-cycle/02-sage-fails.md +14 -0
  129. package/dist-assets/examples/healing-cycle/03-phoenix-diagnosis.md +17 -0
  130. package/dist-assets/examples/healing-cycle/04-phoenix-fix.md +18 -0
  131. package/dist-assets/examples/healing-cycle/05-sage-revalidation.md +12 -0
  132. package/dist-assets/examples/healing-cycle/06-orchestration-log.md +14 -0
  133. package/dist-assets/examples/infra-deploy/00-CONTEXT.md +9 -0
  134. package/dist-assets/examples/infra-deploy/01-operational-goal.md +12 -0
  135. package/dist-assets/examples/infra-deploy/02-architecture-specs.md +15 -0
  136. package/dist-assets/examples/infra-deploy/03-implementation-plan.md +14 -0
  137. package/dist-assets/examples/infra-deploy/04-step-breakdown.md +9 -0
  138. package/dist-assets/examples/infra-deploy/05-execution-handoff.md +13 -0
  139. package/dist-assets/examples/infra-deploy/06-operational-report.md +11 -0
  140. package/dist-assets/examples/multi-pr-release/00-CONTEXT.md +9 -0
  141. package/dist-assets/examples/multi-pr-release/01-requirement.md +13 -0
  142. package/dist-assets/examples/multi-pr-release/02-strategic-plan.md +13 -0
  143. package/dist-assets/examples/multi-pr-release/03-pr-breakdown.md +14 -0
  144. package/dist-assets/examples/multi-pr-release/04-release-plan.md +12 -0
  145. package/dist-assets/examples/multi-pr-release/05-orchestration-report.md +7 -0
  146. package/dist-assets/examples/nuxt-dashboard/01-requirement.md +81 -0
  147. package/dist-assets/examples/nuxt-dashboard/02-functional-spec.md +88 -0
  148. package/dist-assets/examples/nuxt-dashboard/03-technical-plan.md +76 -0
  149. package/dist-assets/examples/nuxt-dashboard/04-pr-breakdown.md +219 -0
  150. package/dist-assets/examples/nuxt-dashboard/05-execution-handoff.md +88 -0
  151. package/dist-assets/examples/nuxt-dashboard/06-validation-report.md +56 -0
  152. package/dist-assets/examples/nuxt-dashboard/07-orchestration-report.md +79 -0
  153. package/dist-assets/examples/nuxt-dashboard/README.md +52 -0
  154. package/dist-assets/examples/react-dashboard/01-requirement.md +84 -0
  155. package/dist-assets/examples/react-dashboard/02-functional-spec.md +88 -0
  156. package/dist-assets/examples/react-dashboard/03-technical-plan.md +76 -0
  157. package/dist-assets/examples/react-dashboard/04-pr-breakdown.md +218 -0
  158. package/dist-assets/examples/react-dashboard/05-execution-handoff.md +13 -0
  159. package/dist-assets/examples/react-dashboard/06-validation-report.md +12 -0
  160. package/dist-assets/examples/react-dashboard/07-orchestration-report.md +7 -0
  161. package/dist-assets/examples/react-dashboard/README.md +70 -0
  162. package/dist-assets/examples/refactoring-service/00-CONTEXT.md +9 -0
  163. package/dist-assets/examples/refactoring-service/01-debt-report.md +12 -0
  164. package/dist-assets/examples/refactoring-service/02-behavior-spec.md +11 -0
  165. package/dist-assets/examples/refactoring-service/03-technical-plan.md +13 -0
  166. package/dist-assets/examples/refactoring-service/04-pr-breakdown.md +9 -0
  167. package/dist-assets/examples/refactoring-service/05-execution-handoff.md +14 -0
  168. package/dist-assets/examples/refactoring-service/06-stability-report.md +12 -0
  169. package/dist-assets/examples/sdd-cycle/00-CONTEXT.md +12 -0
  170. package/dist-assets/examples/sdd-cycle/01-raw-request.md +13 -0
  171. package/dist-assets/examples/sdd-cycle/02-spec-creation.md +18 -0
  172. package/dist-assets/examples/sdd-cycle/03-spec-review.md +12 -0
  173. package/dist-assets/examples/sdd-cycle/04-technical-plan.md +16 -0
  174. package/dist-assets/examples/sdd-cycle/05-pr-breakdown.md +9 -0
  175. package/dist-assets/examples/sdd-cycle/06-spec-implement.md +13 -0
  176. package/dist-assets/examples/sdd-cycle/07-validation-against-spec.md +13 -0
  177. package/dist-assets/examples/wordpress-theme/01-requirement.md +29 -0
  178. package/dist-assets/examples/wordpress-theme/02-functional-spec.md +22 -0
  179. package/dist-assets/examples/wordpress-theme/03-technical-plan.md +22 -0
  180. package/dist-assets/examples/wordpress-theme/04-pr-breakdown.md +14 -0
  181. package/dist-assets/examples/wordpress-theme/05-execution-handoff.md +17 -0
  182. package/dist-assets/examples/wordpress-theme/06-validation-report.md +16 -0
  183. package/dist-assets/examples/wordpress-theme/README.md +32 -0
  184. package/{harness → dist-assets/harness}/handoffs/HANDOFF.template.md +2 -2
  185. package/{harness → dist-assets/harness}/workflows/agent-evaluation-checklist.md +5 -5
  186. package/{harness → dist-assets/harness}/workflows/implement-review-validate.md +24 -0
  187. package/{harness → dist-assets/harness}/workflows/multi-agent-handoff.md +4 -4
  188. package/{harness → dist-assets/harness}/workflows/planner-executor-workflow.md +5 -5
  189. package/{harness → dist-assets/harness}/workflows/requirement-to-pr.md +1 -1
  190. package/dist-assets/runbooks/agent-delegation-workflow.md +50 -0
  191. package/dist-assets/runbooks/apply-starter-to-real-project.md +45 -0
  192. package/dist-assets/runbooks/commands-cheatsheet.md +44 -0
  193. package/dist-assets/runbooks/how-to-use-skills.md +44 -0
  194. package/dist-assets/runbooks/private-spec-publication-safety.md +35 -0
  195. package/{runbooks → dist-assets/runbooks}/spec-driven-development.md +3 -6
  196. package/dist-assets/runbooks/tutorial-walkthroughs.md +23 -0
  197. package/dist-assets/runbooks/use-linear-for-operational-planning.md +45 -0
  198. package/dist-assets/runbooks/use-napkin-project-memory.md +33 -0
  199. package/dist-assets/skills/architecture/SKILL.md +166 -0
  200. package/dist-assets/skills/backend-development/SKILL.md +166 -0
  201. package/dist-assets/skills/deployment/SKILL.md +166 -0
  202. package/dist-assets/skills/design-principles/SKILL.md +166 -0
  203. package/dist-assets/skills/documentation/SKILL.md +171 -0
  204. package/dist-assets/skills/frontend-development/SKILL.md +225 -0
  205. package/dist-assets/skills/full-stack-development/SKILL.md +166 -0
  206. package/dist-assets/skills/optimize-tokens/SKILL.md +166 -0
  207. package/dist-assets/skills/pr-workflow/SKILL.md +166 -0
  208. package/dist-assets/skills/product-discovery/SKILL.md +166 -0
  209. package/dist-assets/skills/product-planning/SKILL.md +166 -0
  210. package/dist-assets/skills/project-memory/SKILL.md +166 -0
  211. package/dist-assets/skills/prompt-engineer/SKILL.md +166 -0
  212. package/dist-assets/skills/qa-workflow/SKILL.md +186 -0
  213. package/dist-assets/skills/refactoring/SKILL.md +166 -0
  214. package/dist-assets/skills/release-workflow/SKILL.md +166 -0
  215. package/dist-assets/skills/spec-driven-development/SKILL.md +166 -0
  216. package/dist-assets/skills/technical-leadership/SKILL.md +166 -0
  217. package/dist-assets/skills/ui-ux-design/SKILL.md +202 -0
  218. package/dist-assets/templates/.geminiignore.template +8 -0
  219. package/dist-assets/templates/CLAUDE.md.template +20 -0
  220. package/dist-assets/templates/CODEX.md.template +20 -0
  221. package/dist-assets/templates/GEMINI.md.template +20 -0
  222. package/dist-assets/templates/HANDOFF.template.md +45 -0
  223. package/dist-assets/templates/SPEC.template.md +38 -0
  224. package/dist-assets/templates/change-proposal.template.md +14 -0
  225. package/dist-assets/templates/owner-evidence/astra-implementation.json +10 -0
  226. package/dist-assets/templates/owner-evidence/phoenix-remediation.json +8 -0
  227. package/dist-assets/templates/owner-evidence/sage-revalidation.json +8 -0
  228. package/dist-assets/templates/owner-evidence/sage-validation.json +8 -0
  229. package/dist-assets/templates/specs/deep.md +48 -0
  230. package/dist-assets/templates/specs/standard.md +38 -0
  231. package/dist-assets/templates/specs/tiny.md +19 -0
  232. package/package.json +43 -47
  233. package/src/adapters/index.js +3 -0
  234. package/src/adapters/platforms/claude.js +126 -0
  235. package/src/adapters/platforms/codex.js +100 -0
  236. package/src/adapters/platforms/gemini.js +232 -0
  237. package/src/cli.js +114 -0
  238. package/src/commands/collect-evidence.js +61 -0
  239. package/src/commands/doctor.js +186 -0
  240. package/src/commands/execute.js +172 -0
  241. package/{packages/ai-workflow/src → src}/commands/init.js +119 -20
  242. package/src/commands/run.js +112 -0
  243. package/src/core/completion-contract.js +35 -0
  244. package/src/core/execution-planner.js +59 -0
  245. package/src/core/gates/branch-gate.js +146 -0
  246. package/src/core/handoff/handoff-engine.js +104 -0
  247. package/src/core/healing/cli-remediation-executor.js +151 -0
  248. package/src/core/healing/healer-engine.js +179 -0
  249. package/src/core/identity.js +43 -0
  250. package/{packages/ai-workflow/src → src}/core/install-plan.js +3 -3
  251. package/src/core/opencode-merge.js +149 -0
  252. package/{packages/ai-workflow/src → src}/core/package-assets.js +29 -10
  253. package/src/core/request-classifier.js +58 -0
  254. package/src/core/runtime/opencode-adapter.js +94 -0
  255. package/src/core/sdd/validator.js +67 -0
  256. package/src/core/statuses.js +29 -0
  257. package/src/core/symlink-layout.js +93 -0
  258. package/src/core/templates.js +221 -0
  259. package/src/core/validation/canonical-finalization.js +43 -0
  260. package/src/core/validation/evidence-collector.js +109 -0
  261. package/src/core/validation/quality-guard.js +243 -0
  262. package/src/core/workflow-profiles.js +107 -0
  263. package/src/core/workflow-state-machine.js +46 -0
  264. package/.agents/napkin.md +0 -89
  265. package/.agents/skills/backend-implementer/SKILL.md +0 -490
  266. package/.agents/skills/build-and-validate/SKILL.md +0 -442
  267. package/.agents/skills/deploy-engineer/SKILL.md +0 -541
  268. package/.agents/skills/docs-writer/SKILL.md +0 -430
  269. package/.agents/skills/frontend-implementer/SKILL.md +0 -488
  270. package/.agents/skills/interface-design/SKILL.md +0 -428
  271. package/.agents/skills/interface-design/references/critique.md +0 -67
  272. package/.agents/skills/interface-design/references/example.md +0 -86
  273. package/.agents/skills/interface-design/references/principles.md +0 -235
  274. package/.agents/skills/interface-design/references/validation.md +0 -48
  275. package/.agents/skills/minimal-context/SKILL.md +0 -177
  276. package/.agents/skills/napkin/SKILL.md +0 -84
  277. package/.agents/skills/opencode-agent-design/SKILL.md +0 -77
  278. package/.agents/skills/playwright-cli/SKILL.md +0 -62
  279. package/.agents/skills/pr-orchestrator/SKILL.md +0 -366
  280. package/.agents/skills/product-manager/SKILL.md +0 -519
  281. package/.agents/skills/seo-audit/SKILL.md +0 -176
  282. package/.agents/skills/stack-variant-creator/SKILL.md +0 -265
  283. package/.agents/skills/tech-lead/SKILL.md +0 -453
  284. package/.agents/skills/tester/SKILL.md +0 -399
  285. package/.agents/skills/token-economy/SKILL.md +0 -137
  286. package/.agents/skills/vue-nuxt/SKILL.md +0 -102
  287. package/.agents/skills/wordpress-engineer/SKILL.md +0 -75
  288. package/.codex/prompts/README.md +0 -44
  289. package/.codex/prompts/autopilot.md +0 -50
  290. package/.codex/prompts/deploy.md +0 -33
  291. package/.codex/prompts/execute-selected-pr.md +0 -35
  292. package/.codex/prompts/fix-issue.md +0 -34
  293. package/.codex/prompts/minimal-context-mode.md +0 -55
  294. package/.codex/prompts/orchestrate-next.md +0 -33
  295. package/.codex/prompts/plan-from-requirement.md +0 -37
  296. package/.codex/prompts/review-implementation.md +0 -33
  297. package/.codex/prompts/roadmap-audit.md +0 -22
  298. package/.codex/prompts/specs/create-spec-from-requirement.md +0 -26
  299. package/.codex/prompts/specs/review-spec.md +0 -29
  300. package/.codex/prompts/specs/spec-to-pr-breakdown.md +0 -23
  301. package/.codex/prompts/specs/spec-to-technical-plan.md +0 -28
  302. package/.codex/prompts/start-project.md +0 -29
  303. package/.codex/prompts/token-economy-mode.md +0 -48
  304. package/.codex/prompts/validate-work.md +0 -28
  305. package/checklists/change-spec-readiness-checklist.md +0 -34
  306. package/docs/full-documentation.md +0 -661
  307. package/docs/setup-codex-opencode.md +0 -313
  308. package/harness/README.md +0 -106
  309. package/opencode/README.md +0 -84
  310. package/opencode/agents/README.md +0 -113
  311. package/opencode/agents/atlas.md +0 -127
  312. package/opencode/agents/discovery.md +0 -61
  313. package/opencode/agents/fixer.md +0 -51
  314. package/opencode/agents/implementer.md +0 -61
  315. package/opencode/agents/orchestrator.md +0 -145
  316. package/opencode/agents/planner.md +0 -60
  317. package/opencode/agents/prompt-engineer.md +0 -50
  318. package/opencode/agents/release-manager.md +0 -50
  319. package/opencode/agents/reviewer.md +0 -51
  320. package/opencode/agents/spec-engineer.md +0 -85
  321. package/opencode/agents/validator.md +0 -50
  322. package/opencode/agents/wordpress-engineer.md +0 -49
  323. package/opencode/commands/README.md +0 -48
  324. package/opencode/commands/autopilot.md +0 -50
  325. package/opencode/commands/deploy.md +0 -35
  326. package/opencode/commands/execute.md +0 -47
  327. package/opencode/commands/orchestrate.md +0 -37
  328. package/opencode/commands/plan.md +0 -39
  329. package/opencode/commands/review.md +0 -33
  330. package/opencode/commands/roadmap-audit.md +0 -30
  331. package/opencode/commands/ship.md +0 -48
  332. package/opencode/commands/specs/create-spec-from-request.md +0 -27
  333. package/opencode/commands/specs/create-spec-from-requirement.md +0 -25
  334. package/opencode/commands/specs/review-spec.md +0 -26
  335. package/opencode/commands/specs/spec-to-pr-breakdown.md +0 -19
  336. package/opencode/commands/specs/spec-to-tasks.md +0 -26
  337. package/opencode/commands/specs/spec-to-technical-plan.md +0 -27
  338. package/opencode/commands/start.md +0 -45
  339. package/opencode/commands/token-economy.md +0 -29
  340. package/opencode/commands/validate.md +0 -33
  341. package/opencode.jsonc +0 -235
  342. package/packages/ai-workflow/README.md +0 -82
  343. package/packages/ai-workflow/src/cli.js +0 -70
  344. package/packages/ai-workflow/src/commands/codex.js +0 -37
  345. package/packages/ai-workflow/src/commands/doctor.js +0 -168
  346. package/packages/ai-workflow/src/commands/guide.js +0 -194
  347. package/packages/ai-workflow/src/core/opencode-merge.js +0 -172
  348. package/packages/ai-workflow/src/core/symlink-layout.js +0 -54
  349. package/packages/ai-workflow/src/core/templates.js +0 -276
  350. package/runbooks/agent-delegation-workflow.md +0 -111
  351. package/runbooks/apply-starter-to-real-project.md +0 -445
  352. package/runbooks/commands-cheatsheet.md +0 -71
  353. package/runbooks/how-to-use-skills.md +0 -713
  354. package/runbooks/quick-start-guide.md +0 -213
  355. package/runbooks/tutorial-walkthroughs.md +0 -416
  356. package/runbooks/use-linear-for-operational-planning.md +0 -185
  357. package/runbooks/use-napkin-project-memory.md +0 -77
  358. package/templates/AGENTS.template.md +0 -397
  359. package/templates/DESIGN.template.md +0 -484
  360. package/templates/PR-PLAN.template.md +0 -172
  361. package/templates/README.template.md +0 -293
  362. package/templates/REQUIREMENT.template.md +0 -165
  363. package/templates/SPEC.template.md +0 -397
  364. package/templates/TECH-PLAN.template.md +0 -244
  365. package/templates/change-proposal.template.md +0 -97
  366. /package/{checklists/spec-readiness-checklist.md → dist-assets/docs/policies/SPEC_READINESS.md} +0 -0
  367. /package/{prompts → dist-assets/prompts}/00-bootstrap-project.md +0 -0
  368. /package/{prompts → dist-assets/prompts}/01-create-requirement.md +0 -0
  369. /package/{prompts → dist-assets/prompts}/02-create-spec.md +0 -0
  370. /package/{prompts → dist-assets/prompts}/03-create-tech-plan.md +0 -0
  371. /package/{prompts → dist-assets/prompts}/04-breakdown-prs.md +0 -0
  372. /package/{prompts → dist-assets/prompts}/05-implement-pr.md +0 -0
  373. /package/{prompts → dist-assets/prompts}/06-review-and-fix.md +0 -0
  374. /package/{prompts → dist-assets/prompts}/07-apply-design.md +0 -0
  375. /package/{prompts → dist-assets/prompts}/08-validate.md +0 -0
  376. /package/{prompts → dist-assets/prompts}/09-deploy.md +0 -0
  377. /package/{prompts → dist-assets/prompts}/commands/implement.md +0 -0
  378. /package/{prompts → dist-assets/prompts}/commands/requirement.md +0 -0
  379. /package/{prompts → dist-assets/prompts}/commands/spec.md +0 -0
  380. /package/{prompts → dist-assets/prompts}/commands/tech-plan.md +0 -0
  381. /package/{prompts → dist-assets/prompts}/commands/validate.md +0 -0
  382. /package/{runbooks → dist-assets/runbooks}/branch-cleanup.md +0 -0
  383. /package/{runbooks → dist-assets/runbooks}/deploy-checklist.md +0 -0
  384. /package/{runbooks → dist-assets/runbooks}/publication-readiness-checklist.md +0 -0
  385. /package/{runbooks → dist-assets/runbooks}/publish-package-checklist.md +0 -0
  386. /package/{runbooks → dist-assets/runbooks}/team-governance-pr-readiness.md +0 -0
  387. /package/{runbooks → dist-assets/runbooks}/validate-starter-in-real-project.md +0 -0
  388. /package/{runbooks → dist-assets/runbooks}/validation-checklist.md +0 -0
  389. /package/{schemas → dist-assets/schemas}/README.md +0 -0
  390. /package/{schemas → dist-assets/schemas}/functional-spec.schema.json +0 -0
  391. /package/{schemas → dist-assets/schemas}/handoff.schema.json +0 -0
  392. /package/{schemas → dist-assets/schemas}/pr-breakdown.schema.json +0 -0
  393. /package/{schemas → dist-assets/schemas}/requirement.schema.json +0 -0
  394. /package/{schemas → dist-assets/schemas}/technical-plan.schema.json +0 -0
  395. /package/{schemas → dist-assets/schemas}/validation-report.schema.json +0 -0
  396. /package/{packages/ai-workflow/src → src}/core/backup.js +0 -0
  397. /package/{packages/ai-workflow/src → src}/core/filesystem.js +0 -0
@@ -0,0 +1,232 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { COMPLETION_STATUS_TEXT } from "../../core/statuses.js";
4
+
5
+ /**
6
+ * Maps OpenCode agent names to primary agent roles.
7
+ * @type {Record<string, string>}
8
+ */
9
+ const PERSONA_MAPPING = {
10
+ "atlas": "Atlas",
11
+ "orion": "Orion",
12
+ "sage": "Sage",
13
+ "nexus": "Nexus",
14
+ "astra": "Astra",
15
+ "sage-validation": "Sage",
16
+ "orion-release": "Orion",
17
+ "orion-deploy": "Orion",
18
+ "nexus-discovery": "Nexus",
19
+ "phoenix": "Phoenix"
20
+ };
21
+
22
+ /**
23
+ * Gemini Adapter - Transforms OpenCode .md to Gemini Skill format and manages .gemini/ integration.
24
+ */
25
+ export class GeminiAdapter {
26
+ constructor({ cwd }) {
27
+ this.cwd = cwd;
28
+ }
29
+
30
+ /**
31
+ * Transforms an OpenCode agent or specialized skill file to a Gemini Skill.
32
+ * @param {string} filePath - Path to the source .md file.
33
+ * @returns {Promise<{content: string, name: string}>}
34
+ */
35
+ async transform(filePath) {
36
+ const content = await fs.readFile(filePath, "utf8");
37
+ const fileName = path.basename(filePath, ".md") === "SKILL"
38
+ ? path.basename(path.dirname(filePath))
39
+ : path.basename(filePath, ".md");
40
+
41
+ const persona = PERSONA_MAPPING[fileName.toLowerCase()] || "Astra";
42
+
43
+ // Check if already has frontmatter
44
+ if (content.trim().startsWith("---")) {
45
+ return { content, name: fileName };
46
+ }
47
+
48
+ // Extract description from the first paragraph after the title
49
+ const descriptionMatch = content.match(/^# .*\n\n(.*)/m);
50
+ const description = descriptionMatch ? descriptionMatch[1].trim() : `Specialized agent for ${fileName}.`;
51
+
52
+ const skillContent = `---
53
+ name: ${fileName}
54
+ description: ${description}
55
+ ---
56
+ # ${persona} Persona
57
+
58
+ ${content}
59
+
60
+ ## Completion Contract (Mandatory)
61
+ Every task completion MUST provide the following payload:
62
+ 1. **Status**: ${COMPLETION_STATUS_TEXT}
63
+ 2. **Scope reviewed**: Brief summary of what was analyzed.
64
+ 3. **Findings**: Evidence-based discoveries.
65
+ 4. **Files affected**: List of all concrete paths modified or created.
66
+ 5. **Validation/evidence**: Commands run and their results.
67
+ 6. **Risks/notes**: Any caveats or technical debt introduced.
68
+ 7. **Required manager action**: Clear next step for the orchestrator.
69
+ 8. **Can manager continue**: [yes/no]
70
+ `;
71
+
72
+ return {
73
+ content: skillContent,
74
+ name: fileName
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Deploys transformed skills and agents to their respective directories.
80
+ * Also orchestrates the .gemini/ native integration.
81
+ */
82
+ async deploy(transformedItems, installRoot = ".ai-workflow") {
83
+ const agentsDir = path.join(this.cwd, installRoot, "opencode/agents");
84
+ const skillsDir = path.join(this.cwd, installRoot, "opencode/skills");
85
+ const geminiDir = path.join(this.cwd, ".gemini");
86
+
87
+ await fs.mkdir(agentsDir, { recursive: true });
88
+ await fs.mkdir(skillsDir, { recursive: true });
89
+
90
+ for (const item of transformedItems) {
91
+ const isAgent = PERSONA_MAPPING[item.name.toLowerCase()];
92
+ const targetDir = isAgent ? agentsDir : path.join(skillsDir, item.name);
93
+ const fileName = isAgent ? `${item.name}.md` : "SKILL.md";
94
+
95
+ const absoluteTargetDir = isAgent ? agentsDir : targetDir;
96
+ await fs.mkdir(absoluteTargetDir, { recursive: true });
97
+ await fs.writeFile(path.join(absoluteTargetDir, fileName), item.content);
98
+ }
99
+
100
+ // Deploy native Gemini CLI extensions (.gemini/)
101
+ await this.deployNativeExtensions(installRoot);
102
+
103
+ // Also deploy root GEMINI.md if it doesn't exist
104
+ await this.deployInstructions();
105
+ }
106
+
107
+ /**
108
+ * Orchestrates the .gemini/ directory with copies of .ai-workflow/ assets.
109
+ * Using hard copies instead of symlinks ensures native discovery across all platforms.
110
+ */
111
+ async deployNativeExtensions(installRoot = ".ai-workflow") {
112
+ const geminiDir = path.join(this.cwd, ".gemini");
113
+ const geminiAgents = path.join(geminiDir, "agents");
114
+ const geminiSkills = path.join(geminiDir, "skills");
115
+ const geminiCommands = path.join(geminiDir, "commands");
116
+
117
+ await fs.mkdir(geminiAgents, { recursive: true });
118
+ await fs.mkdir(geminiSkills, { recursive: true });
119
+ await fs.mkdir(geminiCommands, { recursive: true });
120
+
121
+ // 1. Copy Agents
122
+ const sourceAgentsDir = path.join(this.cwd, installRoot, "opencode/agents");
123
+ const agentFiles = await fs.readdir(sourceAgentsDir).catch(() => []);
124
+ for (const file of agentFiles) {
125
+ if (!file.endsWith(".md")) continue;
126
+ const content = await fs.readFile(path.join(sourceAgentsDir, file), "utf8");
127
+ await fs.writeFile(path.join(geminiAgents, file), content);
128
+ }
129
+
130
+ // 2. Copy Skills
131
+ const sourceSkillsDir = path.join(this.cwd, installRoot, "opencode/skills");
132
+ const skillFolders = await fs.readdir(sourceSkillsDir).catch(() => []);
133
+ for (const folder of skillFolders) {
134
+ const skillSource = path.join(sourceSkillsDir, folder, "SKILL.md");
135
+ if (await this.exists(skillSource)) {
136
+ await fs.mkdir(path.join(geminiSkills, folder), { recursive: true });
137
+ const content = await fs.readFile(skillSource, "utf8");
138
+ await fs.writeFile(path.join(geminiSkills, folder, "SKILL.md"), content);
139
+ }
140
+ }
141
+
142
+ // 3. Copy Commands (from dist-assets/commands)
143
+ const sourceCommandsDir = path.join(this.cwd, installRoot, "opencode/commands");
144
+ if (await this.exists(sourceCommandsDir)) {
145
+ const commandFiles = await fs.readdir(sourceCommandsDir).catch(() => []);
146
+ for (const file of commandFiles) {
147
+ if (!file.endsWith(".md") && !file.endsWith(".toml")) continue;
148
+ const content = await fs.readFile(path.join(sourceCommandsDir, file), "utf8");
149
+ await fs.writeFile(path.join(geminiCommands, file), content);
150
+ }
151
+ }
152
+
153
+ // 4. Inject project settings.json
154
+ const settingsPath = path.join(geminiDir, "settings.json");
155
+ if (!(await this.exists(settingsPath))) {
156
+ const settings = {
157
+ model: { name: "auto" },
158
+ ui: { theme: "Ayu" }
159
+ };
160
+ await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2));
161
+ }
162
+ }
163
+
164
+ async exists(p) {
165
+ try {
166
+ await fs.access(p);
167
+ return true;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+
173
+ /**
174
+ * Deploys the main GEMINI.md and .geminiignore instructions to the project root.
175
+ */
176
+ async deployInstructions() {
177
+ const targetPath = path.join(this.cwd, "GEMINI.md");
178
+ const ignorePath = path.join(this.cwd, ".geminiignore");
179
+
180
+ // Deploy GEMINI.md if it doesn't exist
181
+ try {
182
+ await fs.access(targetPath);
183
+ } catch {
184
+ const instructions = `# AI Workflow Kit - Engineering Governance
185
+
186
+ ## Mandate: Atlas Authority Protocol
187
+ All architectural changes must align with the specifications issued by the **Specification Authority** (./specs).
188
+
189
+ ## Ternary Architecture
190
+ - **Root:** Orchestration and config.
191
+ - **.ai-workflow/:** Implementation (The Muscle).
192
+ - **./specs:** Specifications (The Brain).
193
+
194
+ ## Branch Gates
195
+ - **main Branch:** READ-ONLY.
196
+ - **Validation:** Merges require successful observed validation; full/release workflows may persist EVIDENCE.json.
197
+
198
+ ## Primary Agents
199
+ - **Atlas (Orchestrator)**
200
+ - **Orion (Strategist)**
201
+ - **Sage (Auditor)**
202
+ - **Nexus (Spec Architect)**
203
+ - **Astra (Developer)**
204
+ - **Phoenix (Healer)**
205
+
206
+ ## Operational Preferences
207
+ - Use \`token-economy\` and \`minimal-context\` skills.
208
+ - **Native Discovery**: This project uses workspace-specific extensions in \`.gemini/\`.
209
+ - **Workflow Entry**: Use \`/atlas\` to begin any task.
210
+ `;
211
+ await fs.writeFile(targetPath, instructions);
212
+ }
213
+
214
+ // Deploy .geminiignore if it doesn't exist
215
+ try {
216
+ await fs.access(ignorePath);
217
+ } catch {
218
+ const ignoreContent = `.ai-workflow/
219
+ .ai-workflow-backups/
220
+ node_modules/
221
+ .git/
222
+ EVIDENCE.json
223
+ *.tgz
224
+ *.zip
225
+ *.tar
226
+ .gemini/tmp/
227
+ .gemini/history/
228
+ `;
229
+ await fs.writeFile(ignorePath, ignoreContent);
230
+ }
231
+ }
232
+ }
package/src/cli.js ADDED
@@ -0,0 +1,114 @@
1
+ import { getPackageVersion } from "./core/package-assets.js";
2
+ import { runInit } from "./commands/init.js";
3
+ import { runDoctor } from "./commands/doctor.js";
4
+ import { runCollectEvidence } from "./commands/collect-evidence.js";
5
+ import { runMasterOrchestrator } from "./commands/run.js";
6
+ import { runExecute } from "./commands/execute.js";
7
+
8
+ function printHelp() {
9
+ console.log(`ai-workflow
10
+
11
+ Usage:
12
+ ai-workflow execute "<request>" [--task=<slug>] [--request="<request>"]
13
+ ai-workflow run --spec-path=<path>
14
+ ai-workflow init [--yes] [--force] [--dry-run] [--no-install] [--no-overwrite] [--gemini] [--claude] [--codex] [--profile=<profile>]
15
+ ai-workflow collect-evidence [--task=<slug>] [--mode=<quick|standard|full>] [--dry-run]
16
+ ai-workflow doctor
17
+
18
+ Commands:
19
+ execute Orchestrate execution of a natural request through the state machine
20
+ run Proportionate orchestrator with branch safety, validation, and bounded remediation
21
+ init Install AI workflow defaults (OpenCode). --profile=standard (default) or --profile=full (adds examples)
22
+ collect-evidence Run observed project validation; persists EVIDENCE.json only for full mode
23
+ doctor Verify local ai-workflow installation
24
+ `);
25
+ }
26
+
27
+ function parseFlags(args) {
28
+ const specPathArg = args.find((arg) => arg.startsWith("--spec-path="));
29
+ const profileEqArg = args.find((arg) => arg.startsWith("--profile="));
30
+ const taskArg = args.find((arg) => arg.startsWith("--task="));
31
+ const modeArg = args.find((arg) => arg.startsWith("--mode="));
32
+ const requestArg = args.find((arg) => arg.startsWith("--request="));
33
+ const profileIdx = args.indexOf("--profile");
34
+ const profileVal = profileEqArg
35
+ ? profileEqArg.replace("--profile=", "")
36
+ : profileIdx >= 0 && profileIdx + 1 < args.length && !args[profileIdx + 1].startsWith("--")
37
+ ? args[profileIdx + 1]
38
+ : undefined;
39
+
40
+ return {
41
+ yes: args.includes("--yes"),
42
+ force: args.includes("--force"),
43
+ dryRun: args.includes("--dry-run"),
44
+ noInstall: args.includes("--no-install"),
45
+ noOverwrite: args.includes("--no-overwrite"),
46
+ gemini: args.includes("--gemini"),
47
+ claude: args.includes("--claude"),
48
+ codex: args.includes("--codex"),
49
+ "dev-mode": args.includes("--dev-mode"),
50
+ specPath: specPathArg ? specPathArg.replace("--spec-path=", "") : undefined,
51
+ profile: profileVal || undefined,
52
+ taskSlug: taskArg ? taskArg.replace("--task=", "") : undefined,
53
+ mode: modeArg ? modeArg.replace("--mode=", "") : undefined,
54
+ request: requestArg ? requestArg.replace("--request=", "") : undefined
55
+ };
56
+ }
57
+
58
+
59
+ export async function runCli(args) {
60
+ const [command] = args;
61
+
62
+ if (command === "--version" || command === "-v") {
63
+ console.log(getPackageVersion() || "unknown");
64
+ return;
65
+ }
66
+
67
+ if (!command || command === "--help" || command === "-h") {
68
+ printHelp();
69
+ return;
70
+ }
71
+
72
+ if (command === "execute") {
73
+ const flags = parseFlags(args.slice(1));
74
+ const positionals = args.slice(1).filter((arg) => !arg.startsWith("-"));
75
+ const request = flags.request || positionals.join(" ");
76
+ await runExecute({
77
+ cwd: process.cwd(),
78
+ naturalRequest: request,
79
+ override: args.includes("--override") ? "authorized-override-token" : undefined,
80
+ taskSlug: flags.taskSlug
81
+ });
82
+ return;
83
+ }
84
+
85
+ if (command === "run") {
86
+ await runMasterOrchestrator({
87
+ cwd: process.cwd(),
88
+ ...parseFlags(args.slice(1))
89
+ });
90
+ return;
91
+ }
92
+
93
+ if (command === "init") {
94
+ await runInit({
95
+ cwd: process.cwd(),
96
+ ...parseFlags(args.slice(1))
97
+ });
98
+ return;
99
+ }
100
+
101
+ if (command === "collect-evidence") {
102
+ const flags = parseFlags(args.slice(1));
103
+ if (flags.mode && !["quick", "standard", "full"].includes(flags.mode)) throw new Error("--mode must be quick, standard, or full");
104
+ await runCollectEvidence({ cwd: process.cwd(), taskSlug: flags.taskSlug, mode: flags.mode, dryRun: flags.dryRun });
105
+ return;
106
+ }
107
+
108
+ if (command === "doctor") {
109
+ await runDoctor({ cwd: process.cwd() });
110
+ return;
111
+ }
112
+
113
+ throw new Error(`unknown command: ${command}`);
114
+ }
@@ -0,0 +1,61 @@
1
+ import { EvidenceCollector } from "../core/validation/evidence-collector.js";
2
+ import { QualityGuard } from "../core/validation/quality-guard.js";
3
+ import { buildDeliverySummary, formatDeliverySummary } from "../core/validation/canonical-finalization.js";
4
+ import fs from "node:fs/promises";
5
+ import path from "node:path";
6
+
7
+ function isNoOpScript(script = "") {
8
+ const value = String(script).trim().toLowerCase();
9
+ return /^(echo\b|true$|exit\s+0$|node\s+-e\s+["']?console\.log)/.test(value) || value.includes("tests-pass");
10
+ }
11
+
12
+ function addScriptTask(tasks, scripts, name, command, { rejectNoOp = false } = {}) {
13
+ const script = scripts[name];
14
+ if (!script) return;
15
+ if (!rejectNoOp && name === "test" && isNoOpScript(script)) return;
16
+ if (rejectNoOp && isNoOpScript(script)) {
17
+ tasks.push({ name, command, kind: name === "test" ? "test" : name, presetStatus: "FAIL_QUALITY_GATE", summary: `Configured ${name} script is a no-op: ${script}` });
18
+ return;
19
+ }
20
+ tasks.push({ name, command, kind: name === "test" ? "test" : name });
21
+ }
22
+
23
+ function isManagedValidationPath(file = "") {
24
+ return /(^|\/)(node_modules|vendor|dist|coverage|\.cache)(\/|$)/.test(String(file).replaceAll("\\", "/"));
25
+ }
26
+
27
+ export async function runCollectEvidence({ cwd, exitOnError = true, taskSlug = null, mode = null, dryRun = false, profile = "generic", branchRecovery = "NOT_RECORDED" }) {
28
+ const tasks = [];
29
+ const qualityGuard = new QualityGuard({ cwd, taskSlug, mode });
30
+ try {
31
+ const pkg = JSON.parse(await fs.readFile(path.join(cwd, "package.json"), "utf8"));
32
+ const scripts = pkg.scripts || {};
33
+ const executableBehavior = await qualityGuard.hasExecutableBehaviorChanges();
34
+ addScriptTask(tasks, scripts, "lint", "npm run lint");
35
+ addScriptTask(tasks, scripts, "test", "npm test", { rejectNoOp: executableBehavior });
36
+ addScriptTask(tasks, scripts, "build", "npm run build");
37
+ addScriptTask(tasks, scripts, "typecheck", "npm run typecheck");
38
+ if (scripts.validate && !String(scripts.validate).includes("ai-workflow collect-evidence")) addScriptTask(tasks, scripts, "validate", "npm run validate");
39
+
40
+ const changed = qualityGuard.getChangedFiles().filter((file) => !isManagedValidationPath(file));
41
+ const hasTs = changed.some((file) => /\.(ts|tsx)$/.test(file)) || await fs.access(path.join(cwd, "tsconfig.json")).then(() => true).catch(() => false);
42
+ if (hasTs && !scripts.typecheck) {
43
+ tasks.push({ name: "typecheck", command: "npm run typecheck", kind: "typecheck", presetStatus: "FAIL_QUALITY_GATE", summary: "TypeScript detected but no typecheck script is configured." });
44
+ }
45
+ } catch {
46
+ // Non-Node projects can still supply validation through project-specific commands.
47
+ }
48
+
49
+ const persist = !dryRun && mode === "full";
50
+ const collector = new EvidenceCollector({ cwd, timeout: 60000, taskSlug, mode, profile, branchRecovery });
51
+ const evidence = await collector.collect(tasks, { writeArtifact: persist });
52
+ const summary = buildDeliverySummary({ evidence });
53
+
54
+ console.log("\n--- Delivery Summary ---");
55
+ console.log(formatDeliverySummary(summary));
56
+ console.log(persist ? "\nArtifact: EVIDENCE.json" : "\nArtifact: NOT_REQUIRED for quick/standard mode");
57
+ console.log(`Commands processed: ${evidence.commands.length}\n`);
58
+
59
+ if (evidence.status === "BLOCKED" && exitOnError) process.exit(1);
60
+ return evidence;
61
+ }
@@ -0,0 +1,186 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { exists, readJson, readJsonc } from "../core/filesystem.js";
4
+
5
+ const REQUIRED_FILES = [
6
+ ".ai-workflow",
7
+ "opencode/README.md"
8
+ ];
9
+
10
+ async function isSymlink(filePath) {
11
+ try {
12
+ const stat = await fs.lstat(filePath);
13
+ return stat.isSymbolicLink();
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ export async function runDoctor({ cwd }) {
20
+ let hasFailure = false;
21
+ let hasWarning = false;
22
+ let managedBlocks = [];
23
+
24
+ console.log("Doctor report:");
25
+
26
+ for (const relativePath of REQUIRED_FILES) {
27
+ const ok = await exists(path.join(cwd, relativePath));
28
+
29
+ if (ok) {
30
+ console.log(`PASS ${relativePath}`);
31
+ } else {
32
+ hasFailure = true;
33
+ console.log(`FAIL ${relativePath} missing`);
34
+ }
35
+ }
36
+
37
+ const configPathV2 = path.join(cwd, ".ai-workflow/config.json");
38
+ const configPathLegacy = path.join(cwd, ".ai-workflow.json");
39
+ let configPath = null;
40
+
41
+ if (await exists(configPathV2)) {
42
+ configPath = configPathV2;
43
+ } else if (await exists(configPathLegacy)) {
44
+ configPath = configPathLegacy;
45
+ }
46
+
47
+ if (configPath) {
48
+ try {
49
+ const config = await readJson(configPath);
50
+
51
+ if (config.installMode === "project-local" || config.mode === "standalone") {
52
+ console.log("PASS install mode is project-local/standalone");
53
+ } else {
54
+ hasWarning = true;
55
+ console.log(`WARN install mode is not project-local/standalone in ${path.basename(configPath)}`);
56
+ }
57
+
58
+ if (config.profile) {
59
+ console.log(`PASS profile detected: ${config.profile}`);
60
+ } else {
61
+ hasWarning = true;
62
+ console.log(`WARN profile is missing in ${path.basename(configPath)}`);
63
+ }
64
+
65
+ if (config.runtime) {
66
+ console.log(`PASS runtime: ${config.runtime}`);
67
+ } else {
68
+ console.log(`NOTE runtime field not present in ${path.basename(configPath)}`);
69
+ }
70
+
71
+ if (Array.isArray(config.managedBlocks)) {
72
+ managedBlocks = config.managedBlocks;
73
+ } else {
74
+ console.log(`NOTE managedBlocks not present in ${path.basename(configPath)} (legacy field)`);
75
+ }
76
+
77
+ if (Array.isArray(config.managedFiles)) {
78
+ for (const relativePath of config.managedFiles) {
79
+ const fileExists = await exists(path.join(cwd, relativePath));
80
+ if (!fileExists) {
81
+ hasWarning = true;
82
+ console.log(`WARN managed file missing: ${relativePath}`);
83
+ }
84
+ }
85
+ }
86
+
87
+ if (Array.isArray(config.managedLinks)) {
88
+ for (const relativePath of config.managedLinks) {
89
+ const absolutePath = path.join(cwd, relativePath);
90
+ const linkExists = await exists(absolutePath);
91
+ if (!linkExists) {
92
+ hasWarning = true;
93
+ console.log(`WARN managed link missing: ${relativePath}`);
94
+ continue;
95
+ }
96
+
97
+ const isLink = await isSymlink(absolutePath);
98
+ if (!isLink) {
99
+ hasWarning = true;
100
+ console.log(`WARN managed link is not a symlink: ${relativePath}`);
101
+ }
102
+ }
103
+ }
104
+ } catch {
105
+ hasFailure = true;
106
+ console.log(`FAIL ${path.basename(configPath)} is not valid JSON`);
107
+ }
108
+ }
109
+
110
+ const opencodePath = path.join(cwd, "opencode.jsonc");
111
+ if (!(await exists(opencodePath))) {
112
+ hasFailure = true;
113
+ console.log("FAIL opencode.jsonc missing");
114
+ } else {
115
+ try {
116
+ const opencodeConfig = await readJsonc(opencodePath);
117
+ console.log("PASS opencode.jsonc is valid JSONC");
118
+
119
+ const needsAgentDefault = managedBlocks.includes("opencode.jsonc:agent.default");
120
+ if (!needsAgentDefault || opencodeConfig.agent?.default) {
121
+ console.log("PASS opencode agent.default available");
122
+ } else {
123
+ hasFailure = true;
124
+ console.log("FAIL opencode agent.default missing");
125
+ }
126
+
127
+ const requiredCommands = managedBlocks
128
+ .filter((block) => block.startsWith("opencode.jsonc:command."))
129
+ .map((block) => block.replace("opencode.jsonc:command.", ""));
130
+
131
+ if (requiredCommands.length === 0) {
132
+ console.log("PASS no managed opencode commands required");
133
+ } else {
134
+ const missingCommands = requiredCommands.filter((command) => !opencodeConfig.command?.[command]);
135
+ if (missingCommands.length === 0) {
136
+ console.log(`PASS opencode managed commands available (${requiredCommands.length})`);
137
+ } else {
138
+ hasFailure = true;
139
+ console.log(`FAIL opencode command entries missing: ${missingCommands.join(", ")}`);
140
+ }
141
+ }
142
+
143
+ const requiredAgents = managedBlocks
144
+ .filter((block) => block.startsWith("opencode.jsonc:agent.") && !block.endsWith(".default"))
145
+ .map((block) => block.replace("opencode.jsonc:agent.", ""));
146
+
147
+ if (requiredAgents.length === 0) {
148
+ console.log("PASS no managed opencode agents required");
149
+ } else {
150
+ const missingAgents = requiredAgents.filter((agent) => !opencodeConfig.agent?.[agent]);
151
+ if (missingAgents.length === 0) {
152
+ console.log(`PASS opencode managed agents available (${requiredAgents.length})`);
153
+ } else {
154
+ hasFailure = true;
155
+ console.log(`FAIL opencode agent entries missing: ${missingAgents.join(", ")}`);
156
+ }
157
+ }
158
+ } catch {
159
+ hasFailure = true;
160
+ console.log("FAIL opencode.jsonc is not valid JSONC");
161
+ }
162
+ }
163
+
164
+ const packageJsonPath = path.join(cwd, "package.json");
165
+ if (await exists(packageJsonPath)) {
166
+ try {
167
+ const packageJson = await readJson(packageJsonPath);
168
+ const scripts = packageJson.scripts ?? {};
169
+
170
+ if (!scripts.validate) {
171
+ hasWarning = true;
172
+ console.log("WARN package.json has no validate script");
173
+ }
174
+ } catch {
175
+ hasFailure = true;
176
+ console.log("FAIL package.json is not valid JSON");
177
+ }
178
+ }
179
+
180
+ const finalStatus = hasFailure ? "FAIL" : hasWarning ? "PASS_WITH_NOTES" : "PASS";
181
+ console.log(`Final status: ${finalStatus}`);
182
+
183
+ if (hasFailure) {
184
+ process.exitCode = 1;
185
+ }
186
+ }