@williambeto/ai-workflow 1.19.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/CHANGELOG.md +56 -838
  2. package/PUBLISH_MANIFEST.json +34 -0
  3. package/README.md +70 -149
  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/examples/README.md +10 -0
  76. package/dist-assets/examples/autopilot-cycle/00-CONTEXT.md +3 -0
  77. package/dist-assets/examples/autopilot-cycle/01-requirement.md +16 -0
  78. package/dist-assets/examples/autopilot-cycle/02-gate-a-check.md +23 -0
  79. package/dist-assets/examples/autopilot-cycle/03-orion-planning.md +20 -0
  80. package/dist-assets/examples/autopilot-cycle/04-astra-implementation.md +17 -0
  81. package/dist-assets/examples/autopilot-cycle/05-sage-validation.md +15 -0
  82. package/dist-assets/examples/autopilot-cycle/06-phoenix-healing.md +12 -0
  83. package/dist-assets/examples/autopilot-cycle/07-orchestration-report.md +18 -0
  84. package/dist-assets/examples/backend-api/00-CONTEXT.md +12 -0
  85. package/dist-assets/examples/backend-api/01-requirement.md +19 -0
  86. package/dist-assets/examples/backend-api/02-functional-spec.md +20 -0
  87. package/dist-assets/examples/backend-api/03-technical-plan.md +15 -0
  88. package/dist-assets/examples/backend-api/04-pr-breakdown.md +10 -0
  89. package/dist-assets/examples/backend-api/05-execution-handoff.md +13 -0
  90. package/dist-assets/examples/backend-api/06-validation-report.md +11 -0
  91. package/dist-assets/examples/backend-api/07-orchestration-report.md +7 -0
  92. package/dist-assets/examples/blocked-scenarios/00-CONTEXT.md +9 -0
  93. package/dist-assets/examples/blocked-scenarios/01-branch-gate-block.md +12 -0
  94. package/dist-assets/examples/blocked-scenarios/02-quality-gate-block.md +13 -0
  95. package/dist-assets/examples/blocked-scenarios/03-scope-creep-block.md +13 -0
  96. package/dist-assets/examples/blocked-scenarios/04-unblock-resolution.md +9 -0
  97. package/dist-assets/examples/blocked-scenarios/05-orchestration-decision-log.md +11 -0
  98. package/dist-assets/examples/bugfix-critical/00-CONTEXT.md +12 -0
  99. package/dist-assets/examples/bugfix-critical/01-bug-report.md +11 -0
  100. package/dist-assets/examples/bugfix-critical/02-diagnosis-hypothesis.md +11 -0
  101. package/dist-assets/examples/bugfix-critical/03-technical-plan.md +12 -0
  102. package/dist-assets/examples/bugfix-critical/04-implementation-handoff.md +8 -0
  103. package/dist-assets/examples/bugfix-critical/05-validation-report.md +10 -0
  104. package/dist-assets/examples/bugfix-critical/06-orchestration-report.md +7 -0
  105. package/dist-assets/examples/cli-package/00-CONTEXT.md +9 -0
  106. package/dist-assets/examples/cli-package/01-requirement.md +14 -0
  107. package/dist-assets/examples/cli-package/02-technical-spec.md +16 -0
  108. package/dist-assets/examples/cli-package/03-technical-plan.md +12 -0
  109. package/dist-assets/examples/cli-package/04-pr-breakdown.md +9 -0
  110. package/dist-assets/examples/cli-package/05-release-report.md +15 -0
  111. package/dist-assets/examples/docs-only-repo/01-requirement.md +31 -0
  112. package/dist-assets/examples/docs-only-repo/02-functional-spec.md +25 -0
  113. package/dist-assets/examples/docs-only-repo/03-technical-plan.md +21 -0
  114. package/dist-assets/examples/docs-only-repo/04-pr-breakdown.md +13 -0
  115. package/dist-assets/examples/docs-only-repo/05-execution-handoff.md +17 -0
  116. package/dist-assets/examples/docs-only-repo/06-validation-report.md +16 -0
  117. package/dist-assets/examples/docs-only-repo/README.md +26 -0
  118. package/dist-assets/examples/full-stack-checkout/00-CONTEXT.md +9 -0
  119. package/dist-assets/examples/full-stack-checkout/01-requirement.md +12 -0
  120. package/dist-assets/examples/full-stack-checkout/02-functional-spec.md +15 -0
  121. package/dist-assets/examples/full-stack-checkout/03-technical-plan.md +15 -0
  122. package/dist-assets/examples/full-stack-checkout/04-pr-breakdown.md +8 -0
  123. package/dist-assets/examples/full-stack-checkout/05-execution-handoff.md +14 -0
  124. package/dist-assets/examples/full-stack-checkout/06-validation-report.md +12 -0
  125. package/dist-assets/examples/healing-cycle/00-CONTEXT.md +15 -0
  126. package/dist-assets/examples/healing-cycle/01-broken-implementation.md +10 -0
  127. package/dist-assets/examples/healing-cycle/02-sage-fails.md +14 -0
  128. package/dist-assets/examples/healing-cycle/03-phoenix-diagnosis.md +17 -0
  129. package/dist-assets/examples/healing-cycle/04-phoenix-fix.md +18 -0
  130. package/dist-assets/examples/healing-cycle/05-sage-revalidation.md +12 -0
  131. package/dist-assets/examples/healing-cycle/06-orchestration-log.md +14 -0
  132. package/dist-assets/examples/infra-deploy/00-CONTEXT.md +9 -0
  133. package/dist-assets/examples/infra-deploy/01-operational-goal.md +12 -0
  134. package/dist-assets/examples/infra-deploy/02-architecture-specs.md +15 -0
  135. package/dist-assets/examples/infra-deploy/03-implementation-plan.md +14 -0
  136. package/dist-assets/examples/infra-deploy/04-step-breakdown.md +9 -0
  137. package/dist-assets/examples/infra-deploy/05-execution-handoff.md +13 -0
  138. package/dist-assets/examples/infra-deploy/06-operational-report.md +11 -0
  139. package/dist-assets/examples/multi-pr-release/00-CONTEXT.md +9 -0
  140. package/dist-assets/examples/multi-pr-release/01-requirement.md +13 -0
  141. package/dist-assets/examples/multi-pr-release/02-strategic-plan.md +13 -0
  142. package/dist-assets/examples/multi-pr-release/03-pr-breakdown.md +14 -0
  143. package/dist-assets/examples/multi-pr-release/04-release-plan.md +12 -0
  144. package/dist-assets/examples/multi-pr-release/05-orchestration-report.md +7 -0
  145. package/dist-assets/examples/nuxt-dashboard/01-requirement.md +81 -0
  146. package/dist-assets/examples/nuxt-dashboard/02-functional-spec.md +88 -0
  147. package/dist-assets/examples/nuxt-dashboard/03-technical-plan.md +76 -0
  148. package/dist-assets/examples/nuxt-dashboard/04-pr-breakdown.md +219 -0
  149. package/dist-assets/examples/nuxt-dashboard/05-execution-handoff.md +88 -0
  150. package/dist-assets/examples/nuxt-dashboard/06-validation-report.md +56 -0
  151. package/dist-assets/examples/nuxt-dashboard/07-orchestration-report.md +79 -0
  152. package/dist-assets/examples/nuxt-dashboard/README.md +52 -0
  153. package/dist-assets/examples/react-dashboard/01-requirement.md +84 -0
  154. package/dist-assets/examples/react-dashboard/02-functional-spec.md +88 -0
  155. package/dist-assets/examples/react-dashboard/03-technical-plan.md +76 -0
  156. package/dist-assets/examples/react-dashboard/04-pr-breakdown.md +218 -0
  157. package/dist-assets/examples/react-dashboard/05-execution-handoff.md +13 -0
  158. package/dist-assets/examples/react-dashboard/06-validation-report.md +12 -0
  159. package/dist-assets/examples/react-dashboard/07-orchestration-report.md +7 -0
  160. package/dist-assets/examples/react-dashboard/README.md +70 -0
  161. package/dist-assets/examples/refactoring-service/00-CONTEXT.md +9 -0
  162. package/dist-assets/examples/refactoring-service/01-debt-report.md +12 -0
  163. package/dist-assets/examples/refactoring-service/02-behavior-spec.md +11 -0
  164. package/dist-assets/examples/refactoring-service/03-technical-plan.md +13 -0
  165. package/dist-assets/examples/refactoring-service/04-pr-breakdown.md +9 -0
  166. package/dist-assets/examples/refactoring-service/05-execution-handoff.md +14 -0
  167. package/dist-assets/examples/refactoring-service/06-stability-report.md +12 -0
  168. package/dist-assets/examples/sdd-cycle/00-CONTEXT.md +12 -0
  169. package/dist-assets/examples/sdd-cycle/01-raw-request.md +13 -0
  170. package/dist-assets/examples/sdd-cycle/02-spec-creation.md +18 -0
  171. package/dist-assets/examples/sdd-cycle/03-spec-review.md +12 -0
  172. package/dist-assets/examples/sdd-cycle/04-technical-plan.md +16 -0
  173. package/dist-assets/examples/sdd-cycle/05-pr-breakdown.md +9 -0
  174. package/dist-assets/examples/sdd-cycle/06-spec-implement.md +13 -0
  175. package/dist-assets/examples/sdd-cycle/07-validation-against-spec.md +13 -0
  176. package/dist-assets/examples/wordpress-theme/01-requirement.md +29 -0
  177. package/dist-assets/examples/wordpress-theme/02-functional-spec.md +22 -0
  178. package/dist-assets/examples/wordpress-theme/03-technical-plan.md +22 -0
  179. package/dist-assets/examples/wordpress-theme/04-pr-breakdown.md +14 -0
  180. package/dist-assets/examples/wordpress-theme/05-execution-handoff.md +17 -0
  181. package/dist-assets/examples/wordpress-theme/06-validation-report.md +16 -0
  182. package/dist-assets/examples/wordpress-theme/README.md +32 -0
  183. package/{harness → dist-assets/harness}/handoffs/HANDOFF.template.md +2 -2
  184. package/{harness → dist-assets/harness}/workflows/agent-evaluation-checklist.md +5 -5
  185. package/{harness → dist-assets/harness}/workflows/implement-review-validate.md +24 -0
  186. package/{harness → dist-assets/harness}/workflows/multi-agent-handoff.md +4 -4
  187. package/{harness → dist-assets/harness}/workflows/planner-executor-workflow.md +5 -5
  188. package/{harness → dist-assets/harness}/workflows/requirement-to-pr.md +1 -1
  189. package/dist-assets/runbooks/agent-delegation-workflow.md +50 -0
  190. package/dist-assets/runbooks/apply-starter-to-real-project.md +45 -0
  191. package/dist-assets/runbooks/commands-cheatsheet.md +44 -0
  192. package/dist-assets/runbooks/how-to-use-skills.md +44 -0
  193. package/dist-assets/runbooks/private-spec-publication-safety.md +35 -0
  194. package/{runbooks → dist-assets/runbooks}/spec-driven-development.md +3 -6
  195. package/dist-assets/runbooks/tutorial-walkthroughs.md +23 -0
  196. package/dist-assets/runbooks/use-linear-for-operational-planning.md +45 -0
  197. package/dist-assets/runbooks/use-napkin-project-memory.md +33 -0
  198. package/dist-assets/skills/architecture/SKILL.md +166 -0
  199. package/dist-assets/skills/backend-development/SKILL.md +166 -0
  200. package/dist-assets/skills/deployment/SKILL.md +166 -0
  201. package/dist-assets/skills/design-principles/SKILL.md +166 -0
  202. package/dist-assets/skills/documentation/SKILL.md +171 -0
  203. package/dist-assets/skills/frontend-development/SKILL.md +225 -0
  204. package/dist-assets/skills/full-stack-development/SKILL.md +166 -0
  205. package/dist-assets/skills/optimize-tokens/SKILL.md +166 -0
  206. package/dist-assets/skills/pr-workflow/SKILL.md +166 -0
  207. package/dist-assets/skills/product-discovery/SKILL.md +166 -0
  208. package/dist-assets/skills/product-planning/SKILL.md +166 -0
  209. package/dist-assets/skills/project-memory/SKILL.md +166 -0
  210. package/dist-assets/skills/prompt-engineer/SKILL.md +166 -0
  211. package/dist-assets/skills/qa-workflow/SKILL.md +186 -0
  212. package/dist-assets/skills/refactoring/SKILL.md +166 -0
  213. package/dist-assets/skills/release-workflow/SKILL.md +166 -0
  214. package/dist-assets/skills/spec-driven-development/SKILL.md +166 -0
  215. package/dist-assets/skills/technical-leadership/SKILL.md +166 -0
  216. package/dist-assets/skills/ui-ux-design/SKILL.md +202 -0
  217. package/dist-assets/templates/.geminiignore.template +8 -0
  218. package/dist-assets/templates/CLAUDE.md.template +20 -0
  219. package/dist-assets/templates/CODEX.md.template +20 -0
  220. package/dist-assets/templates/GEMINI.md.template +20 -0
  221. package/dist-assets/templates/HANDOFF.template.md +45 -0
  222. package/dist-assets/templates/SPEC.template.md +38 -0
  223. package/dist-assets/templates/change-proposal.template.md +14 -0
  224. package/dist-assets/templates/owner-evidence/astra-implementation.json +10 -0
  225. package/dist-assets/templates/owner-evidence/phoenix-remediation.json +8 -0
  226. package/dist-assets/templates/owner-evidence/sage-revalidation.json +8 -0
  227. package/dist-assets/templates/owner-evidence/sage-validation.json +8 -0
  228. package/dist-assets/templates/specs/deep.md +48 -0
  229. package/dist-assets/templates/specs/standard.md +38 -0
  230. package/dist-assets/templates/specs/tiny.md +19 -0
  231. package/package.json +42 -47
  232. package/src/adapters/index.js +3 -0
  233. package/src/adapters/platforms/claude.js +126 -0
  234. package/src/adapters/platforms/codex.js +100 -0
  235. package/src/adapters/platforms/gemini.js +232 -0
  236. package/src/cli.js +96 -0
  237. package/src/commands/collect-evidence.js +61 -0
  238. package/src/commands/doctor.js +186 -0
  239. package/{packages/ai-workflow/src → src}/commands/init.js +119 -20
  240. package/src/commands/run.js +111 -0
  241. package/src/core/completion-contract.js +35 -0
  242. package/src/core/gates/branch-gate.js +113 -0
  243. package/src/core/handoff/handoff-engine.js +78 -0
  244. package/src/core/healing/cli-remediation-executor.js +151 -0
  245. package/src/core/healing/healer-engine.js +179 -0
  246. package/src/core/identity.js +43 -0
  247. package/{packages/ai-workflow/src → src}/core/install-plan.js +3 -3
  248. package/src/core/opencode-merge.js +149 -0
  249. package/{packages/ai-workflow/src → src}/core/package-assets.js +29 -10
  250. package/src/core/sdd/validator.js +67 -0
  251. package/src/core/statuses.js +29 -0
  252. package/src/core/symlink-layout.js +93 -0
  253. package/src/core/templates.js +218 -0
  254. package/src/core/validation/canonical-finalization.js +43 -0
  255. package/src/core/validation/evidence-collector.js +109 -0
  256. package/src/core/validation/quality-guard.js +243 -0
  257. package/src/core/workflow-profiles.js +107 -0
  258. package/.agents/napkin.md +0 -89
  259. package/.agents/skills/backend-implementer/SKILL.md +0 -490
  260. package/.agents/skills/build-and-validate/SKILL.md +0 -442
  261. package/.agents/skills/deploy-engineer/SKILL.md +0 -541
  262. package/.agents/skills/docs-writer/SKILL.md +0 -430
  263. package/.agents/skills/frontend-implementer/SKILL.md +0 -488
  264. package/.agents/skills/interface-design/SKILL.md +0 -428
  265. package/.agents/skills/interface-design/references/critique.md +0 -67
  266. package/.agents/skills/interface-design/references/example.md +0 -86
  267. package/.agents/skills/interface-design/references/principles.md +0 -235
  268. package/.agents/skills/interface-design/references/validation.md +0 -48
  269. package/.agents/skills/minimal-context/SKILL.md +0 -177
  270. package/.agents/skills/napkin/SKILL.md +0 -84
  271. package/.agents/skills/opencode-agent-design/SKILL.md +0 -77
  272. package/.agents/skills/playwright-cli/SKILL.md +0 -62
  273. package/.agents/skills/pr-orchestrator/SKILL.md +0 -366
  274. package/.agents/skills/product-manager/SKILL.md +0 -519
  275. package/.agents/skills/seo-audit/SKILL.md +0 -176
  276. package/.agents/skills/stack-variant-creator/SKILL.md +0 -265
  277. package/.agents/skills/tech-lead/SKILL.md +0 -453
  278. package/.agents/skills/tester/SKILL.md +0 -399
  279. package/.agents/skills/token-economy/SKILL.md +0 -137
  280. package/.agents/skills/vue-nuxt/SKILL.md +0 -102
  281. package/.agents/skills/wordpress-engineer/SKILL.md +0 -75
  282. package/.codex/prompts/README.md +0 -44
  283. package/.codex/prompts/autopilot.md +0 -50
  284. package/.codex/prompts/deploy.md +0 -33
  285. package/.codex/prompts/execute-selected-pr.md +0 -35
  286. package/.codex/prompts/fix-issue.md +0 -34
  287. package/.codex/prompts/minimal-context-mode.md +0 -55
  288. package/.codex/prompts/orchestrate-next.md +0 -33
  289. package/.codex/prompts/plan-from-requirement.md +0 -37
  290. package/.codex/prompts/review-implementation.md +0 -33
  291. package/.codex/prompts/roadmap-audit.md +0 -22
  292. package/.codex/prompts/specs/create-spec-from-requirement.md +0 -26
  293. package/.codex/prompts/specs/review-spec.md +0 -29
  294. package/.codex/prompts/specs/spec-to-pr-breakdown.md +0 -23
  295. package/.codex/prompts/specs/spec-to-technical-plan.md +0 -28
  296. package/.codex/prompts/start-project.md +0 -29
  297. package/.codex/prompts/token-economy-mode.md +0 -48
  298. package/.codex/prompts/validate-work.md +0 -28
  299. package/checklists/change-spec-readiness-checklist.md +0 -34
  300. package/docs/full-documentation.md +0 -661
  301. package/docs/setup-codex-opencode.md +0 -313
  302. package/harness/README.md +0 -106
  303. package/opencode/README.md +0 -84
  304. package/opencode/agents/README.md +0 -113
  305. package/opencode/agents/atlas.md +0 -127
  306. package/opencode/agents/discovery.md +0 -61
  307. package/opencode/agents/fixer.md +0 -51
  308. package/opencode/agents/implementer.md +0 -61
  309. package/opencode/agents/orchestrator.md +0 -145
  310. package/opencode/agents/planner.md +0 -60
  311. package/opencode/agents/prompt-engineer.md +0 -50
  312. package/opencode/agents/release-manager.md +0 -50
  313. package/opencode/agents/reviewer.md +0 -51
  314. package/opencode/agents/spec-engineer.md +0 -85
  315. package/opencode/agents/validator.md +0 -50
  316. package/opencode/agents/wordpress-engineer.md +0 -49
  317. package/opencode/commands/README.md +0 -48
  318. package/opencode/commands/autopilot.md +0 -50
  319. package/opencode/commands/deploy.md +0 -35
  320. package/opencode/commands/execute.md +0 -47
  321. package/opencode/commands/orchestrate.md +0 -37
  322. package/opencode/commands/plan.md +0 -39
  323. package/opencode/commands/review.md +0 -33
  324. package/opencode/commands/roadmap-audit.md +0 -30
  325. package/opencode/commands/ship.md +0 -48
  326. package/opencode/commands/specs/create-spec-from-request.md +0 -27
  327. package/opencode/commands/specs/create-spec-from-requirement.md +0 -25
  328. package/opencode/commands/specs/review-spec.md +0 -26
  329. package/opencode/commands/specs/spec-to-pr-breakdown.md +0 -19
  330. package/opencode/commands/specs/spec-to-tasks.md +0 -26
  331. package/opencode/commands/specs/spec-to-technical-plan.md +0 -27
  332. package/opencode/commands/start.md +0 -45
  333. package/opencode/commands/token-economy.md +0 -29
  334. package/opencode/commands/validate.md +0 -33
  335. package/opencode.jsonc +0 -235
  336. package/packages/ai-workflow/README.md +0 -82
  337. package/packages/ai-workflow/src/cli.js +0 -70
  338. package/packages/ai-workflow/src/commands/codex.js +0 -37
  339. package/packages/ai-workflow/src/commands/doctor.js +0 -168
  340. package/packages/ai-workflow/src/commands/guide.js +0 -194
  341. package/packages/ai-workflow/src/core/opencode-merge.js +0 -172
  342. package/packages/ai-workflow/src/core/symlink-layout.js +0 -54
  343. package/packages/ai-workflow/src/core/templates.js +0 -276
  344. package/runbooks/agent-delegation-workflow.md +0 -111
  345. package/runbooks/apply-starter-to-real-project.md +0 -445
  346. package/runbooks/commands-cheatsheet.md +0 -71
  347. package/runbooks/how-to-use-skills.md +0 -713
  348. package/runbooks/quick-start-guide.md +0 -213
  349. package/runbooks/tutorial-walkthroughs.md +0 -416
  350. package/runbooks/use-linear-for-operational-planning.md +0 -185
  351. package/runbooks/use-napkin-project-memory.md +0 -77
  352. package/templates/AGENTS.template.md +0 -397
  353. package/templates/DESIGN.template.md +0 -484
  354. package/templates/PR-PLAN.template.md +0 -172
  355. package/templates/README.template.md +0 -293
  356. package/templates/REQUIREMENT.template.md +0 -165
  357. package/templates/SPEC.template.md +0 -397
  358. package/templates/TECH-PLAN.template.md +0 -244
  359. package/templates/change-proposal.template.md +0 -97
  360. /package/{checklists/spec-readiness-checklist.md → dist-assets/docs/policies/SPEC_READINESS.md} +0 -0
  361. /package/{prompts → dist-assets/prompts}/00-bootstrap-project.md +0 -0
  362. /package/{prompts → dist-assets/prompts}/01-create-requirement.md +0 -0
  363. /package/{prompts → dist-assets/prompts}/02-create-spec.md +0 -0
  364. /package/{prompts → dist-assets/prompts}/03-create-tech-plan.md +0 -0
  365. /package/{prompts → dist-assets/prompts}/04-breakdown-prs.md +0 -0
  366. /package/{prompts → dist-assets/prompts}/05-implement-pr.md +0 -0
  367. /package/{prompts → dist-assets/prompts}/06-review-and-fix.md +0 -0
  368. /package/{prompts → dist-assets/prompts}/07-apply-design.md +0 -0
  369. /package/{prompts → dist-assets/prompts}/08-validate.md +0 -0
  370. /package/{prompts → dist-assets/prompts}/09-deploy.md +0 -0
  371. /package/{prompts → dist-assets/prompts}/commands/implement.md +0 -0
  372. /package/{prompts → dist-assets/prompts}/commands/requirement.md +0 -0
  373. /package/{prompts → dist-assets/prompts}/commands/spec.md +0 -0
  374. /package/{prompts → dist-assets/prompts}/commands/tech-plan.md +0 -0
  375. /package/{prompts → dist-assets/prompts}/commands/validate.md +0 -0
  376. /package/{runbooks → dist-assets/runbooks}/branch-cleanup.md +0 -0
  377. /package/{runbooks → dist-assets/runbooks}/deploy-checklist.md +0 -0
  378. /package/{runbooks → dist-assets/runbooks}/publication-readiness-checklist.md +0 -0
  379. /package/{runbooks → dist-assets/runbooks}/publish-package-checklist.md +0 -0
  380. /package/{runbooks → dist-assets/runbooks}/team-governance-pr-readiness.md +0 -0
  381. /package/{runbooks → dist-assets/runbooks}/validate-starter-in-real-project.md +0 -0
  382. /package/{runbooks → dist-assets/runbooks}/validation-checklist.md +0 -0
  383. /package/{schemas → dist-assets/schemas}/README.md +0 -0
  384. /package/{schemas → dist-assets/schemas}/functional-spec.schema.json +0 -0
  385. /package/{schemas → dist-assets/schemas}/handoff.schema.json +0 -0
  386. /package/{schemas → dist-assets/schemas}/pr-breakdown.schema.json +0 -0
  387. /package/{schemas → dist-assets/schemas}/requirement.schema.json +0 -0
  388. /package/{schemas → dist-assets/schemas}/technical-plan.schema.json +0 -0
  389. /package/{schemas → dist-assets/schemas}/validation-report.schema.json +0 -0
  390. /package/{packages/ai-workflow/src → src}/core/backup.js +0 -0
  391. /package/{packages/ai-workflow/src → src}/core/filesystem.js +0 -0
@@ -2,10 +2,11 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { createInstallPlan } from "../core/install-plan.js";
4
4
  import { buildAiWorkflowConfig, getTemplateFiles, isValidProfile } from "../core/templates.js";
5
- import { exists, writeFileSafe } from "../core/filesystem.js";
5
+ import { exists, writeFileSafe, readJson } from "../core/filesystem.js";
6
6
  import { createManagedBackup, createManagedPathBackup } from "../core/backup.js";
7
7
  import { mergeOpencodeConfig } from "../core/opencode-merge.js";
8
- import { buildSymlinkEntries, isSymlinkTo } from "../core/symlink-layout.js";
8
+ import { buildSymlinkEntries, isSymlinkTo, setupInternalSymlinks } from "../core/symlink-layout.js";
9
+ import { GeminiAdapter, ClaudeAdapter, CodexAdapter } from "../adapters/index.js";
9
10
 
10
11
  function summarize(actions) {
11
12
  const createCount = actions.filter((a) => a.type === "create").length;
@@ -79,16 +80,63 @@ async function upsertGitignoreBlock(cwd, entries) {
79
80
  return "updated";
80
81
  }
81
82
 
82
- export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite, profile }) {
83
- const selectedProfile = profile ?? "full";
84
- const installRoot = ".ai-workflow";
83
+ async function injectScripts(cwd) {
84
+ const pkgPath = path.join(cwd, "package.json");
85
+ if (!(await exists(pkgPath))) return;
86
+
87
+ try {
88
+ const pkg = await readJson(pkgPath);
89
+ if (!pkg.scripts) pkg.scripts = {};
90
+
91
+ if (!pkg.scripts.validate) {
92
+ pkg.scripts.validate = "ai-workflow collect-evidence";
93
+ await writeFileSafe(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
94
+ return true;
95
+ }
96
+ } catch {
97
+ // Ignore invalid package.json
98
+ }
99
+ return false;
100
+ }
101
+
102
+ export async function runInit({
103
+ cwd, yes, force, dryRun, noInstall, noOverwrite, gemini, claude, codex, "dev-mode": devMode, profile }) {
104
+ // Self-execution guard
105
+ if (!devMode) {
106
+ try {
107
+ const pkgPath = path.join(cwd, "package.json");
108
+ if (await exists(pkgPath)) {
109
+ const pkg = await readJson(pkgPath);
110
+ if (pkg.name === "@williambeto/ai-workflow") {
111
+ console.error("\nFATAL: Cannot run 'ai-workflow init' inside its own development repository.");
112
+ console.error("This would corrupt the development environment. Aborting.");
113
+ console.error("Use the --dev-mode flag if you are developing the kit itself and need to test the init command.\n");
114
+ process.exit(1);
115
+ }
116
+ }
117
+ } catch {
118
+ // Ignore if package.json is unreadable. The guard is a safety net.
119
+ }
120
+ }
121
+
122
+ const selectedProfile = profile || "standard";
85
123
 
86
124
  if (!isValidProfile(selectedProfile)) {
87
- throw new Error(`invalid profile: ${selectedProfile}. Use minimal, operational, or full.`);
125
+ console.error(`Invalid profile: "${selectedProfile}". Valid profiles: standard, full`);
126
+ process.exit(1);
88
127
  }
128
+ const installRoot = ".ai-workflow";
129
+
130
+ const platforms = [];
131
+ if (gemini) platforms.push("gemini");
132
+ if (claude) platforms.push("claude");
133
+ if (codex) platforms.push("codex");
89
134
 
90
135
  console.log(`ai-workflow: initializing in ${cwd}`);
91
136
  console.log(`Profile: ${selectedProfile}`);
137
+ if (platforms.length > 0) {
138
+ console.log(`Platforms: ${platforms.join(", ")}`);
139
+ }
92
140
 
93
141
  const actions = await createInstallPlan({ cwd, exists, profile: selectedProfile });
94
142
  const linkEntries = buildSymlinkEntries({ templateFiles: getTemplateFiles(selectedProfile), installRoot });
@@ -105,6 +153,9 @@ export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite,
105
153
 
106
154
  if (dryRun) {
107
155
  console.log("Dry-run enabled. No files were written.");
156
+ if (platforms.length > 0) {
157
+ console.log("ai-workflow: (dry-run) platform migration would be executed after file writing.");
158
+ }
108
159
  return;
109
160
  }
110
161
 
@@ -128,17 +179,10 @@ export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite,
128
179
  }
129
180
 
130
181
  const content =
131
- action.relativePath === ".ai-workflow.json"
182
+ action.relativePath === ".ai-workflow/config.json"
132
183
  ? `${JSON.stringify(
133
184
  buildAiWorkflowConfig({
134
- profile: selectedProfile,
135
- managedFiles: Array.from(
136
- new Set([
137
- ...Object.keys(getTemplateFiles(selectedProfile)).map((p) => path.join(installRoot, p)),
138
- ".ai-workflow.json"
139
- ])
140
- ),
141
- managedLinks: linkEntries.map((entry) => entry.linkPath)
185
+ profile: selectedProfile
142
186
  }),
143
187
  null,
144
188
  2
@@ -175,6 +219,8 @@ export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite,
175
219
  maxPerFile: 20
176
220
  });
177
221
  linkBackups.push(backupPath);
222
+ // Ensure we remove the old path before symlinking if it's not already handled by backup
223
+ await fs.rm(absoluteLinkPath, { recursive: true, force: true });
178
224
  }
179
225
 
180
226
  const stat = await fs.lstat(absoluteTargetPath);
@@ -182,6 +228,7 @@ export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite,
182
228
  const linkTarget = process.platform === "win32" ? absoluteTargetPath : path.relative(path.dirname(absoluteLinkPath), absoluteTargetPath);
183
229
 
184
230
  try {
231
+ await fs.mkdir(path.dirname(absoluteLinkPath), { recursive: true });
185
232
  await fs.symlink(linkTarget, absoluteLinkPath, type);
186
233
  } catch (error) {
187
234
  throw new Error(
@@ -193,25 +240,77 @@ export async function runInit({ cwd, yes, force, dryRun, noInstall, noOverwrite,
193
240
  linkCreated.push(linkPath);
194
241
  }
195
242
 
196
- const opencodeResult =
197
- selectedProfile === "minimal"
198
- ? { reason: "skipped (minimal profile)" }
199
- : await mergeOpencodeConfig(cwd, { force, backupRoot, profile: selectedProfile });
243
+ await setupInternalSymlinks(cwd, installRoot);
244
+
245
+ const opencodeResult = await mergeOpencodeConfig(cwd, { force, backupRoot });
200
246
 
201
247
  const generatedIgnoreEntries = [
202
248
  ".ai-workflow/",
203
- ".ai-workflow.json",
204
249
  ".ai-workflow-backups/",
250
+ "opencode.jsonc.backup.*",
205
251
  ...linkEntries.flatMap((entry) => toIgnoreEntries(entry.linkPath))
206
252
  ];
207
253
 
254
+ if (gemini) {
255
+ generatedIgnoreEntries.push(".gemini/");
256
+ }
257
+ if (codex) {
258
+ generatedIgnoreEntries.push(".agents/", ".codex/");
259
+ }
260
+ if (claude) {
261
+ generatedIgnoreEntries.push(".claude/");
262
+ }
263
+
208
264
  const gitignoreResult = await upsertGitignoreBlock(cwd, generatedIgnoreEntries);
265
+ const scriptInjected = await injectScripts(cwd);
266
+
267
+ if (platforms.length > 0) {
268
+ console.log("ai-workflow: migrating to native platforms...");
269
+ const agentsDir = path.join(cwd, installRoot, "opencode/agents");
270
+ const skillsDir = path.join(cwd, installRoot, "opencode/skills");
271
+
272
+ const agentFiles = (await fs.readdir(agentsDir).catch(() => []))
273
+ .filter((f) => f.endsWith(".md"))
274
+ .map((f) => path.join(agentsDir, f));
275
+
276
+ if (gemini) {
277
+ const adapter = new GeminiAdapter({ cwd });
278
+
279
+ // Collect specialized skills from the new opencode/skills path
280
+ const skillFolders = await fs.readdir(skillsDir).catch(() => []);
281
+ const skillFiles = [];
282
+ for (const folder of skillFolders) {
283
+ const skillPath = path.join(skillsDir, folder, "SKILL.md");
284
+ if (await exists(skillPath)) {
285
+ skillFiles.push(skillPath);
286
+ }
287
+ }
288
+
289
+ const allFiles = [...agentFiles, ...skillFiles];
290
+ const transformed = await Promise.all(allFiles.map((f) => adapter.transform(f)));
291
+ await adapter.deploy(transformed, installRoot);
292
+ console.log(`- gemini: deployed AI Workflow Kit agents to .gemini/ (native discovery enabled)`);
293
+ }
294
+
295
+ if (claude) {
296
+ const adapter = new ClaudeAdapter({ cwd });
297
+ await adapter.deploy(installRoot);
298
+ console.log("- claude: deployed AI Workflow Kit agents to CLAUDE.md and .claude/rules/ (native discovery enabled)");
299
+ }
300
+
301
+ if (codex) {
302
+ const adapter = new CodexAdapter({ cwd });
303
+ await adapter.deploy(installRoot);
304
+ console.log("- codex: deployed AI Workflow Kit agents to .agents/, .codex/, and .github/ (native discovery enabled)");
305
+ }
306
+ }
209
307
 
210
308
  console.log("Installation complete.");
211
309
  console.log(`- profile: ${selectedProfile}`);
212
310
 
213
311
  console.log(`- opencode.jsonc: ${opencodeResult.reason}`);
214
312
  console.log(`- .gitignore: ${gitignoreResult}`);
313
+ console.log(`- scripts: ${scriptInjected ? "injected 'validate'" : "already-up-to-date"}`);
215
314
  console.log(`- symlink layout: ${linkCreated.length > 0 ? `created ${linkCreated.length}` : "already-up-to-date"}`);
216
315
  if (backups.length > 0) {
217
316
  console.log(`- backups created: ${backups.length}`);
@@ -0,0 +1,111 @@
1
+ import { BranchGate } from "../core/gates/branch-gate.js";
2
+ import { SpecValidator } from "../core/sdd/validator.js";
3
+ import { HandoffEngine } from "../core/handoff/handoff-engine.js";
4
+ import { runCollectEvidence } from "./collect-evidence.js";
5
+ import { QualityGuard } from "../core/validation/quality-guard.js";
6
+ import { HealerEngine } from "../core/healing/healer-engine.js";
7
+ import { createCliRemediationExecutor } from "../core/healing/cli-remediation-executor.js";
8
+ import { isRecoverableGateFailure, isTerminalFailure } from "../core/statuses.js";
9
+ import path from "node:path";
10
+ import fs from "node:fs/promises";
11
+ import { getWorkflowProfile, resolveWorkflowProfile } from "../core/workflow-profiles.js";
12
+
13
+ function normalizeTaskSlugFromSpec(specPath) {
14
+ const normalized = String(specPath).replaceAll("\\", "/");
15
+ const marker = "/docs/workflows/";
16
+ const index = normalized.includes(marker)
17
+ ? normalized.indexOf(marker) + marker.length
18
+ : normalized.startsWith("docs/workflows/") ? "docs/workflows/".length : -1;
19
+ if (index >= 0) {
20
+ const slug = normalized.slice(index).split("/")[0];
21
+ if (slug) return slug;
22
+ }
23
+ return path.basename(specPath, path.extname(specPath));
24
+ }
25
+
26
+ function combineValidation(evidence, quality) {
27
+ const statuses = [evidence.internalStatus, quality.overallStatus];
28
+ let overallStatus = "PASS";
29
+ if (statuses.includes("BLOCKED")) overallStatus = "BLOCKED";
30
+ else if (statuses.includes("FAIL")) overallStatus = "FAIL";
31
+ else if (statuses.includes("FAIL_DELEGATION_GATE")) overallStatus = "FAIL_DELEGATION_GATE";
32
+ else if (statuses.includes("FAIL_QUALITY_GATE")) overallStatus = "FAIL_QUALITY_GATE";
33
+ else if (statuses.includes("PASS_WITH_NOTES")) overallStatus = "PASS_WITH_NOTES";
34
+ return { overallStatus, evidence, quality };
35
+ }
36
+
37
+ /**
38
+ * Coordinates branch safety, specification validation, observed validation, bounded remediation, and handoff.
39
+ * Failed required validation can never be promoted to success.
40
+ */
41
+ export async function runMasterOrchestrator({ cwd, specPath, override, remediationExecutor = null }) {
42
+ console.log("\n[AI WORKFLOW] Starting evidence-backed orchestration...\n");
43
+
44
+ const branchGate = new BranchGate({ memoryDir: path.join(cwd, ".ai-workflow"), cwd });
45
+ const taskSlug = specPath ? normalizeTaskSlugFromSpec(specPath) : "implementation";
46
+ const gateResult = branchGate.check(override, { autoRecover: true, taskSlug });
47
+ if (gateResult.blocked) throw new Error(`[GATE BLOCKED] ${gateResult.reason}`);
48
+ console.log(`[PASS] Branch Gate: ${gateResult.recovered ? `${gateResult.branchBefore} -> ${gateResult.branch}` : `${gateResult.branch} is authorized`}.`);
49
+
50
+ if (!specPath) throw new Error("[SDD BLOCKED] Missing --spec-path. An approved specification is required.");
51
+
52
+ const validator = new SpecValidator();
53
+ const absoluteSpecPath = path.isAbsolute(specPath) ? specPath : path.join(cwd, specPath);
54
+ const validation = await validator.validate(absoluteSpecPath);
55
+ if (!validation.valid) throw new Error(`[SDD BLOCKED] Specification is not ready: ${validation.reason}`);
56
+
57
+ const executionMode = validation.tier === "deep" ? "full" : validation.tier === "tiny" ? "quick" : "standard";
58
+ const specContent = await fs.readFile(absoluteSpecPath, "utf8");
59
+ const workflowProfile = resolveWorkflowProfile({ request: specContent });
60
+ const profileDefinition = getWorkflowProfile(workflowProfile);
61
+ console.log(`[PASS] Specification: ${validation.tier.toUpperCase()} spec is APPROVED.`);
62
+ console.log(`[PROFILE] ${workflowProfile} -> ${profileDefinition.owner}; skills: ${profileDefinition.skills.join(", ") || "none"}.`);
63
+
64
+ const validateWorkflow = async () => {
65
+ const evidence = await runCollectEvidence({
66
+ cwd,
67
+ exitOnError: false,
68
+ taskSlug,
69
+ mode: executionMode,
70
+ profile: workflowProfile,
71
+ branchRecovery: gateResult.recovered ? `${gateResult.branchBefore} -> ${gateResult.branch}` : "NOT_REQUIRED"
72
+ });
73
+ const quality = await new QualityGuard({ cwd, taskSlug, mode: executionMode }).verify();
74
+ return combineValidation(evidence, quality);
75
+ };
76
+
77
+ let result = await validateWorkflow();
78
+ if (isRecoverableGateFailure(result.overallStatus)) {
79
+ console.log(`\n[REMEDIATION REQUIRED] ${result.overallStatus}. Starting bounded ${executionMode} remediation.`);
80
+ // Use the provided executor (programmatic API) or fall back to the default CLI executor.
81
+ // The CLI executor re-runs failed npm scripts; it does not modify source code.
82
+ const executor = typeof remediationExecutor === "function"
83
+ ? remediationExecutor
84
+ : createCliRemediationExecutor(cwd);
85
+ const healer = new HealerEngine({ cwd, mode: executionMode, taskSlug });
86
+ result = await healer.run({ initialResult: result, validate: validateWorkflow, remediate: executor });
87
+ }
88
+
89
+ if (isTerminalFailure(result.overallStatus)) {
90
+ throw new Error(`[WORKFLOW BLOCKED] ${result.overallStatus}: ${result.reason || "Validation could not be resolved safely."}`);
91
+ }
92
+ if (isRecoverableGateFailure(result.overallStatus)) {
93
+ throw new Error(`[WORKFLOW BLOCKED] Unresolved gate status after remediation: ${result.overallStatus}`);
94
+ }
95
+
96
+ console.log("\n--- Final Handoff ---");
97
+ const handoffEngine = new HandoffEngine({ cwd });
98
+ const handoffPath = await handoffEngine.generate({
99
+ taskId: path.basename(specPath, ".md"),
100
+ status: result.overallStatus,
101
+ specPaths: [specPath],
102
+ nextActions: `Profile ${workflowProfile}. Observed validation completed. Ready for review or explicitly approved release actions.`
103
+ });
104
+
105
+ console.log(`\n[AI WORKFLOW COMPLETE] ${result.overallStatus}`);
106
+ if (result.remediation?.attempts) console.log(`Remediation attempts: ${result.remediation.attempts}`);
107
+ console.log(`Handoff Packet: ${path.relative(cwd, handoffPath)}\n`);
108
+ return { ...result, workflowProfile };
109
+ }
110
+
111
+ export { combineValidation };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Evaluates objective owner-output completeness. It does not judge visual taste.
3
+ * A caller may resume the same owner once; a second incomplete result must block.
4
+ */
5
+ export function evaluateOwnerCompletion({
6
+ expectedFiles = [],
7
+ existingFiles = [],
8
+ validation = {},
9
+ ownerReportComplete = false,
10
+ resumeCount = 0
11
+ } = {}) {
12
+ const existing = new Set(existingFiles);
13
+ const missingFiles = expectedFiles.filter((file) => !existing.has(file));
14
+ const missingValidation = Object.entries(validation)
15
+ .filter(([, value]) => value === "REQUIRED" || value === false)
16
+ .map(([key]) => key);
17
+ const missing = [
18
+ ...missingFiles.map((file) => `file:${file}`),
19
+ ...missingValidation.map((check) => `validation:${check}`),
20
+ ...(!ownerReportComplete ? ["owner-report"] : [])
21
+ ];
22
+
23
+ if (missing.length === 0) {
24
+ return { status: "PASS", action: "continue", missing: [] };
25
+ }
26
+ if (resumeCount < 1) {
27
+ return { status: "INCOMPLETE", action: "resume-same-owner", missing };
28
+ }
29
+ return {
30
+ status: "BLOCKED",
31
+ action: "stop",
32
+ reason: "Owner output remained incomplete after one resume",
33
+ missing
34
+ };
35
+ }
@@ -0,0 +1,113 @@
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+
5
+ function slugify(value = "task") {
6
+ return String(value)
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9]+/g, "-")
9
+ .replace(/^-+|-+$/g, "")
10
+ .slice(0, 48) || "task";
11
+ }
12
+
13
+ /**
14
+ * BranchGate - Protects main/master and can recover safely onto a scoped branch.
15
+ */
16
+ export class BranchGate {
17
+ constructor({ protectedBranches = ["main", "master"], memoryDir, cwd = process.cwd() } = {}) {
18
+ this.protectedBranches = protectedBranches;
19
+ this.logPath = memoryDir ? path.join(memoryDir, "GATE_ALERTS.log") : null;
20
+ this.cwd = cwd;
21
+ }
22
+
23
+ run(command) {
24
+ return execSync(command, {
25
+ cwd: this.cwd,
26
+ encoding: "utf8",
27
+ stdio: ["ignore", "pipe", "pipe"]
28
+ }).trim();
29
+ }
30
+
31
+ log(event) {
32
+ if (!this.logPath) return;
33
+ const timestamp = new Date().toISOString();
34
+ const logEntry = `[${timestamp}] ${event}\n`;
35
+ try {
36
+ if (!fs.existsSync(path.dirname(this.logPath))) fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
37
+ fs.appendFileSync(this.logPath, logEntry);
38
+ } catch (error) {
39
+ console.error(`Failed to write to gate log: ${error.message}`);
40
+ }
41
+ }
42
+
43
+ getDirtyState() {
44
+ const lines = this.run("git status --short").split("\n").filter(Boolean);
45
+ const tracked = lines.filter((line) => !line.startsWith("??"));
46
+ const untracked = lines.filter((line) => line.startsWith("??"));
47
+ return { clean: lines.length === 0, tracked, untracked, lines };
48
+ }
49
+
50
+ createScopedBranch(taskSlug) {
51
+ const base = `feat/${slugify(taskSlug)}`;
52
+ let candidate = base;
53
+ let suffix = 2;
54
+ while (true) {
55
+ try {
56
+ this.run(`git show-ref --verify --quiet refs/heads/${candidate}`);
57
+ candidate = `${base}-${suffix++}`;
58
+ } catch {
59
+ break;
60
+ }
61
+ }
62
+ this.run(`git switch -c ${candidate}`);
63
+ return candidate;
64
+ }
65
+
66
+ /**
67
+ * @param {string} override
68
+ * @param {{autoRecover?: boolean, taskSlug?: string}} options
69
+ */
70
+ check(override = "", { autoRecover = false, taskSlug = "implementation" } = {}) {
71
+ try {
72
+ const currentBranch = this.run("git rev-parse --abbrev-ref HEAD");
73
+ const isProtected = this.protectedBranches.includes(currentBranch);
74
+ if (!isProtected) return { blocked: false, branch: currentBranch, recovered: false };
75
+
76
+ if (override && override.trim().length >= 20) {
77
+ this.log(`AUTHORIZED BYPASS on '${currentBranch}': ${override.trim()}`);
78
+ return { blocked: false, branch: currentBranch, authorized: true, recovered: false };
79
+ }
80
+
81
+ if (autoRecover) {
82
+ const dirty = this.getDirtyState();
83
+ if (dirty.tracked.length > 0) {
84
+ const reason = `Unsafe tracked changes prevent Branch Gate Auto-Recovery: ${dirty.tracked.join(", ")}`;
85
+ this.log(`BLOCKED AUTO-RECOVERY on '${currentBranch}': ${reason}`);
86
+ return { blocked: true, branch: currentBranch, reason, dirtyState: dirty };
87
+ }
88
+
89
+ const recoveredBranch = this.createScopedBranch(taskSlug);
90
+ this.log(`AUTO-RECOVERED '${currentBranch}' -> '${recoveredBranch}'`);
91
+ return {
92
+ blocked: false,
93
+ branch: recoveredBranch,
94
+ branchBefore: currentBranch,
95
+ recovered: true,
96
+ dirtyState: dirty
97
+ };
98
+ }
99
+
100
+ const reason = override && override.trim().length < 20
101
+ ? "Override justification too short (min 20 chars)."
102
+ : `Direct commits to '${currentBranch}' are prohibited.`;
103
+ this.log(`BLOCKED ATTEMPT on '${currentBranch}': ${reason}`);
104
+ return {
105
+ blocked: true,
106
+ branch: currentBranch,
107
+ reason: `${reason} Enable safe auto-recovery or use AI_OVERRIDE with a concrete justification.`
108
+ };
109
+ } catch (error) {
110
+ return { blocked: false, branch: "unknown", error: error.message, recovered: false };
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,78 @@
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+
5
+ /**
6
+ * HandoffEngine - Bundles project context into a single Markdown packet.
7
+ */
8
+ export class HandoffEngine {
9
+ constructor({ cwd }) {
10
+ this.cwd = cwd;
11
+ }
12
+
13
+ /**
14
+ * Generates a handoff packet.
15
+ * @param {Object} data - Context data.
16
+ * @returns {Promise<string>} The generated packet content.
17
+ */
18
+ async generate({ taskId, author, status, specPaths = [], nextActions }) {
19
+ const timestamp = new Date().toISOString();
20
+
21
+ // 1. Collect Specs content
22
+ let specsContent = "";
23
+ for (const specPath of specPaths) {
24
+ const absolutePath = path.isAbsolute(specPath) ? specPath : path.join(this.cwd, specPath);
25
+ try {
26
+ const content = await fs.readFile(absolutePath, "utf8");
27
+ specsContent += `### File: ${specPath}\n\n${content}\n\n`;
28
+ } catch (err) {
29
+ specsContent += `### File: ${specPath}\n\n[Error reading file: ${err.message}]\n\n`;
30
+ }
31
+ }
32
+
33
+ // 2. Capture Git Diff
34
+ let gitDiff = "No changes detected.";
35
+ try {
36
+ gitDiff = execSync("git diff HEAD", { cwd: this.cwd, encoding: "utf8" }).trim() || "No changes detected.";
37
+ } catch (err) {
38
+ gitDiff = `[Error capturing diff: ${err.message}]`;
39
+ }
40
+
41
+ // 3. Read EVIDENCE.json
42
+ let evidenceJson = "{}";
43
+ let evidenceSummary = "No evidence found.";
44
+ const evidencePath = path.join(this.cwd, "EVIDENCE.json");
45
+ try {
46
+ const content = await fs.readFile(evidencePath, "utf8");
47
+ const data = JSON.parse(content);
48
+ evidenceJson = JSON.stringify(data, null, 2);
49
+ evidenceSummary = `Status: ${data.status}, Commands: ${data.commands?.length || 0}`;
50
+ } catch (err) {
51
+ // Optional: don't fail if evidence is missing
52
+ }
53
+
54
+ // 4. Populate Template
55
+ const templatePath = path.join(import.meta.dirname, "../../../dist-assets/templates/HANDOFF.template.md");
56
+ let template = await fs.readFile(templatePath, "utf8");
57
+
58
+ const packet = template
59
+ .replace("${TASK_ID}", taskId || "unknown")
60
+ .replace("${TIMESTAMP}", timestamp)
61
+ .replace("${AUTHOR}", author || "AI Workflow Kit")
62
+ .replace("${STATUS}", status || "IN_PROGRESS")
63
+ .replace("${SPECS_CONTENT}", specsContent || "No specs provided.")
64
+ .replace("${EVIDENCE_SUMMARY}", evidenceSummary)
65
+ .replace("${EVIDENCE_JSON}", evidenceJson)
66
+ .replace("${GIT_DIFF}", gitDiff)
67
+ .replace("${NEXT_ACTIONS}", nextActions || "Awaiting manager assignment.");
68
+
69
+ const handoffDir = path.join(this.cwd, ".ai-workflow/handoffs");
70
+ await fs.mkdir(handoffDir, { recursive: true });
71
+
72
+ const packetName = `HANDOFF-${taskId || "TMP"}-${Date.now()}.md`;
73
+ const packetPath = path.join(handoffDir, packetName);
74
+ await fs.writeFile(packetPath, packet);
75
+
76
+ return packetPath;
77
+ }
78
+ }