@jaimevalasek/aioson 1.7.0 → 1.8.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 (383) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/README.md +153 -10
  3. package/docs/en/cli-reference.md +56 -1
  4. package/docs/en/i18n.md +18 -18
  5. package/docs/en/schemas/index.json +10 -0
  6. package/docs/en/schemas/parallel-assign.schema.json +9 -0
  7. package/docs/en/schemas/parallel-doctor.schema.json +36 -0
  8. package/docs/en/schemas/parallel-guard.schema.json +63 -0
  9. package/docs/en/schemas/parallel-merge.schema.json +84 -0
  10. package/docs/en/schemas/parallel-status.schema.json +91 -1
  11. package/docs/integrations/apps-publish-marketplace.md +94 -0
  12. package/docs/pt/README.md +9 -0
  13. package/docs/pt/agentes.md +324 -3
  14. package/docs/pt/clientes-ai.md +7 -3
  15. package/docs/pt/comandos-cli.md +160 -13
  16. package/docs/pt/compress-agents.md +304 -0
  17. package/docs/pt/design-docs-governance.md +59 -0
  18. package/docs/pt/feature-archive.md +191 -0
  19. package/docs/pt/genome-3.0-spec.md +115 -4
  20. package/docs/pt/genome-distribution.md +232 -0
  21. package/docs/pt/inicio-rapido.md +1 -0
  22. package/docs/pt/motor-hardening.md +492 -0
  23. package/docs/pt/runner-system.md +113 -0
  24. package/package.json +2 -1
  25. package/src/agent-manifests.js +66 -0
  26. package/src/agents.js +27 -7
  27. package/src/autonomy-policy.js +139 -0
  28. package/src/brain-query.js +161 -0
  29. package/src/cli.js +1377 -1099
  30. package/src/commands/agents.js +102 -7
  31. package/src/commands/artifact-validate.js +33 -4
  32. package/src/commands/auth.js +272 -0
  33. package/src/commands/brain-query.js +44 -0
  34. package/src/commands/briefing.js +344 -0
  35. package/src/commands/commit-prepare.js +547 -0
  36. package/src/commands/compress-agents.js +416 -0
  37. package/src/commands/context-health.js +4 -2
  38. package/src/commands/context-trim.js +17 -11
  39. package/src/commands/design-hybrid-options.js +3 -3
  40. package/src/commands/devlog-process.js +6 -4
  41. package/src/commands/dossier.js +423 -0
  42. package/src/commands/feature-archive.js +513 -0
  43. package/src/commands/feature-close.js +123 -18
  44. package/src/commands/gate-approve.js +198 -0
  45. package/src/commands/gate-check.js +24 -5
  46. package/src/commands/genome-doctor.js +166 -9
  47. package/src/commands/git-guard.js +170 -0
  48. package/src/commands/harness.js +121 -0
  49. package/src/commands/implementation-plan.js +47 -20
  50. package/src/commands/init.js +6 -2
  51. package/src/commands/install.js +6 -2
  52. package/src/commands/live.js +497 -56
  53. package/src/commands/locale-apply.js +9 -6
  54. package/src/commands/locale-diff.js +11 -112
  55. package/src/commands/mcp-doctor.js +2 -1
  56. package/src/commands/mcp-init.js +4 -10
  57. package/src/commands/memory.js +234 -0
  58. package/src/commands/parallel-assign.js +107 -27
  59. package/src/commands/parallel-doctor.js +416 -3
  60. package/src/commands/parallel-guard.js +241 -0
  61. package/src/commands/parallel-init.js +66 -4
  62. package/src/commands/parallel-merge.js +299 -0
  63. package/src/commands/parallel-status.js +147 -3
  64. package/src/commands/preflight.js +63 -4
  65. package/src/commands/qa-init.js +10 -5
  66. package/src/commands/revision.js +235 -0
  67. package/src/commands/scaffold-complete.js +188 -0
  68. package/src/commands/security-audit.js +275 -0
  69. package/src/commands/security-scan.js +376 -0
  70. package/src/commands/self-implement-loop.js +46 -2
  71. package/src/commands/setup-context.js +11 -10
  72. package/src/commands/squad-agent-create.js +51 -9
  73. package/src/commands/squad-investigate.js +53 -0
  74. package/src/commands/squad-plan.js +33 -1
  75. package/src/commands/squad-scaffold.js +4 -3
  76. package/src/commands/squad-score.js +71 -14
  77. package/src/commands/squad-status.js +22 -1
  78. package/src/commands/squad-validate.js +93 -2
  79. package/src/commands/store-genome.js +304 -0
  80. package/src/commands/store-skill.js +247 -0
  81. package/src/commands/store-squad.js +431 -0
  82. package/src/commands/store-system.js +392 -0
  83. package/src/commands/tool-capabilities.js +63 -0
  84. package/src/commands/update.js +3 -3
  85. package/src/commands/verify-gate.js +40 -0
  86. package/src/commands/workflow-execute.js +644 -155
  87. package/src/commands/workflow-harden.js +231 -0
  88. package/src/commands/workflow-heal.js +136 -0
  89. package/src/commands/workflow-next.js +460 -22
  90. package/src/commands/workflow-status.js +328 -138
  91. package/src/commands/workspace.js +144 -0
  92. package/src/constants.js +55 -75
  93. package/src/context-memory.js +133 -4
  94. package/src/context-writer.js +2 -1
  95. package/src/context.js +32 -2
  96. package/src/doctor.js +46 -6
  97. package/src/dossier/codemap-store.js +267 -0
  98. package/src/dossier/dossier-bootstrap.js +222 -0
  99. package/src/dossier/dossier-compact.js +159 -0
  100. package/src/dossier/lock.js +128 -0
  101. package/src/dossier/revision-store.js +313 -0
  102. package/src/dossier/schema.js +155 -0
  103. package/src/dossier/store.js +400 -0
  104. package/src/execution-gateway.js +3 -0
  105. package/src/friction-scanner.js +202 -0
  106. package/src/genome-schema.js +24 -1
  107. package/src/genomes.js +33 -0
  108. package/src/handoff-contract.js +363 -0
  109. package/src/handoff-validator.js +45 -0
  110. package/src/harness/circuit-breaker.js +135 -0
  111. package/src/i18n/messages/en.js +317 -22
  112. package/src/i18n/messages/es.js +259 -18
  113. package/src/i18n/messages/fr.js +260 -18
  114. package/src/i18n/messages/pt-BR.js +313 -22
  115. package/src/install-profile.js +0 -16
  116. package/src/installer.js +70 -6
  117. package/src/lib/git-commit-guard.js +691 -0
  118. package/src/lib/security/artifact-reader.js +167 -0
  119. package/src/lib/security/exit-codes.js +51 -0
  120. package/src/lib/security/findings-writer.js +176 -0
  121. package/src/lib/security/runtime-events.js +77 -0
  122. package/src/lib/security/secrets-regex.js +115 -0
  123. package/src/lib/store/security-scan.js +173 -0
  124. package/src/lib/terminal-checkbox.js +130 -0
  125. package/src/lib/tmux-launcher.js +163 -0
  126. package/src/lib/tool-capabilities.js +102 -0
  127. package/src/locales.js +12 -8
  128. package/src/parallel-workspace.js +756 -0
  129. package/src/parser.js +8 -1
  130. package/src/path-guard.js +47 -0
  131. package/src/preflight-engine.js +237 -26
  132. package/src/self-healing.js +142 -0
  133. package/src/session-handoff.js +111 -1
  134. package/src/squad/squad-scaffold.js +183 -19
  135. package/src/test-briefing.js +226 -0
  136. package/src/updater.js +1 -1
  137. package/src/utils.js +3 -0
  138. package/src/workflow-gates.js +185 -0
  139. package/template/.aioson/agents/analyst.md +76 -130
  140. package/template/.aioson/agents/architect.md +53 -86
  141. package/template/.aioson/agents/committer.md +161 -0
  142. package/template/.aioson/agents/copywriter.md +463 -0
  143. package/template/.aioson/agents/cypher.md +252 -0
  144. package/template/.aioson/agents/dev.md +112 -600
  145. package/template/.aioson/agents/deyvin.md +33 -235
  146. package/template/.aioson/agents/discover.md +235 -0
  147. package/template/.aioson/agents/discovery-design-doc.md +17 -252
  148. package/template/.aioson/agents/genome.md +76 -26
  149. package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
  150. package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
  151. package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
  152. package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
  153. package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
  154. package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
  155. package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
  156. package/template/.aioson/agents/manifests/product.manifest.json +23 -0
  157. package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
  158. package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
  159. package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
  160. package/template/.aioson/agents/neo.md +10 -8
  161. package/template/.aioson/agents/orache.md +2 -6
  162. package/template/.aioson/agents/orchestrator.md +81 -182
  163. package/template/.aioson/agents/pentester.md +235 -0
  164. package/template/.aioson/agents/pm.md +40 -104
  165. package/template/.aioson/agents/product.md +99 -344
  166. package/template/.aioson/agents/profiler-enricher.md +57 -6
  167. package/template/.aioson/agents/profiler-forge.md +17 -7
  168. package/template/.aioson/agents/profiler-researcher.md +29 -6
  169. package/template/.aioson/agents/qa.md +165 -410
  170. package/template/.aioson/agents/setup.md +52 -262
  171. package/template/.aioson/agents/sheldon.md +122 -754
  172. package/template/.aioson/agents/site-forge.md +111 -1583
  173. package/template/.aioson/agents/squad.md +139 -1820
  174. package/template/.aioson/agents/tester.md +10 -0
  175. package/template/.aioson/agents/ux-ui.md +103 -645
  176. package/template/.aioson/agents/validator.md +69 -0
  177. package/template/.aioson/brains/scripts/query.js +5 -1
  178. package/template/.aioson/config/autonomy-protocol.json +43 -0
  179. package/template/.aioson/config.md +43 -15
  180. package/template/.aioson/constitution.md +36 -33
  181. package/template/.aioson/context/design-doc.md +136 -0
  182. package/template/.aioson/context/project-map.md +57 -0
  183. package/template/.aioson/design-docs/code-reuse.md +48 -0
  184. package/template/.aioson/design-docs/componentization.md +47 -0
  185. package/template/.aioson/design-docs/file-size.md +52 -0
  186. package/template/.aioson/design-docs/folder-structure.md +51 -0
  187. package/template/.aioson/design-docs/naming.md +54 -0
  188. package/template/.aioson/docs/LAYERS.md +12 -2
  189. package/template/.aioson/docs/dev/execution-discipline.md +106 -0
  190. package/template/.aioson/docs/dev/stack-conventions.md +83 -0
  191. package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
  192. package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
  193. package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
  194. package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
  195. package/template/.aioson/docs/product/conversation-playbook.md +116 -0
  196. package/template/.aioson/docs/product/prd-contract.md +107 -0
  197. package/template/.aioson/docs/product/quality-lens.md +57 -0
  198. package/template/.aioson/docs/product/research-loop.md +65 -0
  199. package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
  200. package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
  201. package/template/.aioson/docs/sheldon/research-loop.md +56 -0
  202. package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
  203. package/template/.aioson/docs/site-forge-build.md +195 -0
  204. package/template/.aioson/docs/site-forge-extraction.md +135 -0
  205. package/template/.aioson/docs/site-forge-qa.md +155 -0
  206. package/template/.aioson/docs/site-forge-recon.md +434 -0
  207. package/template/.aioson/docs/site-forge-transform.md +249 -0
  208. package/template/.aioson/docs/squad/content-output.md +91 -0
  209. package/template/.aioson/docs/squad/creation-flow.md +135 -0
  210. package/template/.aioson/docs/squad/domain-classification.md +117 -0
  211. package/template/.aioson/docs/squad/genome-bindings.md +47 -0
  212. package/template/.aioson/docs/squad/package-contract.md +234 -0
  213. package/template/.aioson/docs/squad/quality-lens.md +56 -0
  214. package/template/.aioson/docs/squad/research-loop.md +59 -0
  215. package/template/.aioson/docs/squad/session-operations.md +117 -0
  216. package/template/.aioson/docs/squad/workflow-quality.md +165 -0
  217. package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
  218. package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
  219. package/template/.aioson/docs/ux-ui/component-map.md +35 -0
  220. package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
  221. package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
  222. package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
  223. package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
  224. package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
  225. package/template/.aioson/genomes/copywriting.md +204 -0
  226. package/template/.aioson/genomes/copywriting.meta.json +48 -0
  227. package/template/.aioson/git-guard.json +11 -0
  228. package/template/.aioson/mcp/servers.md +0 -1
  229. package/template/.aioson/rules/agent-language-policy.md +93 -0
  230. package/template/.aioson/rules/aioson-context-boundary.md +63 -0
  231. package/template/.aioson/rules/canonical-path-contract.md +47 -0
  232. package/template/.aioson/rules/data-format-convention.md +24 -86
  233. package/template/.aioson/rules/disk-first-artifacts.md +44 -0
  234. package/template/.aioson/rules/output-brevity.md +44 -0
  235. package/template/.aioson/rules/prd-section-ownership.md +49 -0
  236. package/template/.aioson/rules/security-baseline.md +139 -0
  237. package/template/.aioson/rules/spec-level-ownership.md +61 -0
  238. package/template/.aioson/rules/squad-driver-pattern.md +81 -0
  239. package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
  240. package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
  241. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +2 -0
  242. package/template/.aioson/skills/marketing/references/anti-patterns.md +254 -0
  243. package/template/.aioson/skills/marketing/references/fascinations.md +192 -0
  244. package/template/.aioson/skills/marketing/references/five-acts.md +248 -0
  245. package/template/.aioson/skills/marketing/references/market-intelligence.md +198 -0
  246. package/template/.aioson/skills/marketing/references/offer-structure.md +203 -0
  247. package/template/.aioson/skills/marketing/references/one-belief.md +149 -0
  248. package/template/.aioson/skills/marketing/references/patterns.md +218 -0
  249. package/template/.aioson/skills/marketing/references/pms-research.md +193 -0
  250. package/template/.aioson/skills/marketing/vsl-craft.md +385 -0
  251. package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
  252. package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
  253. package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
  254. package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
  255. package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
  256. package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
  257. package/template/.aioson/skills/static/landing-page-deploy.md +192 -0
  258. package/template/.aioson/skills/static/landing-page-forge.md +730 -0
  259. package/template/.aioson/skills/static/ui-ux-modern.md +1 -0
  260. package/template/.aioson/skills/static/web-research-cache.md +3 -0
  261. package/template/.aioson/tasks/squad-create.md +56 -7
  262. package/template/.aioson/tasks/squad-design.md +80 -2
  263. package/template/.aioson/tasks/squad-investigate.md +14 -1
  264. package/template/.aioson/templates/squads/digital-marketing-agency/template.json +96 -0
  265. package/template/.claude/commands/aioson/agent/committer.md +5 -0
  266. package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
  267. package/template/.claude/commands/aioson/agent/cypher.md +5 -0
  268. package/template/.claude/commands/aioson/agent/pair.md +5 -0
  269. package/template/.claude/commands/aioson/agent/validator.md +5 -0
  270. package/template/.gemini/commands/aios-analyst.toml +6 -3
  271. package/template/.gemini/commands/aios-architect.toml +7 -6
  272. package/template/.gemini/commands/aios-committer.toml +7 -0
  273. package/template/.gemini/commands/aios-copywriter.toml +7 -0
  274. package/template/.gemini/commands/aios-cypher.toml +7 -0
  275. package/template/.gemini/commands/aios-dev.toml +8 -7
  276. package/template/.gemini/commands/aios-deyvin.toml +6 -5
  277. package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
  278. package/template/.gemini/commands/aios-genome.toml +7 -0
  279. package/template/.gemini/commands/aios-neo.toml +5 -3
  280. package/template/.gemini/commands/aios-orache.toml +7 -0
  281. package/template/.gemini/commands/aios-orchestrator.toml +8 -7
  282. package/template/.gemini/commands/aios-pair.toml +6 -5
  283. package/template/.gemini/commands/aios-pm.toml +8 -7
  284. package/template/.gemini/commands/aios-product.toml +5 -3
  285. package/template/.gemini/commands/aios-qa.toml +6 -5
  286. package/template/.gemini/commands/aios-setup.toml +5 -2
  287. package/template/.gemini/commands/aios-sheldon.toml +7 -0
  288. package/template/.gemini/commands/aios-site-forge.toml +7 -0
  289. package/template/.gemini/commands/aios-squad.toml +7 -0
  290. package/template/.gemini/commands/aios-tester.toml +6 -5
  291. package/template/.gemini/commands/aios-ux-ui.toml +8 -7
  292. package/template/.gemini/commands/aios-validator.toml +7 -0
  293. package/template/AGENTS.md +12 -1
  294. package/template/CLAUDE.md +6 -1
  295. package/template/.aioson/locales/en/agents/analyst.md +0 -244
  296. package/template/.aioson/locales/en/agents/architect.md +0 -245
  297. package/template/.aioson/locales/en/agents/dev.md +0 -397
  298. package/template/.aioson/locales/en/agents/deyvin.md +0 -137
  299. package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
  300. package/template/.aioson/locales/en/agents/genome.md +0 -212
  301. package/template/.aioson/locales/en/agents/neo.md +0 -8
  302. package/template/.aioson/locales/en/agents/orache.md +0 -6
  303. package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
  304. package/template/.aioson/locales/en/agents/pair.md +0 -5
  305. package/template/.aioson/locales/en/agents/pm.md +0 -84
  306. package/template/.aioson/locales/en/agents/product.md +0 -378
  307. package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
  308. package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
  309. package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
  310. package/template/.aioson/locales/en/agents/qa.md +0 -270
  311. package/template/.aioson/locales/en/agents/setup.md +0 -421
  312. package/template/.aioson/locales/en/agents/sheldon.md +0 -455
  313. package/template/.aioson/locales/en/agents/squad.md +0 -449
  314. package/template/.aioson/locales/en/agents/tester.md +0 -6
  315. package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
  316. package/template/.aioson/locales/es/agents/analyst.md +0 -225
  317. package/template/.aioson/locales/es/agents/architect.md +0 -245
  318. package/template/.aioson/locales/es/agents/dev.md +0 -370
  319. package/template/.aioson/locales/es/agents/deyvin.md +0 -99
  320. package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
  321. package/template/.aioson/locales/es/agents/genome.md +0 -104
  322. package/template/.aioson/locales/es/agents/neo.md +0 -50
  323. package/template/.aioson/locales/es/agents/orache.md +0 -105
  324. package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
  325. package/template/.aioson/locales/es/agents/pair.md +0 -7
  326. package/template/.aioson/locales/es/agents/pm.md +0 -90
  327. package/template/.aioson/locales/es/agents/product.md +0 -372
  328. package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
  329. package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
  330. package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
  331. package/template/.aioson/locales/es/agents/qa.md +0 -198
  332. package/template/.aioson/locales/es/agents/setup.md +0 -405
  333. package/template/.aioson/locales/es/agents/sheldon.md +0 -309
  334. package/template/.aioson/locales/es/agents/squad.md +0 -532
  335. package/template/.aioson/locales/es/agents/tester.md +0 -9
  336. package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
  337. package/template/.aioson/locales/fr/agents/analyst.md +0 -225
  338. package/template/.aioson/locales/fr/agents/architect.md +0 -245
  339. package/template/.aioson/locales/fr/agents/dev.md +0 -370
  340. package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
  341. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
  342. package/template/.aioson/locales/fr/agents/genome.md +0 -104
  343. package/template/.aioson/locales/fr/agents/neo.md +0 -50
  344. package/template/.aioson/locales/fr/agents/orache.md +0 -106
  345. package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
  346. package/template/.aioson/locales/fr/agents/pair.md +0 -7
  347. package/template/.aioson/locales/fr/agents/pm.md +0 -90
  348. package/template/.aioson/locales/fr/agents/product.md +0 -372
  349. package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
  350. package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
  351. package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
  352. package/template/.aioson/locales/fr/agents/qa.md +0 -198
  353. package/template/.aioson/locales/fr/agents/setup.md +0 -405
  354. package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
  355. package/template/.aioson/locales/fr/agents/squad.md +0 -532
  356. package/template/.aioson/locales/fr/agents/tester.md +0 -9
  357. package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
  358. package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
  359. package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
  360. package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
  361. package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
  362. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
  363. package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
  364. package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
  365. package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
  366. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
  367. package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
  368. package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
  369. package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
  370. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
  371. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
  372. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
  373. package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
  374. package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
  375. package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
  376. package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
  377. package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
  378. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
  379. package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
  380. package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
  381. package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
  382. package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
  383. package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
@@ -0,0 +1,198 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson gate:approve — approve a phase gate for a feature.
5
+ *
6
+ * Validates with gate:check before writing. If gate:check fails, blocks approval.
7
+ * Writes flat frontmatter fields to spec-{slug}.md:
8
+ * gate_requirements, gate_design, gate_plan, gate_execution
9
+ *
10
+ * Usage:
11
+ * aioson gate:approve . --feature=checkout --gate=C
12
+ * aioson gate:approve . --feature=checkout --gate=C --json
13
+ *
14
+ * If gate:check fails, shows exact manual fallback: file, field, and value to set.
15
+ */
16
+
17
+ const path = require('node:path');
18
+ const fs = require('node:fs/promises');
19
+ const {
20
+ contextDir,
21
+ readFileSafe,
22
+ fileExists,
23
+ parseFrontmatter,
24
+ parseGatesFromSpec,
25
+ GATE_NAMES,
26
+ GATE_ALIASES
27
+ } = require('../preflight-engine');
28
+ const { runGateCheck } = require('./gate-check');
29
+
30
+ const BAR = '━'.repeat(45);
31
+
32
+ const GATE_FLAT_FIELDS = {
33
+ A: 'gate_requirements',
34
+ B: 'gate_design',
35
+ C: 'gate_plan',
36
+ D: 'gate_execution'
37
+ };
38
+
39
+ const GATE_NEXT_AGENTS = {
40
+ A: { agent: '@architect', action: '/architect', why: 'Gate A (requirements) approved — architecture can proceed' },
41
+ B: { agent: '@pm', action: '/pm', why: 'Gate B (design) approved — implementation plan can be written' },
42
+ C: { agent: '@orchestrator or @dev', action: '/orchestrator (MEDIUM) or /dev (MICRO/SMALL)', why: 'Gate C (plan) approved — implementation can proceed' },
43
+ D: { agent: 'feature complete', action: 'mark feature done in features.md', why: 'Gate D (execution) approved — feature is complete' }
44
+ };
45
+
46
+ /**
47
+ * Update or insert a flat frontmatter field in a markdown file.
48
+ * Preserves all other frontmatter fields. Uses flat key: value format.
49
+ */
50
+ function updateFrontmatterField(content, field, value) {
51
+ const fmMatch = content.match(/^(---\r?\n)([\s\S]*?)(\r?\n---)/);
52
+ if (!fmMatch) {
53
+ // No frontmatter — prepend it
54
+ return `---\n${field}: ${value}\n---\n\n${content}`;
55
+ }
56
+
57
+ const prefix = fmMatch[1];
58
+ const fmBody = fmMatch[2];
59
+ const suffix = fmMatch[3];
60
+ const rest = content.slice(fmMatch[0].length);
61
+
62
+ const lines = fmBody.split(/\r?\n/);
63
+ let found = false;
64
+ const updated = lines.map((line) => {
65
+ const colonIdx = line.indexOf(':');
66
+ if (colonIdx === -1) return line;
67
+ const key = line.slice(0, colonIdx).trim();
68
+ if (key === field) {
69
+ found = true;
70
+ return `${field}: ${value}`;
71
+ }
72
+ return line;
73
+ });
74
+
75
+ if (!found) updated.push(`${field}: ${value}`);
76
+
77
+ return `${prefix}${updated.join('\n')}${suffix}${rest}`;
78
+ }
79
+
80
+ async function runGateApprove({ args, options = {}, logger }) {
81
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
82
+ const slug = options.feature ? String(options.feature) : null;
83
+ let gateLetter = options.gate ? String(options.gate).toUpperCase() : null;
84
+
85
+ if (!slug) {
86
+ if (options.json) return { ok: false, reason: 'missing_feature' };
87
+ logger.log('--feature=<slug> is required.');
88
+ return { ok: false };
89
+ }
90
+
91
+ if (!gateLetter) {
92
+ if (options.json) return { ok: false, reason: 'missing_gate' };
93
+ logger.log('--gate=<A|B|C|D> is required.');
94
+ return { ok: false };
95
+ }
96
+
97
+ // Resolve aliases
98
+ if (GATE_ALIASES[gateLetter.toLowerCase()]) {
99
+ gateLetter = GATE_ALIASES[gateLetter.toLowerCase()];
100
+ }
101
+
102
+ if (!GATE_NAMES[gateLetter]) {
103
+ if (options.json) return { ok: false, reason: 'invalid_gate', gate: gateLetter };
104
+ logger.log(`Invalid gate: ${gateLetter}. Use A, B, C, or D.`);
105
+ return { ok: false };
106
+ }
107
+
108
+ // Step 1: run gate:check first (AC-SDLC-06 — gate:approve fails if gate:check fails)
109
+ const silentLogger = { log: () => {} };
110
+ const check = await runGateCheck({
111
+ args: [targetDir],
112
+ options: { feature: slug, gate: gateLetter, json: true },
113
+ logger: silentLogger
114
+ });
115
+
116
+ const specFile = path.join(contextDir(targetDir), `spec-${slug}.md`);
117
+ const specExists = await fileExists(specFile);
118
+ const specFieldName = GATE_FLAT_FIELDS[gateLetter];
119
+ const gateName = GATE_NAMES[gateLetter];
120
+
121
+ if (!check.ok) {
122
+ // Gate check failed — block approval and show manual fallback (AC-SDLC-08)
123
+ const result = {
124
+ ok: false,
125
+ blocked: true,
126
+ gate: gateLetter,
127
+ gate_name: gateName,
128
+ feature: slug,
129
+ reason: 'gate_check_failed',
130
+ missing: check.missing || [],
131
+ manual_fallback: specExists
132
+ ? `To manually approve when prerequisites are met:\n File: .aioson/context/spec-${slug}.md\n Field: ${specFieldName}\n Value: approved`
133
+ : `spec-${slug}.md does not exist. Create it with ${specFieldName}: approved in frontmatter after prerequisites are satisfied.`
134
+ };
135
+
136
+ if (options.json) return result;
137
+
138
+ logger.log('');
139
+ logger.log(`Gate ${gateLetter} (${gateName}) — ${slug}`);
140
+ logger.log(BAR);
141
+ logger.log(`Result: ✗ BLOCKED — gate:check did not pass`);
142
+ logger.log('');
143
+ logger.log('Missing prerequisites:');
144
+ for (const m of check.missing || []) logger.log(` ✗ ${m}`);
145
+ logger.log('');
146
+ logger.log('Manual fallback (use only after all prerequisites are satisfied):');
147
+ logger.log(` File: .aioson/context/spec-${slug}.md`);
148
+ logger.log(` Field: ${specFieldName}`);
149
+ logger.log(` Value: approved`);
150
+ logger.log('');
151
+ logger.log('Tip: re-run gate:check after satisfying prerequisites, then gate:approve again.');
152
+ logger.log('');
153
+ return result;
154
+ }
155
+
156
+ // Step 2: write flat frontmatter field (AC-SDLC-07 — flat format, not nested phase_gates)
157
+ let content = specExists ? await readFileSafe(specFile) : null;
158
+
159
+ if (!content) {
160
+ // Create minimal spec with gate field
161
+ content = `---\nfeature: ${slug}\n${specFieldName}: approved\n---\n\n# Spec — ${slug}\n\nCreated by gate:approve.\n`;
162
+ } else {
163
+ content = updateFrontmatterField(content, specFieldName, 'approved');
164
+ }
165
+
166
+ await fs.writeFile(specFile, content, 'utf8');
167
+
168
+ const nextInfo = GATE_NEXT_AGENTS[gateLetter];
169
+ const result = {
170
+ ok: true,
171
+ gate: gateLetter,
172
+ gate_name: gateName,
173
+ feature: slug,
174
+ field_written: specFieldName,
175
+ spec_file: `.aioson/context/spec-${slug}.md`,
176
+ next_agent: nextInfo.agent,
177
+ next_action: nextInfo.action,
178
+ why: nextInfo.why
179
+ };
180
+
181
+ if (options.json) return result;
182
+
183
+ logger.log('');
184
+ logger.log(`Gate ${gateLetter} (${gateName}) — ${slug}`);
185
+ logger.log(BAR);
186
+ logger.log(`Result: ✓ APPROVED`);
187
+ logger.log('');
188
+ logger.log(`Written: ${specFieldName}: approved → .aioson/context/spec-${slug}.md`);
189
+ logger.log('');
190
+ logger.log(`Next agent: ${nextInfo.agent}`);
191
+ logger.log(`Why: ${nextInfo.why}`);
192
+ logger.log(`Action: ${nextInfo.action}`);
193
+ logger.log('');
194
+
195
+ return result;
196
+ }
197
+
198
+ module.exports = { runGateApprove };
@@ -19,6 +19,7 @@ const {
19
19
  fileExists,
20
20
  parseGatesFromSpec,
21
21
  parseFrontmatter,
22
+ detectClassification,
22
23
  GATE_NAMES,
23
24
  GATE_ALIASES
24
25
  } = require('../preflight-engine');
@@ -52,6 +53,7 @@ async function checkGate(targetDir, slug, gateLetter) {
52
53
  const specContent = await readFileSafe(specFile);
53
54
  const gates = specContent ? parseGatesFromSpec(specContent) : {};
54
55
  const fm = specContent ? parseFrontmatter(specContent) : {};
56
+ const classification = await detectClassification(targetDir, slug);
55
57
 
56
58
  const gateName = GATE_NAMES[gateLetter];
57
59
  const gateStatus = gates[gateName] || 'pending';
@@ -79,12 +81,19 @@ async function checkGate(targetDir, slug, gateLetter) {
79
81
  const exists = await fileExists(filePath);
80
82
  if (exists) {
81
83
  let detail = null;
84
+ let ok = true;
82
85
  const content = await readFileSafe(filePath);
83
86
  if (content) {
84
87
  const fileFm = parseFrontmatter(content);
85
- if (fileFm.status) detail = `status: ${fileFm.status}`;
88
+ const status = fileFm.status ? String(fileFm.status).toLowerCase() : null;
89
+ if (status) detail = `status: ${status}`;
90
+
91
+ if (gateLetter === 'C' && status !== 'approved') {
92
+ ok = false;
93
+ missing.push(`${fileName} status is ${status || 'missing'} — @pm must approve the implementation plan`);
94
+ }
86
95
  }
87
- evidence.push({ type: 'artifact', file: fileName, exists: true, detail, ok: true });
96
+ evidence.push({ type: 'artifact', file: fileName, exists: true, detail, ok });
88
97
  } else {
89
98
  evidence.push({ type: 'artifact', file: fileName, exists: false, ok: false });
90
99
  missing.push(`${fileName} not found`);
@@ -130,11 +139,21 @@ async function checkGate(targetDir, slug, gateLetter) {
130
139
 
131
140
  let recommendation = '';
132
141
  if (result === 'PASS') {
133
- const nextAgents = { A: '@architect', B: '@dev or @pm', C: '@dev', D: 'feature complete' };
142
+ const nextAgents = {
143
+ A: '@architect',
144
+ B: classification === 'MEDIUM' ? '@pm' : '@dev',
145
+ C: classification === 'MEDIUM' ? '@orchestrator' : '@dev',
146
+ D: 'feature complete'
147
+ };
134
148
  recommendation = `${nextAgents[gateLetter] || 'proceed'} can proceed`;
135
149
  } else {
136
- const fixAgents = { A: 'complete requirements (@analyst)', B: 'complete design (@architect)', C: 'approve implementation plan', D: 'complete implementation and run @qa' };
137
- recommendation = `BLOCKED ${fixAgents[gateLetter] || 'resolve missing items'} first`;
150
+ const fixAgents = {
151
+ A: `activate @analyst to produce requirements-${slug}.md, then run: aioson gate:approve . --feature=${slug} --gate=A`,
152
+ B: `activate @architect to produce architecture.md, then run: aioson gate:approve . --feature=${slug} --gate=B`,
153
+ C: `activate @pm to produce and approve implementation-plan-${slug}.md, then run: aioson gate:approve . --feature=${slug} --gate=C`,
154
+ D: `activate @qa for final verification; if QA passes, run: aioson gate:approve . --feature=${slug} --gate=D`
155
+ };
156
+ recommendation = `BLOCKED — ${fixAgents[gateLetter] || 'resolve missing items'}`;
138
157
  }
139
158
 
140
159
  return {
@@ -4,6 +4,84 @@ const fs = require('node:fs/promises');
4
4
  const path = require('node:path');
5
5
  const { loadCompatibleGenome } = require('../lib/genomes/compat');
6
6
 
7
+ const INSTALLED_SKILLS_DIR = '.aioson/installed-skills';
8
+ const BUILTIN_SKILLS_DIR = '.aioson/skills';
9
+ const GENOMES_DIR = '.aioson/genomes';
10
+
11
+ /**
12
+ * Walk up the directory tree from startDir looking for a dir that contains .aioson/.
13
+ * Falls back to process.cwd() if not found.
14
+ */
15
+ async function findProjectRoot(startDir) {
16
+ let current = startDir;
17
+ for (let i = 0; i < 10; i++) {
18
+ try {
19
+ await fs.access(path.join(current, '.aioson'));
20
+ return current;
21
+ } catch {
22
+ const parent = path.dirname(current);
23
+ if (parent === current) break;
24
+ current = parent;
25
+ }
26
+ }
27
+ return process.cwd();
28
+ }
29
+
30
+ /**
31
+ * Check whether a skill slug is available in the project.
32
+ * Checks installed skills AND built-in skills directories.
33
+ */
34
+ async function isSkillAvailable(projectRoot, slug) {
35
+ const installedPath = path.join(projectRoot, INSTALLED_SKILLS_DIR, slug, 'SKILL.md');
36
+ const builtinExact = path.join(projectRoot, BUILTIN_SKILLS_DIR, slug, 'SKILL.md');
37
+ // Also check as a flat dir (some skills live directly under .aioson/skills/{slug}/)
38
+ const builtinDir = path.join(projectRoot, BUILTIN_SKILLS_DIR, slug);
39
+
40
+ for (const candidate of [installedPath, builtinExact]) {
41
+ try {
42
+ await fs.access(candidate);
43
+ return { found: true, path: path.relative(projectRoot, path.dirname(candidate)) };
44
+ } catch { /* not found */ }
45
+ }
46
+
47
+ try {
48
+ const stat = await fs.stat(builtinDir);
49
+ if (stat.isDirectory()) {
50
+ return { found: true, path: path.relative(projectRoot, builtinDir) };
51
+ }
52
+ } catch { /* not found */ }
53
+
54
+ return { found: false };
55
+ }
56
+
57
+ /**
58
+ * Check whether a genome slug is available in the project.
59
+ */
60
+ async function isGenomeAvailable(projectRoot, slug) {
61
+ const genomePath = path.join(projectRoot, GENOMES_DIR, `${slug}.md`);
62
+ try {
63
+ await fs.access(genomePath);
64
+ return { found: true, path: path.relative(projectRoot, genomePath) };
65
+ } catch {
66
+ return { found: false };
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Read and parse the .meta.json companion file for a genome .md.
72
+ * Returns null if absent or invalid JSON.
73
+ */
74
+ async function readGenomeMeta(mdFilePath) {
75
+ const slug = path.basename(mdFilePath, '.md');
76
+ const metaPath = path.join(path.dirname(mdFilePath), `${slug}.meta.json`);
77
+ try {
78
+ const raw = await fs.readFile(metaPath, 'utf8');
79
+ return { meta: JSON.parse(raw), metaPath };
80
+ } catch {
81
+ return { meta: null, metaPath };
82
+ }
83
+ }
84
+
7
85
  async function runGenomeDoctor({ args, options = {}, logger }) {
8
86
  const target = args[0];
9
87
  if (!target) {
@@ -13,6 +91,7 @@ async function runGenomeDoctor({ args, options = {}, logger }) {
13
91
  const filePath = path.resolve(process.cwd(), target);
14
92
  const raw = await fs.readFile(filePath, 'utf8');
15
93
  const loaded = loadCompatibleGenome(raw, { filePath });
94
+
16
95
  const result = {
17
96
  ok: true,
18
97
  file: filePath,
@@ -21,18 +100,96 @@ async function runGenomeDoctor({ args, options = {}, logger }) {
21
100
  slug: loaded.document.slug,
22
101
  type: loaded.document.type,
23
102
  depth: loaded.document.depth,
24
- evidenceMode: loaded.document.evidenceMode
103
+ evidenceMode: loaded.document.evidenceMode,
104
+ dependencies: {
105
+ skills: [],
106
+ genomes: [],
107
+ missing: { skills: [], genomes: [] }
108
+ }
25
109
  };
26
110
 
27
- if (options.json) return result;
111
+ // Check for .meta.json companion
112
+ const { meta, metaPath } = await readGenomeMeta(filePath);
113
+ const hasMeta = Boolean(meta);
114
+ result.hasMeta = hasMeta;
115
+
116
+ if (!options.json) {
117
+ logger.log(`Genome file: ${filePath}`);
118
+ logger.log(`Format: ${result.detectedFormat}`);
119
+ logger.log(`Migrated internally: ${result.migrated ? 'yes' : 'no'}`);
120
+ logger.log(`Slug: ${result.slug}`);
121
+ logger.log(`Type: ${result.type}`);
122
+ logger.log(`Depth: ${result.depth}`);
123
+ logger.log(`Evidence mode: ${result.evidenceMode}`);
124
+ logger.log(`Meta file: ${hasMeta ? path.relative(process.cwd(), metaPath) : 'not found'}`);
125
+ }
126
+
127
+ // Dependency check — requires meta.json with dependencies field
128
+ const deps = hasMeta && meta.dependencies
129
+ ? {
130
+ skills: Array.isArray(meta.dependencies.skills) ? meta.dependencies.skills : [],
131
+ genomes: Array.isArray(meta.dependencies.genomes) ? meta.dependencies.genomes : []
132
+ }
133
+ : { skills: [], genomes: [] };
134
+
135
+ result.dependencies.skills = deps.skills;
136
+ result.dependencies.genomes = deps.genomes;
137
+
138
+ if (deps.skills.length === 0 && deps.genomes.length === 0) {
139
+ if (!options.json) logger.log('\nDependencies: none declared');
140
+ return result;
141
+ }
142
+
143
+ const projectRoot = await findProjectRoot(path.dirname(filePath));
144
+ const missingSkills = [];
145
+ const missingGenomes = [];
146
+
147
+ if (!options.json) logger.log('\nChecking dependencies...');
148
+
149
+ for (const slug of deps.skills) {
150
+ const check = await isSkillAvailable(projectRoot, slug);
151
+ if (check.found) {
152
+ if (!options.json) logger.log(` skill "${slug}": OK (${check.path})`);
153
+ } else {
154
+ missingSkills.push(slug);
155
+ if (!options.json) logger.log(` skill "${slug}": MISSING`);
156
+ }
157
+ }
158
+
159
+ for (const slug of deps.genomes) {
160
+ const check = await isGenomeAvailable(projectRoot, slug);
161
+ if (check.found) {
162
+ if (!options.json) logger.log(` genome "${slug}": OK (${check.path})`);
163
+ } else {
164
+ missingGenomes.push(slug);
165
+ if (!options.json) logger.log(` genome "${slug}": MISSING`);
166
+ }
167
+ }
168
+
169
+ result.dependencies.missing = { skills: missingSkills, genomes: missingGenomes };
170
+
171
+ const hasMissing = missingSkills.length > 0 || missingGenomes.length > 0;
172
+ if (hasMissing) {
173
+ result.ok = false;
174
+ if (!options.json) {
175
+ logger.log('\nMissing dependencies detected.');
176
+ if (missingSkills.length > 0) {
177
+ logger.log('Install missing skills:');
178
+ for (const slug of missingSkills) {
179
+ logger.log(` aioson skill:install --slug=${slug}`);
180
+ }
181
+ }
182
+ if (missingGenomes.length > 0) {
183
+ logger.log('Install missing genomes:');
184
+ for (const slug of missingGenomes) {
185
+ logger.log(` aioson genome:install --slug=${slug}`);
186
+ }
187
+ }
188
+ }
189
+ } else if (!options.json) {
190
+ logger.log('\nAll dependencies satisfied.');
191
+ }
28
192
 
29
- logger.log(`Genome file: ${filePath}`);
30
- logger.log(`Format: ${result.detectedFormat}`);
31
- logger.log(`Migrated internally: ${result.migrated ? 'yes' : 'no'}`);
32
- logger.log(`Slug: ${result.slug}`);
33
- logger.log(`Type: ${result.type}`);
34
- logger.log(`Depth: ${result.depth}`);
35
- logger.log(`Evidence mode: ${result.evidenceMode}`);
36
193
  return result;
37
194
  }
38
195
 
@@ -0,0 +1,170 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson git:guard — inspect staged files before commit
5
+ *
6
+ * Usage:
7
+ * aioson git:guard .
8
+ * aioson git:guard . --json
9
+ * aioson git:guard . --allow-warnings --json
10
+ * aioson git:guard . --install-hook
11
+ * aioson git:guard . --uninstall-hook
12
+ */
13
+
14
+ const path = require('node:path');
15
+ const {
16
+ inspectStagedChanges,
17
+ installPreCommitHook,
18
+ uninstallPreCommitHook
19
+ } = require('../lib/git-commit-guard');
20
+
21
+ function formatFinding(prefix, finding) {
22
+ const line = finding.line ? `:${finding.line}` : '';
23
+ return `${prefix} ${finding.path}${line} — ${finding.reason} [${finding.id}]`;
24
+ }
25
+
26
+ async function runGitGuard({ args, options = {}, logger }) {
27
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
28
+ const allowWarnings = Boolean(options['allow-warnings'] || options.allowWarnings);
29
+ const installHook = Boolean(options['install-hook'] || options.installHook);
30
+ const uninstallHook = Boolean(options['uninstall-hook'] || options.uninstallHook || options['remove-hook'] || options.removeHook);
31
+
32
+ if (installHook && uninstallHook) {
33
+ process.exitCode = 1;
34
+ const failure = {
35
+ ok: false,
36
+ error: 'git_guard_invalid_options',
37
+ message: 'Use either --install-hook or --uninstall-hook, not both.',
38
+ projectDir: targetDir
39
+ };
40
+ if (!options.json) logger.error(failure.message);
41
+ return failure;
42
+ }
43
+
44
+ if (installHook || uninstallHook) {
45
+ let hookResult;
46
+ try {
47
+ hookResult = installHook
48
+ ? await installPreCommitHook(targetDir, options)
49
+ : await uninstallPreCommitHook(targetDir, options);
50
+ } catch (error) {
51
+ process.exitCode = 1;
52
+ const failure = {
53
+ ok: false,
54
+ error: 'git_guard_hook_failed',
55
+ message: error.message,
56
+ projectDir: targetDir
57
+ };
58
+ if (!options.json) logger.error(`Commit hook operation failed: ${error.message}`);
59
+ return failure;
60
+ }
61
+
62
+ if (!hookResult.ok) process.exitCode = 1;
63
+ if (options.json) return hookResult;
64
+
65
+ logger.log('');
66
+ logger.log(`Commit hook — ${hookResult.gitRoot}`);
67
+ if (!hookResult.ok) {
68
+ logger.error(hookResult.message);
69
+ return hookResult;
70
+ }
71
+
72
+ if (installHook) {
73
+ logger.log(hookResult.dryRun ? 'Pre-commit hook dry-run complete.' : 'Pre-commit hook installed.');
74
+ logger.log(`Hook path: ${hookResult.hookPath}`);
75
+ if (hookResult.backedUpExistingHook) {
76
+ logger.log(`Existing hook backed up to: ${hookResult.backupPath}`);
77
+ }
78
+ if (hookResult.chainedBackupHook) {
79
+ logger.log('AIOSON will chain the backed-up hook after the guard passes.');
80
+ }
81
+ return hookResult;
82
+ }
83
+
84
+ if (hookResult.removed || hookResult.dryRun) {
85
+ logger.log(hookResult.dryRun ? 'Pre-commit hook uninstall dry-run complete.' : 'Pre-commit hook removed.');
86
+ if (hookResult.restoredBackup) {
87
+ logger.log(`Restored previous hook from: ${hookResult.backupPath}`);
88
+ }
89
+ return hookResult;
90
+ }
91
+
92
+ logger.log(hookResult.message);
93
+ return hookResult;
94
+ }
95
+
96
+ let result;
97
+ try {
98
+ result = await inspectStagedChanges(targetDir, {
99
+ allowWarnings,
100
+ config: options.config
101
+ });
102
+ } catch (error) {
103
+ process.exitCode = 1;
104
+ const failure = {
105
+ ok: false,
106
+ error: 'git_guard_failed',
107
+ message: error.message,
108
+ projectDir: targetDir
109
+ };
110
+ if (!options.json) logger.error(`Commit guard failed: ${error.message}`);
111
+ return failure;
112
+ }
113
+
114
+ const output = {
115
+ ok: result.ok,
116
+ projectDir: targetDir,
117
+ gitRoot: result.gitRoot,
118
+ strict: result.strict,
119
+ policy: result.policy,
120
+ stagedFiles: result.stagedFiles,
121
+ files: result.files,
122
+ errors: result.errors,
123
+ warnings: result.warnings,
124
+ suggestedCommands: result.suggestedCommands,
125
+ summary: result.summary
126
+ };
127
+
128
+ if (!result.ok) process.exitCode = 1;
129
+
130
+ if (options.json) return output;
131
+
132
+ logger.log('');
133
+ logger.log(`Commit guard — ${result.gitRoot}`);
134
+ logger.log(`Staged files: ${result.summary.stagedCount}`);
135
+ logger.log(`Policy: ${result.policy.loaded ? result.policy.path : 'default built-in policy (no project config found)'}`);
136
+
137
+ if (result.summary.stagedCount === 0) {
138
+ logger.error('No staged files found. Stage explicit files before committing.');
139
+ return output;
140
+ }
141
+
142
+ if (result.ok) {
143
+ logger.log('Commit guard passed.');
144
+ return output;
145
+ }
146
+
147
+ logger.error('Commit guard blocked this commit.');
148
+ if (result.errors.length > 0) {
149
+ logger.error('Errors:');
150
+ for (const finding of result.errors) {
151
+ logger.error(formatFinding(' [ERROR]', finding));
152
+ }
153
+ }
154
+ if (result.warnings.length > 0) {
155
+ logger.error('Warnings:');
156
+ for (const finding of result.warnings) {
157
+ logger.error(formatFinding(' [WARN] ', finding));
158
+ }
159
+ }
160
+ if (result.suggestedCommands.length > 0) {
161
+ logger.error('Suggested next commands:');
162
+ for (const command of result.suggestedCommands) {
163
+ logger.error(` ${command}`);
164
+ }
165
+ }
166
+
167
+ return output;
168
+ }
169
+
170
+ module.exports = { runGitGuard };