@cubis/foundry 0.3.76 → 0.3.78

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 (276) hide show
  1. package/dist/cli/build/commands.js +19 -0
  2. package/dist/cli/build/commands.js.map +1 -0
  3. package/dist/cli/commands/register.js +4 -0
  4. package/dist/cli/commands/register.js.map +1 -1
  5. package/dist/cli/core.js +844 -25
  6. package/dist/cli/core.js.map +1 -1
  7. package/mcp/src/tools/skillTools.test.ts +34 -1
  8. package/package.json +4 -3
  9. package/src/cli/build/commands.ts +39 -0
  10. package/src/cli/commands/register.ts +6 -0
  11. package/src/cli/core.ts +1026 -28
  12. package/workflows/skills/_schema/skill-platform-attributes.json +7 -0
  13. package/workflows/skills/deep-research/SKILL.md +81 -0
  14. package/workflows/skills/deep-research/evals/assertions.md +17 -0
  15. package/workflows/skills/deep-research/evals/evals.json +56 -0
  16. package/workflows/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  17. package/workflows/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  18. package/workflows/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  19. package/workflows/skills/deep-research/references/comparison-checklist.md +57 -0
  20. package/workflows/skills/deep-research/references/research-output.md +69 -0
  21. package/workflows/skills/deep-research/references/source-ladder.md +81 -0
  22. package/workflows/skills/generated/skill-audit.json +20 -2
  23. package/workflows/skills/generated/skill-catalog.json +70 -4
  24. package/workflows/skills/skills_index.json +66 -0
  25. package/workflows/skills/spec-driven-delivery/SKILL.md +63 -0
  26. package/workflows/workflows/agent-environment-setup/generated/route-manifest.json +123 -10
  27. package/workflows/workflows/agent-environment-setup/manifest.json +48 -1
  28. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/orchestrator.md +6 -5
  29. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/project-planner.md +4 -3
  30. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/researcher.md +8 -4
  31. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/accessibility.toml +10 -3
  32. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/architecture.toml +19 -0
  33. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/backend.toml +10 -3
  34. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/create.toml +10 -3
  35. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/database.toml +10 -3
  36. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/debug.toml +10 -3
  37. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/devops.toml +10 -3
  38. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/implement-track.toml +10 -3
  39. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/migrate.toml +10 -3
  40. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/mobile.toml +10 -3
  41. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/onboard.toml +10 -3
  42. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/orchestrate.toml +10 -3
  43. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/plan.toml +10 -3
  44. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/refactor.toml +10 -3
  45. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/release.toml +10 -3
  46. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/review.toml +10 -3
  47. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/security.toml +10 -3
  48. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/spec.toml +19 -0
  49. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/test.toml +10 -3
  50. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/vercel.toml +10 -3
  51. package/workflows/workflows/agent-environment-setup/platforms/antigravity/rules/GEMINI.md +15 -8
  52. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/SKILL.md +89 -0
  53. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/evals/assertions.md +17 -0
  54. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/evals/evals.json +56 -0
  55. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  56. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  57. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  58. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/comparison-checklist.md +57 -0
  59. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/research-output.md +69 -0
  60. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/source-ladder.md +81 -0
  61. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/spec-driven-delivery/SKILL.md +65 -0
  62. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/architecture.md +82 -0
  63. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/backend.md +3 -0
  64. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/create.md +4 -1
  65. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/database.md +3 -0
  66. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/implement-track.md +7 -1
  67. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/migrate.md +4 -1
  68. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/mobile.md +3 -0
  69. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/onboard.md +4 -3
  70. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/orchestrate.md +8 -3
  71. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/plan.md +16 -6
  72. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/refactor.md +3 -0
  73. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/release.md +3 -0
  74. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/spec.md +81 -0
  75. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/orchestrator.md +6 -5
  76. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/project-planner.md +4 -3
  77. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/researcher.md +8 -4
  78. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/README.md +15 -0
  79. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/route-research-guard.mjs +39 -0
  80. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/settings.snippet.json +15 -0
  81. package/workflows/workflows/agent-environment-setup/platforms/claude/rules/CLAUDE.md +17 -8
  82. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/SKILL.md +95 -0
  83. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/evals/assertions.md +17 -0
  84. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/evals/evals.json +56 -0
  85. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  86. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  87. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  88. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/comparison-checklist.md +57 -0
  89. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/research-output.md +69 -0
  90. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/source-ladder.md +81 -0
  91. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/skills_index.json +66 -0
  92. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/spec-driven-delivery/SKILL.md +66 -0
  93. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/architecture.md +80 -0
  94. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/backend.md +3 -0
  95. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/create.md +4 -1
  96. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/database.md +3 -0
  97. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/implement-track.md +7 -1
  98. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/migrate.md +4 -1
  99. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/mobile.md +3 -0
  100. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/onboard.md +4 -3
  101. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/orchestrate.md +8 -3
  102. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/plan.md +16 -6
  103. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/refactor.md +3 -0
  104. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/release.md +3 -0
  105. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/spec.md +79 -0
  106. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/backend-specialist.md +1 -1
  107. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/code-archaeologist.md +1 -1
  108. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/database-architect.md +1 -1
  109. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/debugger.md +1 -1
  110. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/devops-engineer.md +1 -1
  111. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/documentation-writer.md +1 -1
  112. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/frontend-specialist.md +1 -1
  113. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/game-developer.md +1 -1
  114. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/mobile-developer.md +1 -1
  115. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/orchestrator.md +7 -6
  116. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/penetration-tester.md +1 -1
  117. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/performance-optimizer.md +1 -1
  118. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/product-manager.md +1 -1
  119. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/project-planner.md +5 -4
  120. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/qa-automation-engineer.md +1 -1
  121. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/researcher.md +9 -5
  122. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/security-auditor.md +1 -1
  123. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/seo-specialist.md +1 -1
  124. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/sre-engineer.md +1 -1
  125. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/test-engineer.md +1 -1
  126. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/validator.md +1 -1
  127. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/vercel-expert.md +1 -1
  128. package/workflows/workflows/agent-environment-setup/platforms/codex/rules/AGENTS.md +15 -8
  129. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/SKILL.md +89 -0
  130. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/evals/assertions.md +17 -0
  131. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/evals/evals.json +56 -0
  132. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  133. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  134. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  135. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/comparison-checklist.md +57 -0
  136. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/research-output.md +69 -0
  137. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/source-ladder.md +81 -0
  138. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/spec-driven-delivery/SKILL.md +65 -0
  139. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/accessibility.md +1 -1
  140. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/architecture.md +82 -0
  141. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/backend.md +4 -1
  142. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/create.md +5 -2
  143. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/database.md +4 -1
  144. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/debug.md +1 -1
  145. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/devops.md +1 -1
  146. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/implement-track.md +8 -2
  147. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/migrate.md +5 -2
  148. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/mobile.md +4 -1
  149. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/onboard.md +5 -4
  150. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/orchestrate.md +9 -4
  151. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/plan.md +17 -7
  152. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/refactor.md +4 -1
  153. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/release.md +4 -1
  154. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/review.md +1 -1
  155. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/security.md +1 -1
  156. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/spec.md +81 -0
  157. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/test.md +1 -1
  158. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/vercel.md +1 -1
  159. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/orchestrator.md +6 -5
  160. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/project-planner.md +4 -3
  161. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/researcher.md +8 -4
  162. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-accessibility.prompt.md +9 -3
  163. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-architecture.prompt.md +18 -0
  164. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-backend.prompt.md +9 -3
  165. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-create.prompt.md +9 -3
  166. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-database.prompt.md +9 -3
  167. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-debug.prompt.md +9 -3
  168. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-devops.prompt.md +9 -3
  169. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-implement-track.prompt.md +9 -3
  170. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-migrate.prompt.md +9 -3
  171. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-mobile.prompt.md +9 -3
  172. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-onboard.prompt.md +9 -3
  173. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-orchestrate.prompt.md +9 -3
  174. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-plan.prompt.md +9 -3
  175. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-refactor.prompt.md +9 -3
  176. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-release.prompt.md +9 -3
  177. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-review.prompt.md +9 -3
  178. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-security.prompt.md +9 -3
  179. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-spec.prompt.md +18 -0
  180. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-test.prompt.md +9 -3
  181. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-vercel.prompt.md +9 -3
  182. package/workflows/workflows/agent-environment-setup/platforms/copilot/rules/copilot-instructions.md +15 -8
  183. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/SKILL.md +94 -0
  184. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/evals/assertions.md +17 -0
  185. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/evals/evals.json +56 -0
  186. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  187. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  188. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  189. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/comparison-checklist.md +57 -0
  190. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/research-output.md +69 -0
  191. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/source-ladder.md +81 -0
  192. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/skills_index.json +66 -0
  193. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/spec-driven-delivery/SKILL.md +70 -0
  194. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/architecture.md +80 -0
  195. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/backend.md +3 -0
  196. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/create.md +4 -1
  197. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/database.md +3 -0
  198. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/implement-track.md +7 -1
  199. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/migrate.md +4 -1
  200. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/mobile.md +3 -0
  201. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/onboard.md +4 -3
  202. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/orchestrate.md +8 -3
  203. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/plan.md +16 -6
  204. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/refactor.md +3 -0
  205. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/release.md +3 -0
  206. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/spec.md +79 -0
  207. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/accessibility.toml +10 -3
  208. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/architecture.toml +19 -0
  209. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/backend.toml +10 -3
  210. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/create.toml +10 -3
  211. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/database.toml +10 -3
  212. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/debug.toml +10 -3
  213. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/devops.toml +10 -3
  214. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/implement-track.toml +10 -3
  215. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/migrate.toml +10 -3
  216. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/mobile.toml +10 -3
  217. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/onboard.toml +10 -3
  218. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/orchestrate.toml +10 -3
  219. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/plan.toml +10 -3
  220. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/refactor.toml +10 -3
  221. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/release.toml +10 -3
  222. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/review.toml +10 -3
  223. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/security.toml +10 -3
  224. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/spec.toml +19 -0
  225. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/test.toml +10 -3
  226. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/vercel.toml +10 -3
  227. package/workflows/workflows/agent-environment-setup/platforms/gemini/rules/GEMINI.md +15 -8
  228. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/SKILL.md +89 -0
  229. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/evals/assertions.md +17 -0
  230. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/evals/evals.json +56 -0
  231. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  232. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  233. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  234. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/comparison-checklist.md +57 -0
  235. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/research-output.md +69 -0
  236. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/source-ladder.md +81 -0
  237. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/spec-driven-delivery/SKILL.md +65 -0
  238. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/architecture.md +82 -0
  239. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/backend.md +3 -0
  240. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/create.md +4 -1
  241. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/database.md +3 -0
  242. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/implement-track.md +7 -1
  243. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/migrate.md +4 -1
  244. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/mobile.md +3 -0
  245. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/onboard.md +4 -3
  246. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/orchestrate.md +8 -3
  247. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/plan.md +16 -6
  248. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/refactor.md +3 -0
  249. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/release.md +3 -0
  250. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/spec.md +81 -0
  251. package/workflows/workflows/agent-environment-setup/shared/agents/backend-specialist.md +5 -5
  252. package/workflows/workflows/agent-environment-setup/shared/agents/database-architect.md +3 -3
  253. package/workflows/workflows/agent-environment-setup/shared/agents/orchestrator.md +10 -9
  254. package/workflows/workflows/agent-environment-setup/shared/agents/penetration-tester.md +3 -3
  255. package/workflows/workflows/agent-environment-setup/shared/agents/product-manager.md +6 -6
  256. package/workflows/workflows/agent-environment-setup/shared/agents/project-planner.md +10 -9
  257. package/workflows/workflows/agent-environment-setup/shared/agents/researcher.md +13 -9
  258. package/workflows/workflows/agent-environment-setup/shared/agents/security-auditor.md +2 -2
  259. package/workflows/workflows/agent-environment-setup/shared/rules/STEERING.md +57 -13
  260. package/workflows/workflows/agent-environment-setup/shared/rules/overrides/claude.md +2 -0
  261. package/workflows/workflows/agent-environment-setup/shared/rules/overrides/codex.md +3 -3
  262. package/workflows/workflows/agent-environment-setup/shared/rules/overrides/gemini.md +20 -0
  263. package/workflows/workflows/agent-environment-setup/shared/workflows/architecture.md +80 -0
  264. package/workflows/workflows/agent-environment-setup/shared/workflows/backend.md +8 -5
  265. package/workflows/workflows/agent-environment-setup/shared/workflows/create.md +5 -2
  266. package/workflows/workflows/agent-environment-setup/shared/workflows/database.md +6 -3
  267. package/workflows/workflows/agent-environment-setup/shared/workflows/implement-track.md +12 -6
  268. package/workflows/workflows/agent-environment-setup/shared/workflows/migrate.md +7 -4
  269. package/workflows/workflows/agent-environment-setup/shared/workflows/mobile.md +3 -0
  270. package/workflows/workflows/agent-environment-setup/shared/workflows/onboard.md +6 -5
  271. package/workflows/workflows/agent-environment-setup/shared/workflows/orchestrate.md +10 -5
  272. package/workflows/workflows/agent-environment-setup/shared/workflows/plan.md +18 -8
  273. package/workflows/workflows/agent-environment-setup/shared/workflows/refactor.md +5 -2
  274. package/workflows/workflows/agent-environment-setup/shared/workflows/release.md +3 -0
  275. package/workflows/workflows/agent-environment-setup/shared/workflows/security.md +2 -2
  276. package/workflows/workflows/agent-environment-setup/shared/workflows/spec.md +79 -0
package/src/cli/core.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  symlink,
15
15
  writeFile,
16
16
  } from "node:fs/promises";
17
+ import { createHash } from "node:crypto";
17
18
  import { createRequire } from "node:module";
18
19
  import { spawn, execFile as execFileCallback } from "node:child_process";
19
20
  import os from "node:os";
@@ -60,6 +61,14 @@ const ENGINEERING_RULES_FILE_BLOCK_START_RE =
60
61
  /<!--\s*cbx:engineering:rules:start[^>]*-->/g;
61
62
  const ENGINEERING_RULES_FILE_BLOCK_END_RE =
62
63
  /<!--\s*cbx:engineering:rules:end\s*-->/g;
64
+ const ENGINEERING_ARCHITECTURE_BLOCK_START_RE =
65
+ /<!--\s*cbx:architecture:rules:start[^>]*-->/g;
66
+ const ENGINEERING_ARCHITECTURE_BLOCK_END_RE =
67
+ /<!--\s*cbx:architecture:rules:end\s*-->/g;
68
+ const TECH_ARCHITECTURE_BLOCK_START_RE =
69
+ /<!--\s*cbx:architecture:tech:start[^>]*-->/g;
70
+ const TECH_ARCHITECTURE_BLOCK_END_RE =
71
+ /<!--\s*cbx:architecture:tech:end\s*-->/g;
63
72
  const COPILOT_ALLOWED_SKILL_FRONTMATTER_KEYS = new Set([
64
73
  "compatibility",
65
74
  "description",
@@ -174,17 +183,20 @@ const WORKFLOW_PROFILES = {
174
183
  workflowDirs: [".claude/workflows"],
175
184
  agentDirs: [".claude/agents"],
176
185
  skillDirs: [".claude/skills"],
186
+ hookDirs: [".claude/hooks"],
177
187
  ruleFilesByPriority: ["CLAUDE.md"],
178
188
  },
179
189
  global: {
180
190
  workflowDirs: ["~/.claude/workflows"],
181
191
  agentDirs: ["~/.claude/agents"],
182
192
  skillDirs: ["~/.claude/skills"],
193
+ hookDirs: ["~/.claude/hooks"],
183
194
  ruleFilesByPriority: ["~/.claude/CLAUDE.md"],
184
195
  },
185
196
  detectorPaths: [
186
197
  "CLAUDE.md",
187
198
  ".claude",
199
+ ".claude/hooks",
188
200
  ".claude/rules",
189
201
  ".claude/settings.json",
190
202
  ],
@@ -250,11 +262,18 @@ const PLAYWRIGHT_MCP_URL = `http://localhost:${PLAYWRIGHT_DEFAULT_PORT}/mcp`;
250
262
  const POSTMAN_WORKSPACE_MANUAL_CHOICE = "__postman_workspace_manual__";
251
263
  const CBX_CONFIG_FILENAME = "cbx_config.json";
252
264
  const CBX_CREDENTIALS_ENV_FILENAME = "credentials.env";
265
+ const ARCHITECTURE_BUILD_METADATA_FILENAME = "architecture-build.json";
253
266
  const LEGACY_POSTMAN_CONFIG_FILENAME = ["postman", "setting.json"].join("_");
254
267
  const DEFAULT_CREDENTIAL_PROFILE_NAME = "default";
255
268
  const RESERVED_CREDENTIAL_PROFILE_NAMES = new Set(["all"]);
256
269
  const CREDENTIAL_SERVICES = new Set(["postman", "stitch"]);
257
270
  const MCP_RUNTIMES = new Set(["docker", "local"]);
271
+ const ARCHITECTURE_BUILD_PLATFORMS = new Set([
272
+ "codex",
273
+ "claude",
274
+ "gemini",
275
+ "copilot",
276
+ ]);
258
277
  const MCP_FALLBACKS = new Set(["local", "fail", "skip"]);
259
278
  const MCP_UPDATE_POLICIES = new Set(["pinned", "latest"]);
260
279
  const DEFAULT_MCP_RUNTIME = "docker";
@@ -954,6 +973,219 @@ function buildAntigravityTerminalVerificationBlock({
954
973
  ].join("\n");
955
974
  }
956
975
 
976
+ function hashStableObject(value) {
977
+ return createHash("sha256")
978
+ .update(JSON.stringify(value))
979
+ .digest("hex")
980
+ .slice(0, 12);
981
+ }
982
+
983
+ function firstNonEmpty(values) {
984
+ for (const value of values || []) {
985
+ if (value) return value;
986
+ }
987
+ return null;
988
+ }
989
+
990
+ function inferArchitectureContractProfile(snapshot) {
991
+ const allSignals = [];
992
+ for (const app of snapshot.architectureByApp || []) {
993
+ for (const signal of app.architectureSignals || []) {
994
+ if (!allSignals.includes(signal)) allSignals.push(signal);
995
+ }
996
+ }
997
+
998
+ const style =
999
+ firstNonEmpty([
1000
+ allSignals.find((signal) => /clean architecture/i.test(signal)),
1001
+ allSignals.find((signal) => /hexagonal/i.test(signal)),
1002
+ allSignals.find((signal) => /feature-first/i.test(signal)),
1003
+ allSignals.find((signal) => /mvvm/i.test(signal)),
1004
+ allSignals.find((signal) => /mvc/i.test(signal)),
1005
+ ]) || "Undeclared — align to current repository conventions";
1006
+
1007
+ const moduleBoundaries = snapshot.annotatedDirs
1008
+ .slice(0, 8)
1009
+ .map(({ name, purpose }) =>
1010
+ purpose ? `${name}/ (${purpose})` : `${name}/`,
1011
+ );
1012
+
1013
+ const dependencyRules = [];
1014
+ if (/clean architecture/i.test(style)) {
1015
+ dependencyRules.push(
1016
+ "Domain code must not depend on infrastructure, framework, or presentation layers.",
1017
+ );
1018
+ dependencyRules.push(
1019
+ "Adapters may depend inward on domain contracts, never the reverse.",
1020
+ );
1021
+ } else if (/hexagonal/i.test(style)) {
1022
+ dependencyRules.push(
1023
+ "Ports stay stable at the boundary; adapters implement them without leaking infrastructure concerns inward.",
1024
+ );
1025
+ } else {
1026
+ dependencyRules.push(
1027
+ "Respect existing feature and package boundaries; avoid hidden cross-module imports.",
1028
+ );
1029
+ }
1030
+ dependencyRules.push(
1031
+ "Shared UI, data, and platform conventions belong in the declared common layer, not duplicated per feature.",
1032
+ );
1033
+
1034
+ const designSystemSource =
1035
+ firstNonEmpty([
1036
+ snapshot.topDirs.includes("components")
1037
+ ? "components/ is the primary shared UI surface."
1038
+ : null,
1039
+ snapshot.topDirs.includes("design-system")
1040
+ ? "design-system/ is the primary shared UI surface."
1041
+ : null,
1042
+ snapshot.topDirs.includes("app")
1043
+ ? "App-level UI patterns should be centralized and reused across screens."
1044
+ : null,
1045
+ ]) || "No dedicated design-system directory detected; infer shared UI rules from current components and screens.";
1046
+
1047
+ const testingStrategy = [];
1048
+ if (snapshot.keyScripts.some((script) => script.name === "lint")) {
1049
+ testingStrategy.push("Linting is part of the baseline quality gate.");
1050
+ }
1051
+ if (snapshot.keyScripts.some((script) => script.name.includes("type"))) {
1052
+ testingStrategy.push(
1053
+ "Static typing or analysis should pass before merge when the stack supports it.",
1054
+ );
1055
+ }
1056
+ if (snapshot.keyScripts.some((script) => script.name.startsWith("test"))) {
1057
+ testingStrategy.push(
1058
+ "Focused automated tests should cover the changed behavior before merge.",
1059
+ );
1060
+ }
1061
+ if (testingStrategy.length === 0) {
1062
+ testingStrategy.push(
1063
+ "Add focused validation evidence for non-trivial changes even when no standard test command is detected.",
1064
+ );
1065
+ }
1066
+
1067
+ const scalingConstraints = inferTechnicalConstraints(snapshot, {
1068
+ suggestedProfile: inferContextBudget(snapshot).suggestedProfile,
1069
+ });
1070
+
1071
+ const docUpdateTriggers = [
1072
+ "feature additions that change module boundaries or shared UI rules",
1073
+ "migrations, scale changes, or deployment-shape changes",
1074
+ "refactors that establish new conventions future work should follow",
1075
+ ];
1076
+
1077
+ return {
1078
+ style,
1079
+ moduleBoundaries,
1080
+ dependencyRules,
1081
+ designSystemSource,
1082
+ testingStrategy,
1083
+ scalingConstraints,
1084
+ docUpdateTriggers,
1085
+ };
1086
+ }
1087
+
1088
+ function buildArchitectureMermaid(snapshot) {
1089
+ const topDirs = snapshot.topDirs.slice(0, 4);
1090
+ const flowNodes = topDirs.length > 0 ? topDirs : ["src", "docs"];
1091
+ const lines = [
1092
+ "flowchart TD",
1093
+ ' user["User / Entry Point"] --> app["Application Surface"]',
1094
+ ];
1095
+ for (let index = 0; index < flowNodes.length; index += 1) {
1096
+ const nodeName = flowNodes[index].replace(/[^A-Za-z0-9]/g, "") || `N${index}`;
1097
+ lines.push(` app --> ${nodeName}["${flowNodes[index]}/"]`);
1098
+ }
1099
+ if (snapshot.isMcpServer || snapshot.mcpSignals.length > 0) {
1100
+ lines.push(' app --> mcp["MCP / Tooling Surface"]');
1101
+ }
1102
+ if (snapshot.cicdSignals.length > 0) {
1103
+ lines.push(' app --> deploy["Delivery / Runtime"]');
1104
+ }
1105
+ return lines.join("\n");
1106
+ }
1107
+
1108
+ function buildEngineeringArchitectureSection(snapshot) {
1109
+ const profile = inferArchitectureContractProfile(snapshot);
1110
+ const hash = hashStableObject(profile);
1111
+
1112
+ return [
1113
+ `<!-- cbx:architecture:rules:start version=1 profile=${hash} -->`,
1114
+ "## 10) Architecture Contract (auto-managed)",
1115
+ "",
1116
+ `- Declared style: ${profile.style}.`,
1117
+ `- Design-system source of truth: ${profile.designSystemSource}`,
1118
+ "- Dependency direction rules:",
1119
+ ...profile.dependencyRules.map((rule) => ` - ${rule}`),
1120
+ "- Module and package boundaries to preserve:",
1121
+ ...(profile.moduleBoundaries.length > 0
1122
+ ? profile.moduleBoundaries.map((rule) => ` - ${rule}`)
1123
+ : [" - No strong module boundary was detected automatically; keep new boundaries explicit in specs and ADRs."]),
1124
+ "- Testability expectations:",
1125
+ ...profile.testingStrategy.map((rule) => ` - ${rule}`),
1126
+ "- Doc refresh policy:",
1127
+ " - Update these managed sections when architecture, scale, boundaries, design-system rules, or testing strategy changes.",
1128
+ " - For non-trivial work, read this file before planning and read TECH.md next.",
1129
+ "<!-- cbx:architecture:rules:end -->",
1130
+ "",
1131
+ ].join("\n");
1132
+ }
1133
+
1134
+ function buildTechArchitectureSection(snapshot) {
1135
+ const profile = inferArchitectureContractProfile(snapshot);
1136
+ const payload = {
1137
+ style: profile.style,
1138
+ topDirs: snapshot.topDirs,
1139
+ frameworks: snapshot.frameworks,
1140
+ architectureByApp: snapshot.architectureByApp,
1141
+ };
1142
+ const hash = hashStableObject(payload);
1143
+ const architectureSignals = profile.style
1144
+ ? [`- Primary inferred style: ${profile.style}.`]
1145
+ : [];
1146
+
1147
+ return [
1148
+ `<!-- cbx:architecture:tech:start version=1 snapshot=${hash} -->`,
1149
+ "## Architecture Snapshot (auto-managed)",
1150
+ ...(architectureSignals.length > 0 ? ["", ...architectureSignals] : []),
1151
+ ...(snapshot.architectureByApp.length > 0
1152
+ ? [
1153
+ "- App-level structure signals:",
1154
+ ...snapshot.architectureByApp.slice(0, 6).map((item) => {
1155
+ const label = item.rootPath === "." ? "repo root" : item.rootPath;
1156
+ const signals =
1157
+ item.architectureSignals.length > 0
1158
+ ? item.architectureSignals.join(", ")
1159
+ : "not enough signals to classify";
1160
+ return ` - ${label}: ${signals}`;
1161
+ }),
1162
+ ]
1163
+ : ["- No app-level architecture signals detected automatically."]),
1164
+ "",
1165
+ "### Module / App Topology",
1166
+ ...(profile.moduleBoundaries.length > 0
1167
+ ? profile.moduleBoundaries.map((item) => `- ${item}`)
1168
+ : ["- No significant top-level module boundaries detected automatically."]),
1169
+ "",
1170
+ "### Flow Narratives",
1171
+ "- Describe the primary request, data, and background-job flows here when architecture generation runs.",
1172
+ "- Keep this section current when scale changes or new integration boundaries are introduced.",
1173
+ "",
1174
+ "### Mermaid Diagram",
1175
+ "```mermaid",
1176
+ buildArchitectureMermaid(snapshot),
1177
+ "```",
1178
+ "",
1179
+ "### Scaling / Deployment / Testing Snapshot",
1180
+ ...profile.scalingConstraints.map((item) => `- ${item}`),
1181
+ "",
1182
+ "### External Research Evidence",
1183
+ "- Reserved for `cbx build architecture --research auto|always` when outside evidence informs the architecture notes.",
1184
+ "<!-- cbx:architecture:tech:end -->",
1185
+ "",
1186
+ ].join("\n");
1187
+ }
1188
+
957
1189
  function buildEngineeringRulesTemplate() {
958
1190
  return [
959
1191
  "# Engineering Rules",
@@ -1036,6 +1268,21 @@ function buildEngineeringRulesTemplate() {
1036
1268
  "",
1037
1269
  "- `TECH.md` is generated from current codebase reality.",
1038
1270
  "- Re-run `cbx rules tech-md --overwrite` after major stack or architecture changes.",
1271
+ "",
1272
+ "<!-- cbx:architecture:rules:start version=1 profile=bootstrap -->",
1273
+ "## 10) Architecture Contract (auto-managed)",
1274
+ "",
1275
+ "- Declared style: bootstrap placeholder. Re-run `cbx build architecture --platform <codex|claude|gemini|copilot>` to refresh this contract from the repo.",
1276
+ "- Design-system source of truth: bootstrap placeholder.",
1277
+ "- Dependency direction rules:",
1278
+ " - Replace this placeholder with the managed architecture block when architecture generation runs.",
1279
+ "- Module and package boundaries to preserve:",
1280
+ " - Replace this placeholder with the managed architecture block when architecture generation runs.",
1281
+ "- Testability expectations:",
1282
+ " - Replace this placeholder with the managed architecture block when architecture generation runs.",
1283
+ "- Doc refresh policy:",
1284
+ " - Update this section when architecture, scale, boundaries, design-system rules, or testing strategy changes.",
1285
+ "<!-- cbx:architecture:rules:end -->",
1039
1286
  "<!-- cbx:engineering:rules:end -->",
1040
1287
  "",
1041
1288
  ].join("\n");
@@ -1065,10 +1312,11 @@ function buildEngineeringRulesManagedBlock({
1065
1312
  "2. Keep architecture simple (KISS) and avoid speculative work (YAGNI).",
1066
1313
  "3. Apply SOLID pragmatically to reduce change risk, not add ceremony.",
1067
1314
  "4. Use clear naming with focused responsibilities and explicit boundaries.",
1068
- "5. Require validation evidence (lint/types/tests) before merge.",
1069
- "6. Use Decision Log response style.",
1070
- "7. Every Decision Log must include a `Skills Used` section listing skill, workflow, or agent names.",
1071
- "8. If no skill loaded, `Skills Used: none` is mandatory.",
1315
+ "5. For non-trivial work, read ENGINEERING_RULES.md first and TECH.md next before planning or implementation.",
1316
+ "6. Require validation evidence (lint/types/tests) before merge.",
1317
+ "7. Use Decision Log response style.",
1318
+ "8. Every Decision Log must include a `Skills Used` section listing skill, workflow, or agent names.",
1319
+ "9. If no skill loaded, `Skills Used: none` is mandatory.",
1072
1320
  "",
1073
1321
  "<!-- cbx:engineering:auto:end -->",
1074
1322
  ].join("\n");
@@ -1251,6 +1499,130 @@ async function upsertEngineeringRulesBlock({
1251
1499
  };
1252
1500
  }
1253
1501
 
1502
+ function extractTaggedMarkerAttribute(content, startPattern, key) {
1503
+ const match = String(content || "").match(startPattern);
1504
+ if (!match || !match[0]) return null;
1505
+ const attributeMatch = match[0].match(new RegExp(`${key}=([^\\s>]+)`));
1506
+ return attributeMatch?.[1] || null;
1507
+ }
1508
+
1509
+ async function upsertTaggedSectionInFile({
1510
+ targetPath,
1511
+ initialContent,
1512
+ block,
1513
+ startPattern,
1514
+ endPattern,
1515
+ dryRun = false,
1516
+ }) {
1517
+ const exists = await pathExists(targetPath);
1518
+ const original = exists ? await readFile(targetPath, "utf8") : initialContent;
1519
+ const analysis = analyzeTaggedBlock(original, startPattern, endPattern);
1520
+ let nextContent = original;
1521
+
1522
+ if (!exists || analysis.status === "absent") {
1523
+ const trimmed = String(original || "").trimEnd();
1524
+ nextContent =
1525
+ trimmed.length > 0 ? `${trimmed}\n\n${block}\n` : `${block}\n`;
1526
+ } else if (analysis.range) {
1527
+ nextContent = `${original.slice(0, analysis.range.start)}${block}${original.slice(analysis.range.end)}`;
1528
+ } else {
1529
+ const trimmed = String(original || "").trimEnd();
1530
+ nextContent =
1531
+ trimmed.length > 0 ? `${trimmed}\n\n${block}\n` : `${block}\n`;
1532
+ }
1533
+
1534
+ if (nextContent === original) {
1535
+ return {
1536
+ action: "unchanged",
1537
+ filePath: targetPath,
1538
+ };
1539
+ }
1540
+
1541
+ if (!dryRun) {
1542
+ await mkdir(path.dirname(targetPath), { recursive: true });
1543
+ await writeFile(targetPath, nextContent, "utf8");
1544
+ }
1545
+
1546
+ return {
1547
+ action: exists
1548
+ ? dryRun
1549
+ ? "would-patch"
1550
+ : "patched"
1551
+ : dryRun
1552
+ ? "would-create"
1553
+ : "created",
1554
+ filePath: targetPath,
1555
+ };
1556
+ }
1557
+
1558
+ function buildArchitectureBuildMetadata({
1559
+ platform,
1560
+ researchMode,
1561
+ rulesProfileHash,
1562
+ techSnapshotHash,
1563
+ }) {
1564
+ return {
1565
+ schemaVersion: 1,
1566
+ generatedBy: "cbx build architecture",
1567
+ generatedAt: new Date().toISOString(),
1568
+ platform,
1569
+ researchMode,
1570
+ rulesProfileHash,
1571
+ techSnapshotHash,
1572
+ };
1573
+ }
1574
+
1575
+ async function ensureArchitectureDocScaffold({
1576
+ workspaceRoot,
1577
+ snapshot,
1578
+ overwrite = false,
1579
+ dryRun = false,
1580
+ }) {
1581
+ const engineeringRulesPath = path.join(workspaceRoot, "ENGINEERING_RULES.md");
1582
+ const techMdPath = path.join(workspaceRoot, "TECH.md");
1583
+
1584
+ const rulesTemplate = buildEngineeringRulesTemplate();
1585
+ const rulesFileResult = await upsertEngineeringRulesFile({
1586
+ targetPath: engineeringRulesPath,
1587
+ template: rulesTemplate,
1588
+ overwrite,
1589
+ dryRun,
1590
+ });
1591
+ const rulesArchitectureResult = await upsertTaggedSectionInFile({
1592
+ targetPath: engineeringRulesPath,
1593
+ initialContent: `${rulesTemplate}\n`,
1594
+ block: buildEngineeringArchitectureSection(snapshot),
1595
+ startPattern: ENGINEERING_ARCHITECTURE_BLOCK_START_RE,
1596
+ endPattern: ENGINEERING_ARCHITECTURE_BLOCK_END_RE,
1597
+ dryRun,
1598
+ });
1599
+
1600
+ const techContent = `${buildTechMd(snapshot)}\n`;
1601
+ const techResult = await writeTextFile({
1602
+ targetPath: techMdPath,
1603
+ content: techContent,
1604
+ overwrite,
1605
+ dryRun,
1606
+ });
1607
+ const techArchitectureResult = await upsertTaggedSectionInFile({
1608
+ targetPath: techMdPath,
1609
+ initialContent: techContent,
1610
+ block: buildTechArchitectureSection(snapshot),
1611
+ startPattern: TECH_ARCHITECTURE_BLOCK_START_RE,
1612
+ endPattern: TECH_ARCHITECTURE_BLOCK_END_RE,
1613
+ dryRun,
1614
+ });
1615
+
1616
+ return {
1617
+ engineeringRulesPath,
1618
+ techMdPath,
1619
+ rulesFileResult,
1620
+ rulesArchitectureResult,
1621
+ techResult,
1622
+ techArchitectureResult,
1623
+ };
1624
+ }
1625
+
1254
1626
  function normalizeTechPackageName(value) {
1255
1627
  if (value === undefined || value === null) return null;
1256
1628
  const normalized = String(value)
@@ -2230,7 +2602,7 @@ function inferRecommendedSkills(snapshot) {
2230
2602
  hasFramework("Mongoose") ||
2231
2603
  hasFramework("SQLAlchemy")
2232
2604
  ) {
2233
- recommended.add("database-skills");
2605
+ recommended.add("database-design");
2234
2606
  }
2235
2607
 
2236
2608
  if (recommended.size === 0) {
@@ -2561,6 +2933,9 @@ function buildTechMd(snapshot, { compact = false } = {}) {
2561
2933
  );
2562
2934
  lines.push("");
2563
2935
 
2936
+ lines.push(buildTechArchitectureSection(snapshot).trimEnd());
2937
+ lines.push("");
2938
+
2564
2939
  if (!compact) {
2565
2940
  lines.push("## Package Signals");
2566
2941
  appendTechPackageSection(
@@ -2783,6 +3158,7 @@ async function recordBundleInstallState({
2783
3158
  skills: artifacts.skills.map(toPosixPath),
2784
3159
  commands: (artifacts.commands || []).map(toPosixPath),
2785
3160
  prompts: (artifacts.prompts || []).map(toPosixPath),
3161
+ hooks: (artifacts.hooks || []).map(toPosixPath),
2786
3162
  };
2787
3163
 
2788
3164
  await writeState(scope, state, cwd);
@@ -2815,6 +3191,7 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
2815
3191
  const skillDirs = Array.isArray(cfg.skillDirs) ? cfg.skillDirs : [];
2816
3192
  const commandDirs = Array.isArray(cfg.commandDirs) ? cfg.commandDirs : [];
2817
3193
  const promptDirs = Array.isArray(cfg.promptDirs) ? cfg.promptDirs : [];
3194
+ const hookDirs = Array.isArray(cfg.hookDirs) ? cfg.hookDirs : [];
2818
3195
 
2819
3196
  const resolvePreferredDir = async (dirs) => {
2820
3197
  if (dirs.length === 0) return null;
@@ -2831,6 +3208,7 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
2831
3208
  skillsDir: await resolvePreferredDir(skillDirs),
2832
3209
  commandsDir: commandDirs[0] ? expandPath(commandDirs[0], cwd) : null,
2833
3210
  promptsDir: promptDirs[0] ? expandPath(promptDirs[0], cwd) : null,
3211
+ hooksDir: hookDirs[0] ? expandPath(hookDirs[0], cwd) : null,
2834
3212
  ruleFilesByPriority: cfg.ruleFilesByPriority.map((filePath) =>
2835
3213
  expandPath(filePath, cwd),
2836
3214
  ),
@@ -2862,6 +3240,7 @@ function resolveProfilePathCandidates(profileId, scope, cwd = process.cwd()) {
2862
3240
  skillsDirs: expandUniquePaths(cfg.skillDirs, cwd),
2863
3241
  commandsDirs: expandUniquePaths(cfg.commandDirs, cwd),
2864
3242
  promptsDirs: expandUniquePaths(cfg.promptDirs, cwd),
3243
+ hooksDirs: expandUniquePaths(cfg.hookDirs, cwd),
2865
3244
  ruleFilesByPriority: expandUniquePaths(cfg.ruleFilesByPriority, cwd),
2866
3245
  };
2867
3246
  }
@@ -2895,6 +3274,7 @@ async function resolveArtifactProfilePaths(
2895
3274
  agentsDir: workspacePaths.agentsDir,
2896
3275
  commandsDir: workspacePaths.commandsDir ?? scopedPaths.commandsDir,
2897
3276
  promptsDir: workspacePaths.promptsDir ?? scopedPaths.promptsDir,
3277
+ hooksDir: scopedPaths.hooksDir,
2898
3278
  };
2899
3279
  }
2900
3280
 
@@ -6681,6 +7061,13 @@ async function installBundleArtifacts({
6681
7061
  ) {
6682
7062
  await mkdir(profilePaths.promptsDir, { recursive: true });
6683
7063
  }
7064
+ if (
7065
+ profilePaths.hooksDir &&
7066
+ Array.isArray(platformSpec.hooks) &&
7067
+ platformSpec.hooks.some((entry) => typeof entry?.file === "string")
7068
+ ) {
7069
+ await mkdir(profilePaths.hooksDir, { recursive: true });
7070
+ }
6684
7071
  }
6685
7072
 
6686
7073
  const bundleRoot = path.join(agentAssetsRoot(), "workflows", bundleId);
@@ -6694,6 +7081,7 @@ async function installBundleArtifacts({
6694
7081
  skills: [],
6695
7082
  commands: [],
6696
7083
  prompts: [],
7084
+ hooks: [],
6697
7085
  };
6698
7086
 
6699
7087
  // Bind useSymlinks into copyArtifact so every call site inherits it
@@ -6806,6 +7194,40 @@ async function installBundleArtifacts({
6806
7194
  skipped.push(destination);
6807
7195
  else installed.push(destination);
6808
7196
  }
7197
+ const hookFiles = Array.isArray(platformSpec.hooks)
7198
+ ? platformSpec.hooks
7199
+ .map((entry) =>
7200
+ typeof entry === "string"
7201
+ ? entry
7202
+ : typeof entry?.file === "string"
7203
+ ? entry.file
7204
+ : null,
7205
+ )
7206
+ .filter(Boolean)
7207
+ : [];
7208
+ for (const hookFile of hookFiles) {
7209
+ if (!profilePaths.hooksDir) continue;
7210
+ const source = path.join(platformRoot, "hooks", hookFile);
7211
+ const destination = path.join(
7212
+ profilePaths.hooksDir,
7213
+ path.basename(hookFile),
7214
+ );
7215
+
7216
+ if (!(await pathExists(source))) {
7217
+ throw new Error(`Missing hook source file: ${source}`);
7218
+ }
7219
+
7220
+ const result = await copyArt({
7221
+ source,
7222
+ destination,
7223
+ overwrite,
7224
+ dryRun,
7225
+ });
7226
+ artifacts.hooks.push(destination);
7227
+ if (result.action === "skipped" || result.action === "would-skip")
7228
+ skipped.push(destination);
7229
+ else installed.push(destination);
7230
+ }
6809
7231
  if (shouldInstallPlatformSkills) {
6810
7232
  const agentSkillDependencies = await resolvePlatformAgentSkillDependencies({
6811
7233
  platformRoot,
@@ -7103,6 +7525,22 @@ async function removeBundleArtifacts({
7103
7525
  if (await safeRemove(destination, dryRun)) removed.push(destination);
7104
7526
  }
7105
7527
 
7528
+ for (const hookEntry of platformSpec.hooks || []) {
7529
+ if (!profilePaths.hooksDir) continue;
7530
+ const hookFile =
7531
+ typeof hookEntry === "string"
7532
+ ? hookEntry
7533
+ : typeof hookEntry?.file === "string"
7534
+ ? hookEntry.file
7535
+ : null;
7536
+ if (!hookFile) continue;
7537
+ const destination = path.join(
7538
+ profilePaths.hooksDir,
7539
+ path.basename(hookFile),
7540
+ );
7541
+ if (await safeRemove(destination, dryRun)) removed.push(destination);
7542
+ }
7543
+
7106
7544
  const skillIds = await resolveInstallSkillIds({
7107
7545
  platformSpec,
7108
7546
  extraSkillIds: [],
@@ -11871,6 +12309,13 @@ async function upsertEngineeringArtifacts({
11871
12309
  throw new Error(`No rule file configured for platform '${platform}'.`);
11872
12310
 
11873
12311
  const workspaceRoot = findWorkspaceRoot(cwd);
12312
+ const snapshot = await collectTechSnapshot(workspaceRoot);
12313
+ const scaffold = await ensureArchitectureDocScaffold({
12314
+ workspaceRoot,
12315
+ snapshot,
12316
+ overwrite,
12317
+ dryRun,
12318
+ });
11874
12319
  const techMdPath = path.join(workspaceRoot, "TECH.md");
11875
12320
  const targets = [{ ruleFilePath }];
11876
12321
 
@@ -11891,46 +12336,29 @@ async function upsertEngineeringArtifacts({
11891
12336
  }
11892
12337
  }
11893
12338
 
11894
- const template = buildEngineeringRulesTemplate();
11895
12339
  const engineeringResults = [];
11896
12340
  for (const target of targets) {
11897
- const rulesFilePath = path.join(
11898
- path.dirname(target.ruleFilePath),
11899
- "ENGINEERING_RULES.md",
11900
- );
11901
- const rulesFileResult = await upsertEngineeringRulesFile({
11902
- targetPath: rulesFilePath,
11903
- template,
11904
- overwrite,
11905
- dryRun,
11906
- });
11907
12341
  const blockResult = await upsertEngineeringRulesBlock({
11908
12342
  ruleFilePath: target.ruleFilePath,
11909
12343
  platform,
11910
- engineeringRulesFilePath: rulesFilePath,
12344
+ engineeringRulesFilePath: scaffold.engineeringRulesPath,
11911
12345
  techMdFilePath: techMdPath,
11912
12346
  dryRun,
11913
12347
  });
11914
12348
  engineeringResults.push({
11915
12349
  ruleFilePath: target.ruleFilePath,
11916
- rulesFilePath,
11917
- rulesFileResult,
12350
+ rulesFilePath: scaffold.engineeringRulesPath,
12351
+ rulesFileResult: scaffold.rulesArchitectureResult.action === "unchanged"
12352
+ ? scaffold.rulesFileResult
12353
+ : scaffold.rulesArchitectureResult,
11918
12354
  blockResult,
11919
12355
  });
11920
12356
  }
11921
12357
 
11922
12358
  let techResult = null;
11923
12359
  if (!skipTech) {
11924
- const snapshot = await collectTechSnapshot(workspaceRoot);
11925
- const content = buildTechMd(snapshot);
11926
- const fileResult = await writeTextFile({
11927
- targetPath: techMdPath,
11928
- content: `${content}\n`,
11929
- overwrite,
11930
- dryRun,
11931
- });
11932
12360
  techResult = {
11933
- ...fileResult,
12361
+ ...scaffold.techArchitectureResult,
11934
12362
  snapshot,
11935
12363
  };
11936
12364
  }
@@ -12015,6 +12443,575 @@ async function runRulesTechMd(options) {
12015
12443
  }
12016
12444
  }
12017
12445
 
12446
+ function normalizeArchitectureBuildPlatform(value) {
12447
+ const normalized = normalizePlatform(value);
12448
+ if (!normalized || !ARCHITECTURE_BUILD_PLATFORMS.has(normalized)) {
12449
+ throw new Error(
12450
+ "Architecture build platform must be one of: codex, claude, gemini, copilot.",
12451
+ );
12452
+ }
12453
+ return normalized;
12454
+ }
12455
+
12456
+ function normalizeArchitectureResearchMode(value) {
12457
+ const normalized = String(value || "auto")
12458
+ .trim()
12459
+ .toLowerCase();
12460
+ if (!["auto", "always", "never"].includes(normalized)) {
12461
+ throw new Error("Research mode must be one of: auto, always, never.");
12462
+ }
12463
+ return normalized;
12464
+ }
12465
+
12466
+ async function listSpecPackRoots(workspaceRoot) {
12467
+ const specsRoot = path.join(workspaceRoot, "docs", "specs");
12468
+ if (!(await pathExists(specsRoot))) return [];
12469
+ const entries = await readdir(specsRoot, { withFileTypes: true });
12470
+ return entries
12471
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
12472
+ .map((entry) => `docs/specs/${entry.name}`)
12473
+ .sort((a, b) => a.localeCompare(b))
12474
+ .slice(0, 8);
12475
+ }
12476
+
12477
+ function resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode) {
12478
+ const conditional = [];
12479
+ const frameworks = new Set(snapshot.frameworks || []);
12480
+ const topDirs = new Set(snapshot.topDirs || []);
12481
+ const jsPackages = new Set(snapshot.packageSignals?.javascript || []);
12482
+
12483
+ if (
12484
+ snapshot.isMcpServer ||
12485
+ frameworks.has("Next.js") ||
12486
+ frameworks.has("NestJS") ||
12487
+ frameworks.has("FastAPI") ||
12488
+ topDirs.has("api") ||
12489
+ topDirs.has("routes") ||
12490
+ topDirs.has("controllers")
12491
+ ) {
12492
+ conditional.push("api-design");
12493
+ }
12494
+
12495
+ if (
12496
+ topDirs.has("db") ||
12497
+ topDirs.has("database") ||
12498
+ topDirs.has("migrations") ||
12499
+ jsPackages.has("prisma") ||
12500
+ jsPackages.has("drizzle-orm") ||
12501
+ frameworks.has("SQLAlchemy")
12502
+ ) {
12503
+ conditional.push("database-design");
12504
+ }
12505
+
12506
+ if (specRoots.length > 0) {
12507
+ conditional.push("sadd");
12508
+ }
12509
+
12510
+ if (researchMode === "always") {
12511
+ conditional.push("deep-research");
12512
+ } else if (
12513
+ researchMode === "auto" &&
12514
+ !snapshot.readmeExcerpt &&
12515
+ snapshot.architectureByApp.every(
12516
+ (item) => (item.architectureSignals || []).length === 0,
12517
+ )
12518
+ ) {
12519
+ conditional.push("deep-research");
12520
+ }
12521
+
12522
+ return [...new Set(conditional)];
12523
+ }
12524
+
12525
+ async function resolveArchitectureSkillPathHints(platform, cwd, skillIds) {
12526
+ const profilePaths = await resolveProfilePaths(platform, "project", cwd);
12527
+ const skillsDir = profilePaths.skillsDir;
12528
+ if (!skillsDir) return [];
12529
+ return skillIds
12530
+ .map((skillId) => path.join(skillsDir, skillId, "SKILL.md"))
12531
+ .map((filePath) => toPosixPath(path.relative(findWorkspaceRoot(cwd), filePath)));
12532
+ }
12533
+
12534
+ function buildArchitecturePrompt({
12535
+ platform,
12536
+ workspaceRoot,
12537
+ snapshot,
12538
+ specRoots,
12539
+ researchMode,
12540
+ coreSkills,
12541
+ conditionalSkills,
12542
+ skillPathHints,
12543
+ }) {
12544
+ const rulesPath = "ENGINEERING_RULES.md";
12545
+ const techPath = "TECH.md";
12546
+ const architectureSignals = snapshot.architectureByApp
12547
+ .filter((item) => (item.architectureSignals || []).length > 0)
12548
+ .map((item) => {
12549
+ const label = item.rootPath === "." ? "repo root" : item.rootPath;
12550
+ return `${label}: ${item.architectureSignals.join(", ")}`;
12551
+ });
12552
+
12553
+ return [
12554
+ `You are running inside ${platform}.`,
12555
+ "",
12556
+ "Objective:",
12557
+ `- Inspect the repository at ${toPosixPath(workspaceRoot)} and refresh the managed architecture sections in ${rulesPath} and ${techPath}.`,
12558
+ "- Keep ENGINEERING_RULES.md normative and TECH.md descriptive.",
12559
+ "- Preserve manual content outside the managed `cbx:architecture:*` markers.",
12560
+ "",
12561
+ "Required skill bundle:",
12562
+ `- Load these exact skill IDs first: ${coreSkills.map((skillId) => `\`${skillId}\``).join(", ")}`,
12563
+ conditionalSkills.length > 0
12564
+ ? `- Additional skills to load now: ${conditionalSkills.map((skillId) => `\`${skillId}\``).join(", ")}`
12565
+ : "- Conditional skills to load now: none",
12566
+ skillPathHints.length > 0
12567
+ ? `- Local skill file hints if installed: ${skillPathHints.map((hint) => `\`${hint}\``).join(", ")}`
12568
+ : "- Local skill file hints if installed: none detected",
12569
+ "- Treat the route and skill bundle as already resolved. Do not begin with route discovery.",
12570
+ "",
12571
+ "Repository context:",
12572
+ `- Frameworks: ${snapshot.frameworks.length > 0 ? snapshot.frameworks.join(", ") : "none detected"}`,
12573
+ `- Top directories: ${snapshot.topDirs.length > 0 ? snapshot.topDirs.join(", ") : "none detected"}`,
12574
+ `- Existing spec packs: ${specRoots.length > 0 ? specRoots.join(", ") : "none detected"}`,
12575
+ architectureSignals.length > 0
12576
+ ? `- Architecture signals: ${architectureSignals.join(" | ")}`
12577
+ : "- Architecture signals: none confidently inferred from the repo scan",
12578
+ "",
12579
+ "Execution contract:",
12580
+ "1. Read ENGINEERING_RULES.md first if present, then read TECH.md.",
12581
+ "2. Inspect the repo before making architecture claims.",
12582
+ "3. Update only the content between the existing `cbx:architecture:rules` and `cbx:architecture:tech` markers.",
12583
+ "4. Keep the marker lines themselves intact, including their hash metadata.",
12584
+ "5. In ENGINEERING_RULES.md, state architecture style, dependency rules, feature or module structure rules, design-system source of truth, testability expectations, and doc refresh policy.",
12585
+ "6. In TECH.md, update architecture snapshot, module or app topology, flow narratives, Mermaid diagrams, and scaling or deployment notes.",
12586
+ researchMode === "never"
12587
+ ? "7. Stay repo-only. Do not use outside research."
12588
+ : "7. Use repo evidence first. Use official docs when needed. Treat Reddit or community sources only as labeled secondary evidence.",
12589
+ researchMode === "always"
12590
+ ? "8. Include an external research evidence subsection in TECH.md with clearly labeled primary and secondary evidence."
12591
+ : "8. Include external research notes only if they materially informed the architecture update.",
12592
+ "9. If the project clearly follows Clean Architecture, feature-first modules, or another stable structure, make that explicit so future implementation stays consistent.",
12593
+ "",
12594
+ "Return one JSON object on the last line with this shape:",
12595
+ '{"files_written":["ENGINEERING_RULES.md","TECH.md"],"research_used":false,"gaps":[],"next_actions":[]}',
12596
+ "",
12597
+ "Do not emit placeholder TODOs in the managed sections.",
12598
+ ].join("\n");
12599
+ }
12600
+
12601
+ async function execFileCapture(command, args, options = {}) {
12602
+ try {
12603
+ const result = await execFile(command, args, {
12604
+ ...options,
12605
+ maxBuffer: 8 * 1024 * 1024,
12606
+ });
12607
+ return {
12608
+ ok: true,
12609
+ stdout: result.stdout || "",
12610
+ stderr: result.stderr || "",
12611
+ };
12612
+ } catch (error) {
12613
+ if (error?.code === "ENOENT") {
12614
+ throw new Error(`Required CLI '${command}' is not installed or not on PATH.`);
12615
+ }
12616
+ return {
12617
+ ok: false,
12618
+ stdout: error?.stdout || "",
12619
+ stderr: error?.stderr || "",
12620
+ code: error?.code || 1,
12621
+ };
12622
+ }
12623
+ }
12624
+
12625
+ async function probeArchitectureAdapter(platform, cwd) {
12626
+ if (platform === "codex") {
12627
+ const help = await execFileCapture("codex", ["exec", "--help"], { cwd });
12628
+ return {
12629
+ platform,
12630
+ binary: "codex",
12631
+ helpText: `${help.stdout}\n${help.stderr}`.trim(),
12632
+ buildInvocation(prompt) {
12633
+ const args = ["exec"];
12634
+ if (this.helpText.includes("--skip-git-repo-check")) {
12635
+ args.push("--skip-git-repo-check");
12636
+ }
12637
+ args.push(prompt);
12638
+ return args;
12639
+ },
12640
+ };
12641
+ }
12642
+
12643
+ if (platform === "claude") {
12644
+ const help = await execFileCapture("claude", ["--help"], { cwd });
12645
+ const helpText = `${help.stdout}\n${help.stderr}`.trim();
12646
+ const printFlag = helpText.includes("--print")
12647
+ ? "--print"
12648
+ : helpText.includes(" -p") || helpText.includes("\n-p")
12649
+ ? "-p"
12650
+ : null;
12651
+ if (!printFlag) {
12652
+ throw new Error(
12653
+ "Claude CLI was found, but no headless print mode was detected. Install a Claude Code build that supports --print or -p.",
12654
+ );
12655
+ }
12656
+ return {
12657
+ platform,
12658
+ binary: "claude",
12659
+ helpText,
12660
+ buildInvocation(prompt) {
12661
+ return [printFlag, prompt];
12662
+ },
12663
+ };
12664
+ }
12665
+
12666
+ if (platform === "gemini") {
12667
+ const help = await execFileCapture("gemini", ["--help"], { cwd });
12668
+ const helpText = `${help.stdout}\n${help.stderr}`.trim();
12669
+ const promptFlag = helpText.includes("--prompt")
12670
+ ? "--prompt"
12671
+ : helpText.includes(" -p") || helpText.includes("\n-p")
12672
+ ? "-p"
12673
+ : null;
12674
+ if (!promptFlag) {
12675
+ throw new Error(
12676
+ "Gemini CLI was found, but no prompt flag was detected. Install a Gemini CLI build with --prompt or -p support.",
12677
+ );
12678
+ }
12679
+ return {
12680
+ platform,
12681
+ binary: "gemini",
12682
+ helpText,
12683
+ buildInvocation(prompt) {
12684
+ return [promptFlag, prompt];
12685
+ },
12686
+ };
12687
+ }
12688
+
12689
+ const help = await execFileCapture("copilot", ["--help"], { cwd });
12690
+ const helpText = `${help.stdout}\n${help.stderr}`.trim();
12691
+ const supportsPrompt = helpText.includes("--prompt");
12692
+ const supportsChatPrompt =
12693
+ helpText.includes("chat") && helpText.includes("--prompt");
12694
+ if (!supportsPrompt && !supportsChatPrompt) {
12695
+ throw new Error(
12696
+ "Copilot CLI was found, but no headless prompt mode was detected. This command requires a native Copilot CLI surface with --prompt support.",
12697
+ );
12698
+ }
12699
+ return {
12700
+ platform,
12701
+ binary: "copilot",
12702
+ helpText,
12703
+ buildInvocation(prompt) {
12704
+ if (supportsPrompt) return ["--prompt", prompt];
12705
+ return ["chat", "--prompt", prompt];
12706
+ },
12707
+ };
12708
+ }
12709
+
12710
+ function normalizeArchitectureResult({
12711
+ stdout,
12712
+ workspaceRoot,
12713
+ rulesPath,
12714
+ techPath,
12715
+ researchMode,
12716
+ }) {
12717
+ const trimmed = String(stdout || "").trim();
12718
+ if (trimmed) {
12719
+ const lastLine = trimmed.split(/\r?\n/).pop();
12720
+ if (lastLine && lastLine.startsWith("{") && lastLine.endsWith("}")) {
12721
+ try {
12722
+ const parsed = JSON.parse(lastLine);
12723
+ return {
12724
+ outputRoot: workspaceRoot,
12725
+ filesWritten: Array.isArray(parsed.files_written)
12726
+ ? parsed.files_written
12727
+ : [rulesPath, techPath],
12728
+ researchUsed:
12729
+ typeof parsed.research_used === "boolean"
12730
+ ? parsed.research_used
12731
+ : researchMode === "always",
12732
+ gaps: Array.isArray(parsed.gaps) ? parsed.gaps : [],
12733
+ nextActions: Array.isArray(parsed.next_actions)
12734
+ ? parsed.next_actions
12735
+ : [],
12736
+ rawOutput: trimmed,
12737
+ };
12738
+ } catch {
12739
+ // fall through to default normalization
12740
+ }
12741
+ }
12742
+ }
12743
+
12744
+ return {
12745
+ outputRoot: workspaceRoot,
12746
+ filesWritten: [rulesPath, techPath],
12747
+ researchUsed: researchMode === "always",
12748
+ gaps: [],
12749
+ nextActions: [],
12750
+ rawOutput: trimmed,
12751
+ };
12752
+ }
12753
+
12754
+ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
12755
+ const rulesPath = path.join(workspaceRoot, "ENGINEERING_RULES.md");
12756
+ const techPath = path.join(workspaceRoot, "TECH.md");
12757
+ const metadataPath = path.join(
12758
+ workspaceRoot,
12759
+ ".cbx",
12760
+ ARCHITECTURE_BUILD_METADATA_FILENAME,
12761
+ );
12762
+ const rulesExists = await pathExists(rulesPath);
12763
+ const techExists = await pathExists(techPath);
12764
+
12765
+ const expectedRulesHash = hashStableObject(
12766
+ inferArchitectureContractProfile(snapshot),
12767
+ );
12768
+ const expectedTechHash = hashStableObject({
12769
+ style: inferArchitectureContractProfile(snapshot).style,
12770
+ topDirs: snapshot.topDirs,
12771
+ frameworks: snapshot.frameworks,
12772
+ architectureByApp: snapshot.architectureByApp,
12773
+ });
12774
+
12775
+ const findings = [];
12776
+ let actualRulesHash = null;
12777
+ let actualTechHash = null;
12778
+
12779
+ if (!rulesExists) {
12780
+ findings.push("ENGINEERING_RULES.md is missing.");
12781
+ } else {
12782
+ const content = await readFile(rulesPath, "utf8");
12783
+ actualRulesHash = extractTaggedMarkerAttribute(
12784
+ content,
12785
+ ENGINEERING_ARCHITECTURE_BLOCK_START_RE,
12786
+ "profile",
12787
+ );
12788
+ if (!actualRulesHash) {
12789
+ findings.push("ENGINEERING_RULES.md is missing the managed architecture contract block.");
12790
+ } else if (actualRulesHash !== expectedRulesHash) {
12791
+ findings.push(
12792
+ `ENGINEERING_RULES.md architecture profile is stale (expected ${expectedRulesHash}, found ${actualRulesHash}).`,
12793
+ );
12794
+ }
12795
+ }
12796
+
12797
+ if (!techExists) {
12798
+ findings.push("TECH.md is missing.");
12799
+ } else {
12800
+ const content = await readFile(techPath, "utf8");
12801
+ actualTechHash = extractTaggedMarkerAttribute(
12802
+ content,
12803
+ TECH_ARCHITECTURE_BLOCK_START_RE,
12804
+ "snapshot",
12805
+ );
12806
+ if (!actualTechHash) {
12807
+ findings.push("TECH.md is missing the managed architecture snapshot block.");
12808
+ } else if (actualTechHash !== expectedTechHash) {
12809
+ findings.push(
12810
+ `TECH.md architecture snapshot is stale (expected ${expectedTechHash}, found ${actualTechHash}).`,
12811
+ );
12812
+ }
12813
+ }
12814
+
12815
+ const metadata = await readJsonFileIfExists(metadataPath);
12816
+ if (!metadata.exists) {
12817
+ findings.push("Architecture build metadata is missing.");
12818
+ }
12819
+
12820
+ return {
12821
+ stale: findings.length > 0,
12822
+ findings,
12823
+ rulesPath,
12824
+ techPath,
12825
+ metadataPath,
12826
+ expectedRulesHash,
12827
+ expectedTechHash,
12828
+ actualRulesHash,
12829
+ actualTechHash,
12830
+ };
12831
+ }
12832
+
12833
+ async function runBuildArchitecture(options) {
12834
+ try {
12835
+ const platform = normalizeArchitectureBuildPlatform(options.platform);
12836
+ const researchMode = normalizeArchitectureResearchMode(options.research);
12837
+ const overwrite = Boolean(options.overwrite);
12838
+ const dryRun = Boolean(options.dryRun);
12839
+ const emitJson = Boolean(options.json);
12840
+ const checkOnly = Boolean(options.check);
12841
+ const cwd = process.cwd();
12842
+ const workspaceRoot = findWorkspaceRoot(cwd);
12843
+ const snapshot = await collectTechSnapshot(workspaceRoot);
12844
+
12845
+ if (checkOnly) {
12846
+ const drift = await readArchitectureDriftStatus(workspaceRoot, snapshot);
12847
+ if (emitJson) {
12848
+ console.log(JSON.stringify(drift, null, 2));
12849
+ } else {
12850
+ console.log(`Platform: ${platform}`);
12851
+ console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
12852
+ console.log(`Status: ${drift.stale ? "stale" : "fresh"}`);
12853
+ if (drift.findings.length > 0) {
12854
+ console.log("Findings:");
12855
+ for (const finding of drift.findings) {
12856
+ console.log(`- ${finding}`);
12857
+ }
12858
+ }
12859
+ }
12860
+ if (drift.stale) process.exit(1);
12861
+ return;
12862
+ }
12863
+
12864
+ const scaffold = await ensureArchitectureDocScaffold({
12865
+ workspaceRoot,
12866
+ snapshot,
12867
+ overwrite,
12868
+ dryRun,
12869
+ });
12870
+ const specRoots = await listSpecPackRoots(workspaceRoot);
12871
+ const coreSkills = [
12872
+ "architecture-doc",
12873
+ "system-design",
12874
+ "tech-doc",
12875
+ "frontend-design",
12876
+ ];
12877
+ const conditionalSkills = resolveArchitectureConditionalSkills(
12878
+ snapshot,
12879
+ specRoots,
12880
+ researchMode,
12881
+ );
12882
+ const skillBundle = [...coreSkills, ...conditionalSkills];
12883
+ const skillPathHints = await resolveArchitectureSkillPathHints(
12884
+ platform,
12885
+ cwd,
12886
+ skillBundle,
12887
+ );
12888
+ const prompt = buildArchitecturePrompt({
12889
+ platform,
12890
+ workspaceRoot,
12891
+ snapshot,
12892
+ specRoots,
12893
+ researchMode,
12894
+ coreSkills,
12895
+ conditionalSkills,
12896
+ skillPathHints,
12897
+ });
12898
+ const adapter = await probeArchitectureAdapter(platform, workspaceRoot);
12899
+ const args = adapter.buildInvocation(prompt);
12900
+
12901
+ if (dryRun) {
12902
+ const summary = {
12903
+ platform,
12904
+ workspaceRoot: toPosixPath(workspaceRoot),
12905
+ adapter: adapter.binary,
12906
+ invocation: [adapter.binary, ...args],
12907
+ researchMode,
12908
+ managedTargets: [
12909
+ toPosixPath(scaffold.engineeringRulesPath),
12910
+ toPosixPath(scaffold.techMdPath),
12911
+ ],
12912
+ skillBundle,
12913
+ };
12914
+ if (emitJson) {
12915
+ console.log(JSON.stringify(summary, null, 2));
12916
+ } else {
12917
+ console.log(`Platform: ${platform}`);
12918
+ console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
12919
+ console.log(`Adapter: ${adapter.binary}`);
12920
+ console.log(`Research mode: ${researchMode}`);
12921
+ console.log(
12922
+ `Managed targets: ${toPosixPath(scaffold.engineeringRulesPath)}, ${toPosixPath(scaffold.techMdPath)}`,
12923
+ );
12924
+ console.log(`Skill bundle: ${skillBundle.join(", ")}`);
12925
+ console.log(`Invocation: ${[adapter.binary, ...args].join(" ")}`);
12926
+ }
12927
+ return;
12928
+ }
12929
+
12930
+ const execution = await execFileCapture(adapter.binary, args, {
12931
+ cwd: workspaceRoot,
12932
+ env: process.env,
12933
+ });
12934
+ if (!execution.ok) {
12935
+ throw new Error(
12936
+ `Architecture build failed via ${adapter.binary}. ${String(execution.stderr || execution.stdout || "").trim()}`,
12937
+ );
12938
+ }
12939
+
12940
+ const rulesContent = await readFile(scaffold.engineeringRulesPath, "utf8");
12941
+ const techContent = await readFile(scaffold.techMdPath, "utf8");
12942
+ const metadataPath = path.join(
12943
+ workspaceRoot,
12944
+ ".cbx",
12945
+ ARCHITECTURE_BUILD_METADATA_FILENAME,
12946
+ );
12947
+ const metadata = buildArchitectureBuildMetadata({
12948
+ platform,
12949
+ researchMode,
12950
+ rulesProfileHash:
12951
+ extractTaggedMarkerAttribute(
12952
+ rulesContent,
12953
+ ENGINEERING_ARCHITECTURE_BLOCK_START_RE,
12954
+ "profile",
12955
+ ) || "unknown",
12956
+ techSnapshotHash:
12957
+ extractTaggedMarkerAttribute(
12958
+ techContent,
12959
+ TECH_ARCHITECTURE_BLOCK_START_RE,
12960
+ "snapshot",
12961
+ ) || "unknown",
12962
+ });
12963
+ await mkdir(path.dirname(metadataPath), { recursive: true });
12964
+ await writeFile(
12965
+ metadataPath,
12966
+ `${JSON.stringify(metadata, null, 2)}\n`,
12967
+ "utf8",
12968
+ );
12969
+
12970
+ const result = normalizeArchitectureResult({
12971
+ stdout: execution.stdout,
12972
+ workspaceRoot: toPosixPath(workspaceRoot),
12973
+ rulesPath: "ENGINEERING_RULES.md",
12974
+ techPath: "TECH.md",
12975
+ researchMode,
12976
+ });
12977
+
12978
+ if (emitJson) {
12979
+ console.log(
12980
+ JSON.stringify(
12981
+ {
12982
+ platform,
12983
+ adapter: adapter.binary,
12984
+ skillBundle,
12985
+ result,
12986
+ },
12987
+ null,
12988
+ 2,
12989
+ ),
12990
+ );
12991
+ return;
12992
+ }
12993
+
12994
+ console.log(`Platform: ${platform}`);
12995
+ console.log(`Adapter: ${adapter.binary}`);
12996
+ console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
12997
+ console.log(`Managed docs: ENGINEERING_RULES.md, TECH.md`);
12998
+ console.log(`Skill bundle: ${skillBundle.join(", ")}`);
12999
+ console.log(
13000
+ `Files written: ${(result.filesWritten || []).join(", ") || "(none reported)"}`,
13001
+ );
13002
+ console.log(`Research used: ${result.researchUsed ? "yes" : "no"}`);
13003
+ if (result.gaps.length > 0) {
13004
+ console.log(`Gaps: ${result.gaps.join("; ")}`);
13005
+ }
13006
+ if (result.nextActions.length > 0) {
13007
+ console.log(`Next actions: ${result.nextActions.join("; ")}`);
13008
+ }
13009
+ } catch (error) {
13010
+ console.error(`\nError: ${error.message}`);
13011
+ process.exit(1);
13012
+ }
13013
+ }
13014
+
12018
13015
  function parseCsvOption(value) {
12019
13016
  return String(value || "")
12020
13017
  .split(",")
@@ -12401,6 +13398,7 @@ export function buildCliProgram() {
12401
13398
  defaultMcpDockerContainerName: DEFAULT_MCP_DOCKER_CONTAINER_NAME,
12402
13399
  runRulesInit,
12403
13400
  runRulesTechMd,
13401
+ runBuildArchitecture,
12404
13402
  });
12405
13403
  }
12406
13404