@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
package/src/doctor.js CHANGED
@@ -5,8 +5,8 @@ const path = require('node:path');
5
5
  const { REQUIRED_FILES } = require('./constants');
6
6
  const { installTemplate, TEMPLATE_DIR } = require('./installer');
7
7
  const { exists, copyFileWithDir } = require('./utils');
8
- const { validateProjectContextFile } = require('./context');
9
- const { applyAgentLocale, resolveAgentLocale } = require('./locales');
8
+ const { validateProjectContextFile, getInteractionLanguage } = require('./context');
9
+ const { applyAgentLocale } = require('./locales');
10
10
 
11
11
  function parseMajor(version) {
12
12
  const cleaned = String(version || '').replace(/^v/, '');
@@ -34,6 +34,14 @@ const GEMINI_COMMAND_EXPECTATIONS = [
34
34
  { file: '.gemini/commands/aios-orchestrator.toml', agent: 'orchestrator' }
35
35
  ];
36
36
 
37
+ const DESIGN_GOVERNANCE_FILES = [
38
+ '.aioson/design-docs/code-reuse.md',
39
+ '.aioson/design-docs/componentization.md',
40
+ '.aioson/design-docs/file-size.md',
41
+ '.aioson/design-docs/folder-structure.md',
42
+ '.aioson/design-docs/naming.md'
43
+ ];
44
+
37
45
  const GATEWAY_FILE_BY_CHECK_ID = {
38
46
  'gateway:claude:contract': 'CLAUDE.md',
39
47
  'gateway:codex:contract': 'AGENTS.md',
@@ -79,6 +87,16 @@ async function runDoctor(targetDir) {
79
87
  });
80
88
  }
81
89
 
90
+ for (const rel of DESIGN_GOVERNANCE_FILES) {
91
+ checks.push({
92
+ id: `design-governance:${rel}`,
93
+ key: 'doctor.required_file',
94
+ params: { rel },
95
+ ok: await exists(path.join(targetDir, rel)),
96
+ hintKey: 'doctor.context_hint'
97
+ });
98
+ }
99
+
82
100
  const gatewayChecks = [
83
101
  {
84
102
  id: 'gateway:claude:contract',
@@ -130,7 +148,7 @@ async function runDoctor(targetDir) {
130
148
  key: 'doctor.gateway_gemini_command_pointer',
131
149
  params: { file: expectation.file },
132
150
  ok: await fileContainsAll(commandPath, [
133
- `instruction_file = ".aioson/agents/${expectation.agent}.md"`
151
+ `@{ .aioson/agents/${expectation.agent}.md }`
134
152
  ]),
135
153
  hintKey: 'doctor.gateway_gemini_command_pointer_hint',
136
154
  hintParams: {
@@ -250,14 +268,36 @@ async function applyDoctorFixes(targetDir, report, options = {}) {
250
268
  });
251
269
  }
252
270
 
271
+ const missingDesignGovernanceFiles = report.checks
272
+ .filter((check) => !check.ok && check.id.startsWith('design-governance:'))
273
+ .map((check) => check.params.rel);
274
+
275
+ if (missingDesignGovernanceFiles.length > 0) {
276
+ const restored = await restoreTemplateFiles(targetDir, missingDesignGovernanceFiles, { dryRun });
277
+ if (restored.length > 0) changedCount += restored.length;
278
+ actions.push({
279
+ id: 'design_governance',
280
+ applied: restored.length > 0,
281
+ count: restored.length,
282
+ missingCount: missingDesignGovernanceFiles.length
283
+ });
284
+ } else {
285
+ actions.push({
286
+ id: 'design_governance',
287
+ applied: false,
288
+ skipped: true,
289
+ count: 0,
290
+ missingCount: 0
291
+ });
292
+ }
293
+
253
294
  if (
254
295
  report.contextValidation &&
255
296
  report.contextValidation.parsed &&
256
297
  report.contextValidation.valid &&
257
- report.contextValidation.data &&
258
- report.contextValidation.data.conversation_language
298
+ report.contextValidation.data
259
299
  ) {
260
- const locale = resolveAgentLocale(report.contextValidation.data.conversation_language);
300
+ const locale = getInteractionLanguage(report.contextValidation.data, 'en');
261
301
  const localeResult = await applyAgentLocale(targetDir, locale, { dryRun });
262
302
  if (localeResult.copied.length > 0) changedCount += localeResult.copied.length;
263
303
  actions.push({
@@ -0,0 +1,267 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { isValidSlug } = require('./schema');
6
+
7
+ const FEATURES_SUBDIR = 'features';
8
+ const DOSSIER_FILENAME = 'dossier.md';
9
+
10
+ const VALID_ROLES = new Set([
11
+ 'command-entry', 'core-module', 'io-layer', 'store', 'schema',
12
+ 'test', 'util', 'config', 'integration', 'cli', 'other'
13
+ ]);
14
+ const VALID_COUPLING = new Set(['low', 'medium', 'high']);
15
+ const LINES_REGEX = /^\d+-\d+$/;
16
+
17
+ function dossierPath(contextDir, slug) {
18
+ return path.join(contextDir, FEATURES_SUBDIR, slug, DOSSIER_FILENAME);
19
+ }
20
+
21
+ function parseCodeMapBlock(raw) {
22
+ const marker = '```yaml\n';
23
+ const start = raw.indexOf('## Code Map\n');
24
+ if (start === -1) return null;
25
+ const blockStart = raw.indexOf(marker, start);
26
+ if (blockStart === -1) return null;
27
+ const codeStart = blockStart + marker.length;
28
+ const codeEnd = raw.indexOf('\n```', codeStart);
29
+ if (codeEnd === -1) return null;
30
+ return { blockStart, codeStart, codeEnd };
31
+ }
32
+
33
+ function parseYamlCodeMap(yamlText) {
34
+ const result = { files: [], modules: [], patterns: [] };
35
+ const lines = yamlText.split('\n');
36
+ let currentSection = null;
37
+ let currentItem = null;
38
+
39
+ const flushItem = () => {
40
+ if (currentItem !== null && currentSection !== null) {
41
+ result[currentSection].push(currentItem);
42
+ currentItem = null;
43
+ }
44
+ };
45
+
46
+ for (const line of lines) {
47
+ if (!line.trim()) continue;
48
+
49
+ // Section header
50
+ const sectionMatch = line.match(/^(files|modules|patterns):\s*(\[\])?$/);
51
+ if (sectionMatch) {
52
+ flushItem();
53
+ currentSection = sectionMatch[1];
54
+ continue;
55
+ }
56
+
57
+ // List item start: "- key: value"
58
+ const listItemMatch = line.match(/^-\s+(\w+):\s*(.*)$/);
59
+ if (listItemMatch && currentSection) {
60
+ flushItem();
61
+ currentItem = {};
62
+ currentItem[listItemMatch[1]] = listItemMatch[2].replace(/^["']|["']$/g, '');
63
+ continue;
64
+ }
65
+
66
+ // Continuation: " key: value"
67
+ const kvMatch = line.match(/^\s+(\w+):\s*(.*)$/);
68
+ if (kvMatch && currentItem !== null) {
69
+ currentItem[kvMatch[1]] = kvMatch[2].replace(/^["']|["']$/g, '');
70
+ }
71
+ }
72
+ flushItem();
73
+ return result;
74
+ }
75
+
76
+ function serializeCodeMap(map) {
77
+ const lines = [];
78
+ const serializeList = (key, items) => {
79
+ if (!items || items.length === 0) {
80
+ lines.push(`${key}: []`);
81
+ return;
82
+ }
83
+ lines.push(`${key}:`);
84
+ for (const item of items) {
85
+ const entries = Object.entries(item);
86
+ if (entries.length === 0) continue;
87
+ lines.push(`- ${entries[0][0]}: ${entries[0][1]}`);
88
+ for (const [k, v] of entries.slice(1)) {
89
+ lines.push(` ${k}: ${v}`);
90
+ }
91
+ }
92
+ };
93
+ serializeList('files', map.files);
94
+ serializeList('modules', map.modules);
95
+ serializeList('patterns', map.patterns);
96
+ return lines.join('\n');
97
+ }
98
+
99
+ function validateFileEntry(entry) {
100
+ const errors = [];
101
+ if (!entry.path || typeof entry.path !== 'string') errors.push('path is required');
102
+ if (entry.lines && !LINES_REGEX.test(entry.lines)) errors.push(`lines must be int-int (got: ${entry.lines})`);
103
+ if (entry.role && !VALID_ROLES.has(entry.role)) errors.push(`role must be one of [${[...VALID_ROLES].join(', ')}]`);
104
+ if (entry.coupling_risk && !VALID_COUPLING.has(entry.coupling_risk)) errors.push(`coupling_risk must be low|medium|high`);
105
+ return errors;
106
+ }
107
+
108
+ async function addCodemap({ slug, contextDir, filePath, lines, role, coupling, addedBy, now = () => new Date() }) {
109
+ if (!isValidSlug(slug)) {
110
+ const err = new Error(`invalid slug: ${JSON.stringify(slug)}`);
111
+ err.code = 'EDOSSIERSLUG';
112
+ throw err;
113
+ }
114
+ const errors = validateFileEntry({ path: filePath, lines, role, coupling_risk: coupling });
115
+ if (errors.length > 0) {
116
+ const err = new Error(`invalid codemap entry: ${errors.join('; ')}`);
117
+ err.code = 'ECODEMAPVALIDATION';
118
+ err.errors = errors;
119
+ throw err;
120
+ }
121
+
122
+ // Warn (not error) when the file path doesn't exist on disk — may be a planned file
123
+ let fileWarn = null;
124
+ try {
125
+ await fs.access(path.resolve(contextDir, '..', '..', filePath));
126
+ } catch {
127
+ fileWarn = 'file_not_found';
128
+ }
129
+
130
+ const p = dossierPath(contextDir, slug);
131
+ let raw;
132
+ try {
133
+ raw = await fs.readFile(p, 'utf8');
134
+ } catch (err) {
135
+ if (err && err.code === 'ENOENT') {
136
+ const e = new Error(`dossier not found for slug "${slug}"`);
137
+ e.code = 'EDOSSIERMISSING';
138
+ throw e;
139
+ }
140
+ throw err;
141
+ }
142
+
143
+ const parsed = parseCodeMapBlock(raw);
144
+ let map = { files: [], modules: [], patterns: [] };
145
+ if (parsed) {
146
+ const yamlText = raw.slice(parsed.codeStart, parsed.codeEnd);
147
+ map = parseYamlCodeMap(yamlText);
148
+ }
149
+
150
+ // Idempotency: dedupe by (path, lines)
151
+ const existing = map.files.find(f => f.path === filePath && f.lines === (lines || ''));
152
+ if (existing) {
153
+ return { added: false, path: filePath, warn: fileWarn };
154
+ }
155
+
156
+ const entry = { path: filePath };
157
+ if (lines) entry.lines = lines;
158
+ if (role) entry.role = role;
159
+ if (coupling) entry.coupling_risk = coupling;
160
+ if (addedBy) entry.added_by = addedBy;
161
+ entry.added_at = now().toISOString();
162
+
163
+ map.files.push(entry);
164
+ const newYaml = serializeCodeMap(map);
165
+
166
+ let newRaw;
167
+ if (parsed) {
168
+ newRaw = raw.slice(0, parsed.codeStart) + newYaml + raw.slice(parsed.codeEnd);
169
+ } else {
170
+ // Insert a Code Map section if absent (shouldn't happen in well-formed dossiers)
171
+ newRaw = raw + `\n## Code Map\n\n\`\`\`yaml\n${newYaml}\n\`\`\`\n`;
172
+ }
173
+
174
+ await fs.writeFile(p, newRaw, 'utf8');
175
+ return { added: true, path: filePath, warn: fileWarn };
176
+ }
177
+
178
+ async function linkRule({ slug, contextDir, rulePath, reason, targetDir }) {
179
+ if (!isValidSlug(slug)) {
180
+ const err = new Error(`invalid slug: ${JSON.stringify(slug)}`);
181
+ err.code = 'EDOSSIERSLUG';
182
+ throw err;
183
+ }
184
+
185
+ // Validate rule path exists in .aioson/rules/ or .aioson/design-docs/
186
+ const base = targetDir || process.cwd();
187
+ const absRule = path.resolve(base, rulePath);
188
+ const rulesDir = path.join(base, '.aioson', 'rules');
189
+ const designDocsDir = path.join(base, '.aioson', 'design-docs');
190
+
191
+ const inRules = absRule.startsWith(rulesDir + path.sep) || absRule.startsWith(rulesDir + '/');
192
+ const inDesignDocs = absRule.startsWith(designDocsDir + path.sep) || absRule.startsWith(designDocsDir + '/');
193
+
194
+ if (!inRules && !inDesignDocs) {
195
+ const err = new Error(`rule path must be under .aioson/rules/ or .aioson/design-docs/ (got: ${rulePath})`);
196
+ err.code = 'ELINKREULEPATH';
197
+ throw err;
198
+ }
199
+
200
+ try {
201
+ await fs.access(absRule);
202
+ } catch {
203
+ const err = new Error(`rule file not found: ${absRule}`);
204
+ err.code = 'ELINKREULENOTFOUND';
205
+ err.path = absRule;
206
+ throw err;
207
+ }
208
+
209
+ const p = dossierPath(contextDir, slug);
210
+ let raw;
211
+ try {
212
+ raw = await fs.readFile(p, 'utf8');
213
+ } catch (err) {
214
+ if (err && err.code === 'ENOENT') {
215
+ const e = new Error(`dossier not found for slug "${slug}"`);
216
+ e.code = 'EDOSSIERMISSING';
217
+ throw e;
218
+ }
219
+ throw err;
220
+ }
221
+
222
+ const rulesSection = '## Rules & Design-Docs aplicáveis';
223
+ const entry = `- [${rulePath}](${rulePath})${reason ? ` — ${reason}` : ''}`;
224
+
225
+ // Idempotency: don't duplicate same path
226
+ if (raw.includes(`[${rulePath}]`)) {
227
+ return { added: false, path: rulePath };
228
+ }
229
+
230
+ const lines = raw.split('\n');
231
+ let sectionEnd = lines.length;
232
+ let inSection = false;
233
+
234
+ for (let i = 0; i < lines.length; i++) {
235
+ if (lines[i].trimEnd() === rulesSection) {
236
+ inSection = true;
237
+ } else if (inSection && /^## /.test(lines[i])) {
238
+ sectionEnd = i;
239
+ break;
240
+ }
241
+ }
242
+
243
+ const before = lines.slice(0, sectionEnd);
244
+ const after = lines.slice(sectionEnd);
245
+
246
+ // Remove placeholder line if present
247
+ const placeholderIdx = before.findIndex(l => l.includes('_(vazio —') || l.includes('_(empty'));
248
+ if (placeholderIdx !== -1) before.splice(placeholderIdx, 1);
249
+
250
+ while (before.length > 0 && before[before.length - 1].trim() === '') before.pop();
251
+ before.push('', entry);
252
+
253
+ const newRaw = [...before, '', ...after].join('\n');
254
+ await fs.writeFile(p, newRaw, 'utf8');
255
+ return { added: true, path: rulePath };
256
+ }
257
+
258
+ module.exports = {
259
+ addCodemap,
260
+ linkRule,
261
+ parseCodeMapBlock,
262
+ parseYamlCodeMap,
263
+ serializeCodeMap,
264
+ validateFileEntry,
265
+ VALID_ROLES,
266
+ VALID_COUPLING
267
+ };
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ const crypto = require('node:crypto');
4
+ const fs = require('node:fs/promises');
5
+ const path = require('node:path');
6
+
7
+ const { isValidSlug, SCHEMA_VERSION, ALLOWED_CLASSIFICATIONS, validateFrontmatter } = require('./schema');
8
+ const { featureDir, dossierPath, parseSections, parseFrontmatter } = require('./store');
9
+
10
+ // Maps canonical artifact filenames to the agent that typically produces them.
11
+ const ARTIFACT_AGENTS = {
12
+ [`prd`]: 'product',
13
+ [`spec`]: 'architect',
14
+ [`sheldon-enrichment`]: 'sheldon',
15
+ [`requirements`]: 'analyst',
16
+ [`architecture`]: 'architect'
17
+ };
18
+
19
+ async function fileExists(p) {
20
+ try { await fs.access(p); return true; } catch { return false; }
21
+ }
22
+
23
+ async function readText(p) {
24
+ try { return await fs.readFile(p, 'utf8'); } catch { return null; }
25
+ }
26
+
27
+ function extractSection(markdown, headingNames) {
28
+ if (!markdown) return null;
29
+ const sections = parseSections(markdown);
30
+ for (const name of headingNames) {
31
+ if (sections[name]) {
32
+ const t = sections[name].trim();
33
+ if (t) return t;
34
+ }
35
+ }
36
+ return null;
37
+ }
38
+
39
+ function artifactHash(artifacts) {
40
+ const keys = Object.keys(artifacts).sort();
41
+ const payload = keys.map(k => `${k}=${artifacts[k] ? artifacts[k].length : 0}`).join(';');
42
+ return crypto.createHash('sha256').update(payload).digest('hex').slice(0, 12);
43
+ }
44
+
45
+ function buildBootstrapDossier({ slug, classification, createdAt, artifacts, why, what, agentTrail }) {
46
+ const fm = [
47
+ '---',
48
+ `feature_slug: ${slug}`,
49
+ `schema_version: "${SCHEMA_VERSION}"`,
50
+ `created_by: dossier-init`,
51
+ `created_at: ${createdAt}`,
52
+ `status: ${artifacts.done ? 'closed' : 'active'}`,
53
+ `classification: ${classification}`,
54
+ `last_updated_by: dossier-init`,
55
+ `last_updated_at: ${createdAt}`,
56
+ `bootstrap_hash: ${artifactHash(artifacts)}`,
57
+ '---',
58
+ ''
59
+ ].join('\n');
60
+
61
+ const whyText = why || '_(não encontrado — preencher manualmente)_';
62
+ const whatText = what || '_(não encontrado — preencher manualmente)_';
63
+
64
+ const trailLines = agentTrail.length > 0
65
+ ? agentTrail.map(e => `- **${e.timestamp}** | @${e.agent} | _${e.artifact}_`).join('\n')
66
+ : '_(sintetizado a partir de artefatos existentes)_';
67
+
68
+ const body = [
69
+ '## Why',
70
+ '',
71
+ whyText,
72
+ '',
73
+ '## What',
74
+ '',
75
+ whatText,
76
+ '',
77
+ '## Code Map',
78
+ '',
79
+ '```yaml',
80
+ 'files: []',
81
+ 'modules: []',
82
+ 'patterns: []',
83
+ '```',
84
+ '',
85
+ '## Rules & Design-Docs aplicáveis',
86
+ '',
87
+ '_(populado via dossier:link-rule)_',
88
+ '',
89
+ '## Agent Trail',
90
+ '',
91
+ trailLines,
92
+ '',
93
+ '## Revision Requests',
94
+ '',
95
+ '_(vazio)_',
96
+ ''
97
+ ].join('\n');
98
+
99
+ return fm + body;
100
+ }
101
+
102
+ async function initFromExisting({ slug, contextDir, classification, targetDir, now = () => new Date() } = {}) {
103
+ if (!isValidSlug(slug)) {
104
+ const err = new Error(`invalid slug (must be kebab-case): ${JSON.stringify(slug)}`);
105
+ err.code = 'EDOSSIERSLUG';
106
+ throw err;
107
+ }
108
+
109
+ const dir = featureDir(contextDir, slug);
110
+ const p = dossierPath(contextDir, slug);
111
+
112
+ // Check if dossier already exists (idempotency guard)
113
+ if (await fileExists(p)) {
114
+ // Check if it has the same bootstrap_hash — if artifacts unchanged, it's a no-op
115
+ const raw = await readText(p);
116
+ const fmParse = raw ? parseFrontmatter(raw) : { ok: false };
117
+ if (fmParse.ok && fmParse.data.bootstrap_hash) {
118
+ // Re-compute hash to detect changes
119
+ const artifacts = await gatherArtifacts(slug, contextDir, targetDir);
120
+ const newHash = artifactHash(artifacts);
121
+ if (newHash === fmParse.data.bootstrap_hash) {
122
+ return { created: false, reason: 'unchanged', path: p };
123
+ }
124
+ }
125
+ const err = new Error(`dossier already exists at ${p} — use dossier:show to inspect`);
126
+ err.code = 'EDOSSIEREXISTS';
127
+ err.path = p;
128
+ throw err;
129
+ }
130
+
131
+ const artifacts = await gatherArtifacts(slug, contextDir, targetDir);
132
+
133
+ // Must have at least one artifact to synthesize from
134
+ const hasAny = Object.values(artifacts).some(Boolean);
135
+ if (!hasAny) {
136
+ const err = new Error(`no artifacts found for slug "${slug}" — use dossier:init without --from-existing`);
137
+ err.code = 'EBOOTSTRAPEMPTY';
138
+ throw err;
139
+ }
140
+
141
+ // Resolve classification
142
+ let cls = classification;
143
+ if (!cls) {
144
+ const ctxPath = path.join(contextDir, 'project.context.md');
145
+ const ctxRaw = await readText(ctxPath);
146
+ if (ctxRaw) {
147
+ const m = ctxRaw.match(/^classification:\s*"?([A-Z]+)"?\s*$/m);
148
+ if (m && ALLOWED_CLASSIFICATIONS.has(m[1])) cls = m[1];
149
+ }
150
+ }
151
+ cls = cls || 'MEDIUM';
152
+
153
+ // Extract Why/What
154
+ const prdContent = artifacts.prd || artifacts.prdGlobal;
155
+ const why = extractSection(prdContent, ['Problem', 'Why', 'Vision', 'Problema']);
156
+ const what = extractSection(prdContent, ['Escopo do MVP', 'Scope', 'What', 'Escopo']);
157
+
158
+ // Build agent trail from artifact metadata
159
+ const createdAt = now().toISOString();
160
+ const agentTrail = buildAgentTrail(artifacts, createdAt);
161
+
162
+ // Validate frontmatter before writing
163
+ const fmCheck = validateFrontmatter({
164
+ feature_slug: slug,
165
+ schema_version: SCHEMA_VERSION,
166
+ created_by: 'dossier-init',
167
+ created_at: createdAt,
168
+ status: artifacts.done ? 'closed' : 'active',
169
+ classification: cls,
170
+ last_updated_by: 'dossier-init',
171
+ last_updated_at: createdAt
172
+ });
173
+ if (!fmCheck.valid) {
174
+ const err = new Error(`schema error: ${fmCheck.errors.join('; ')}`);
175
+ err.code = 'EDOSSIERSCHEMA';
176
+ throw err;
177
+ }
178
+
179
+ const markdown = buildBootstrapDossier({ slug, classification: cls, createdAt, artifacts, why, what, agentTrail });
180
+
181
+ await fs.mkdir(dir, { recursive: true });
182
+ await fs.writeFile(p, markdown, 'utf8');
183
+
184
+ return { created: true, path: p, classification: cls, artifactsFound: Object.keys(artifacts).filter(k => artifacts[k]) };
185
+ }
186
+
187
+ async function gatherArtifacts(slug, contextDir, targetDir) {
188
+ const base = targetDir || path.join(contextDir, '..', '..');
189
+ const artifacts = {};
190
+
191
+ // Per-slug artifacts
192
+ artifacts.prd = await readText(path.join(contextDir, `prd-${slug}.md`));
193
+ artifacts.spec = await readText(path.join(contextDir, `spec-${slug}.md`));
194
+ artifacts.sheldonEnrichment = await readText(path.join(contextDir, `sheldon-enrichment-${slug}.md`));
195
+ artifacts.requirements = await readText(path.join(contextDir, `requirements-${slug}.md`));
196
+ artifacts.architecture = await readText(path.join(contextDir, `architecture-${slug}.md`));
197
+
198
+ // Global PRD fallback
199
+ artifacts.prdGlobal = !artifacts.prd ? await readText(path.join(contextDir, 'prd.md')) : null;
200
+
201
+ // done/ directory (feature already closed)
202
+ const doneDir = path.join(contextDir, 'done', slug);
203
+ artifacts.done = await fileExists(doneDir) ? doneDir : null;
204
+
205
+ return artifacts;
206
+ }
207
+
208
+ function buildAgentTrail(artifacts, fallbackTimestamp) {
209
+ const trail = [];
210
+ const add = (artifact, agent) => {
211
+ if (artifacts[artifact]) trail.push({ artifact, agent, timestamp: fallbackTimestamp });
212
+ };
213
+ add('prd', 'product');
214
+ add('prdGlobal', 'product');
215
+ add('requirements', 'analyst');
216
+ add('sheldonEnrichment', 'sheldon');
217
+ add('architecture', 'architect');
218
+ add('spec', 'architect');
219
+ return trail;
220
+ }
221
+
222
+ module.exports = { initFromExisting };