@jaimevalasek/aioson 1.7.2 → 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 (362) hide show
  1. package/CHANGELOG.md +35 -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 +42 -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/cypher.md +252 -0
  143. package/template/.aioson/agents/dev.md +112 -628
  144. package/template/.aioson/agents/deyvin.md +33 -236
  145. package/template/.aioson/agents/discover.md +235 -0
  146. package/template/.aioson/agents/discovery-design-doc.md +17 -252
  147. package/template/.aioson/agents/genome.md +76 -26
  148. package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
  149. package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
  150. package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
  151. package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
  152. package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
  153. package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
  154. package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
  155. package/template/.aioson/agents/manifests/product.manifest.json +23 -0
  156. package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
  157. package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
  158. package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
  159. package/template/.aioson/agents/neo.md +5 -7
  160. package/template/.aioson/agents/orache.md +2 -6
  161. package/template/.aioson/agents/orchestrator.md +81 -182
  162. package/template/.aioson/agents/pentester.md +235 -0
  163. package/template/.aioson/agents/pm.md +40 -104
  164. package/template/.aioson/agents/product.md +99 -344
  165. package/template/.aioson/agents/profiler-enricher.md +57 -6
  166. package/template/.aioson/agents/profiler-forge.md +17 -7
  167. package/template/.aioson/agents/profiler-researcher.md +29 -6
  168. package/template/.aioson/agents/qa.md +168 -514
  169. package/template/.aioson/agents/setup.md +52 -278
  170. package/template/.aioson/agents/sheldon.md +122 -754
  171. package/template/.aioson/agents/site-forge.md +111 -1583
  172. package/template/.aioson/agents/squad.md +139 -2010
  173. package/template/.aioson/agents/tester.md +10 -0
  174. package/template/.aioson/agents/ux-ui.md +104 -812
  175. package/template/.aioson/agents/validator.md +69 -0
  176. package/template/.aioson/brains/scripts/query.js +5 -1
  177. package/template/.aioson/config/autonomy-protocol.json +43 -0
  178. package/template/.aioson/config.md +43 -15
  179. package/template/.aioson/constitution.md +36 -33
  180. package/template/.aioson/context/design-doc.md +136 -0
  181. package/template/.aioson/context/project-map.md +57 -0
  182. package/template/.aioson/design-docs/code-reuse.md +48 -0
  183. package/template/.aioson/design-docs/componentization.md +47 -0
  184. package/template/.aioson/design-docs/file-size.md +52 -0
  185. package/template/.aioson/design-docs/folder-structure.md +51 -0
  186. package/template/.aioson/design-docs/naming.md +54 -0
  187. package/template/.aioson/docs/LAYERS.md +12 -2
  188. package/template/.aioson/docs/dev/execution-discipline.md +106 -0
  189. package/template/.aioson/docs/dev/stack-conventions.md +83 -0
  190. package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
  191. package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
  192. package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
  193. package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
  194. package/template/.aioson/docs/product/conversation-playbook.md +116 -0
  195. package/template/.aioson/docs/product/prd-contract.md +107 -0
  196. package/template/.aioson/docs/product/quality-lens.md +57 -0
  197. package/template/.aioson/docs/product/research-loop.md +65 -0
  198. package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
  199. package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
  200. package/template/.aioson/docs/sheldon/research-loop.md +56 -0
  201. package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
  202. package/template/.aioson/docs/site-forge-build.md +195 -0
  203. package/template/.aioson/docs/site-forge-extraction.md +135 -0
  204. package/template/.aioson/docs/site-forge-qa.md +155 -0
  205. package/template/.aioson/docs/site-forge-recon.md +434 -0
  206. package/template/.aioson/docs/site-forge-transform.md +249 -0
  207. package/template/.aioson/docs/squad/content-output.md +91 -0
  208. package/template/.aioson/docs/squad/creation-flow.md +135 -0
  209. package/template/.aioson/docs/squad/domain-classification.md +117 -0
  210. package/template/.aioson/docs/squad/genome-bindings.md +47 -0
  211. package/template/.aioson/docs/squad/package-contract.md +234 -0
  212. package/template/.aioson/docs/squad/quality-lens.md +56 -0
  213. package/template/.aioson/docs/squad/research-loop.md +59 -0
  214. package/template/.aioson/docs/squad/session-operations.md +117 -0
  215. package/template/.aioson/docs/squad/workflow-quality.md +165 -0
  216. package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
  217. package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
  218. package/template/.aioson/docs/ux-ui/component-map.md +35 -0
  219. package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
  220. package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
  221. package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
  222. package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
  223. package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
  224. package/template/.aioson/genomes/copywriting.meta.json +48 -0
  225. package/template/.aioson/git-guard.json +11 -0
  226. package/template/.aioson/mcp/servers.md +0 -1
  227. package/template/.aioson/rules/agent-language-policy.md +93 -0
  228. package/template/.aioson/rules/aioson-context-boundary.md +63 -0
  229. package/template/.aioson/rules/canonical-path-contract.md +47 -0
  230. package/template/.aioson/rules/data-format-convention.md +24 -86
  231. package/template/.aioson/rules/disk-first-artifacts.md +44 -0
  232. package/template/.aioson/rules/output-brevity.md +44 -0
  233. package/template/.aioson/rules/prd-section-ownership.md +49 -0
  234. package/template/.aioson/rules/security-baseline.md +139 -0
  235. package/template/.aioson/rules/spec-level-ownership.md +61 -0
  236. package/template/.aioson/rules/squad-driver-pattern.md +81 -0
  237. package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
  238. package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
  239. package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
  240. package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
  241. package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
  242. package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
  243. package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
  244. package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
  245. package/template/.aioson/skills/static/web-research-cache.md +3 -0
  246. package/template/.aioson/tasks/squad-create.md +35 -8
  247. package/template/.aioson/tasks/squad-design.md +50 -2
  248. package/template/.aioson/tasks/squad-investigate.md +14 -1
  249. package/template/.claude/commands/aioson/agent/committer.md +5 -0
  250. package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
  251. package/template/.claude/commands/aioson/agent/cypher.md +5 -0
  252. package/template/.claude/commands/aioson/agent/pair.md +5 -0
  253. package/template/.claude/commands/aioson/agent/validator.md +5 -0
  254. package/template/.gemini/commands/aios-analyst.toml +6 -3
  255. package/template/.gemini/commands/aios-architect.toml +7 -6
  256. package/template/.gemini/commands/aios-committer.toml +7 -0
  257. package/template/.gemini/commands/aios-copywriter.toml +7 -0
  258. package/template/.gemini/commands/aios-cypher.toml +7 -0
  259. package/template/.gemini/commands/aios-dev.toml +8 -7
  260. package/template/.gemini/commands/aios-deyvin.toml +6 -5
  261. package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
  262. package/template/.gemini/commands/aios-genome.toml +7 -0
  263. package/template/.gemini/commands/aios-neo.toml +5 -3
  264. package/template/.gemini/commands/aios-orache.toml +7 -0
  265. package/template/.gemini/commands/aios-orchestrator.toml +8 -7
  266. package/template/.gemini/commands/aios-pair.toml +6 -5
  267. package/template/.gemini/commands/aios-pm.toml +8 -7
  268. package/template/.gemini/commands/aios-product.toml +5 -3
  269. package/template/.gemini/commands/aios-qa.toml +6 -5
  270. package/template/.gemini/commands/aios-setup.toml +5 -2
  271. package/template/.gemini/commands/aios-sheldon.toml +7 -0
  272. package/template/.gemini/commands/aios-site-forge.toml +7 -0
  273. package/template/.gemini/commands/aios-squad.toml +7 -0
  274. package/template/.gemini/commands/aios-tester.toml +6 -5
  275. package/template/.gemini/commands/aios-ux-ui.toml +8 -7
  276. package/template/.gemini/commands/aios-validator.toml +7 -0
  277. package/template/AGENTS.md +12 -1
  278. package/template/CLAUDE.md +5 -1
  279. package/template/.aioson/locales/en/agents/analyst.md +0 -244
  280. package/template/.aioson/locales/en/agents/architect.md +0 -245
  281. package/template/.aioson/locales/en/agents/dev.md +0 -397
  282. package/template/.aioson/locales/en/agents/deyvin.md +0 -137
  283. package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
  284. package/template/.aioson/locales/en/agents/genome.md +0 -212
  285. package/template/.aioson/locales/en/agents/neo.md +0 -8
  286. package/template/.aioson/locales/en/agents/orache.md +0 -6
  287. package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
  288. package/template/.aioson/locales/en/agents/pair.md +0 -5
  289. package/template/.aioson/locales/en/agents/pm.md +0 -84
  290. package/template/.aioson/locales/en/agents/product.md +0 -378
  291. package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
  292. package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
  293. package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
  294. package/template/.aioson/locales/en/agents/qa.md +0 -270
  295. package/template/.aioson/locales/en/agents/setup.md +0 -421
  296. package/template/.aioson/locales/en/agents/sheldon.md +0 -455
  297. package/template/.aioson/locales/en/agents/squad.md +0 -449
  298. package/template/.aioson/locales/en/agents/tester.md +0 -6
  299. package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
  300. package/template/.aioson/locales/es/agents/analyst.md +0 -225
  301. package/template/.aioson/locales/es/agents/architect.md +0 -245
  302. package/template/.aioson/locales/es/agents/dev.md +0 -370
  303. package/template/.aioson/locales/es/agents/deyvin.md +0 -99
  304. package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
  305. package/template/.aioson/locales/es/agents/genome.md +0 -104
  306. package/template/.aioson/locales/es/agents/neo.md +0 -50
  307. package/template/.aioson/locales/es/agents/orache.md +0 -105
  308. package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
  309. package/template/.aioson/locales/es/agents/pair.md +0 -7
  310. package/template/.aioson/locales/es/agents/pm.md +0 -90
  311. package/template/.aioson/locales/es/agents/product.md +0 -372
  312. package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
  313. package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
  314. package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
  315. package/template/.aioson/locales/es/agents/qa.md +0 -198
  316. package/template/.aioson/locales/es/agents/setup.md +0 -405
  317. package/template/.aioson/locales/es/agents/sheldon.md +0 -309
  318. package/template/.aioson/locales/es/agents/squad.md +0 -532
  319. package/template/.aioson/locales/es/agents/tester.md +0 -9
  320. package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
  321. package/template/.aioson/locales/fr/agents/analyst.md +0 -225
  322. package/template/.aioson/locales/fr/agents/architect.md +0 -245
  323. package/template/.aioson/locales/fr/agents/dev.md +0 -370
  324. package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
  325. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
  326. package/template/.aioson/locales/fr/agents/genome.md +0 -104
  327. package/template/.aioson/locales/fr/agents/neo.md +0 -50
  328. package/template/.aioson/locales/fr/agents/orache.md +0 -106
  329. package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
  330. package/template/.aioson/locales/fr/agents/pair.md +0 -7
  331. package/template/.aioson/locales/fr/agents/pm.md +0 -90
  332. package/template/.aioson/locales/fr/agents/product.md +0 -372
  333. package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
  334. package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
  335. package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
  336. package/template/.aioson/locales/fr/agents/qa.md +0 -198
  337. package/template/.aioson/locales/fr/agents/setup.md +0 -405
  338. package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
  339. package/template/.aioson/locales/fr/agents/squad.md +0 -532
  340. package/template/.aioson/locales/fr/agents/tester.md +0 -9
  341. package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
  342. package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
  343. package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
  344. package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
  345. package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
  346. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
  347. package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
  348. package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
  349. package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
  350. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
  351. package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
  352. package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
  353. package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
  354. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
  355. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
  356. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
  357. package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
  358. package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
  359. package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
  360. package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
  361. package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
  362. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
@@ -0,0 +1,144 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { exists } = require('../utils');
6
+ const { readConfig } = require('./config');
7
+
8
+ const WORKSPACE_FILE = '.aioson/workspace.json';
9
+ const DEFAULT_BASE_URL = 'https://aioson.com';
10
+
11
+ function slugify(text) {
12
+ return String(text || '')
13
+ .toLowerCase()
14
+ .replace(/[^a-z0-9]+/g, '-')
15
+ .replace(/^-+|-+$/g, '')
16
+ .slice(0, 60);
17
+ }
18
+
19
+ async function findProjectRoot(startDir) {
20
+ let current = path.resolve(startDir || '.');
21
+ for (let i = 0; i < 12; i++) {
22
+ try {
23
+ await fs.access(path.join(current, '.aioson'));
24
+ return current;
25
+ } catch {
26
+ const parent = path.dirname(current);
27
+ if (parent === current) break;
28
+ current = parent;
29
+ }
30
+ }
31
+ return path.resolve(startDir || '.');
32
+ }
33
+
34
+ async function readWorkspace(projectDir) {
35
+ const wsPath = path.join(projectDir, WORKSPACE_FILE);
36
+ if (!(await exists(wsPath))) return null;
37
+ try {
38
+ return JSON.parse(await fs.readFile(wsPath, 'utf8'));
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+
44
+ async function writeWorkspace(projectDir, data) {
45
+ const wsPath = path.join(projectDir, WORKSPACE_FILE);
46
+ await fs.writeFile(wsPath, `${JSON.stringify(data, null, 2)}\n`, 'utf8');
47
+ return wsPath;
48
+ }
49
+
50
+ async function runWorkspaceInit({ args, options, logger, t }) {
51
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
52
+ const projectDir = await findProjectRoot(targetDir);
53
+ const wsPath = path.join(projectDir, WORKSPACE_FILE);
54
+
55
+ if ((await exists(wsPath)) && !options.force) {
56
+ const ws = JSON.parse(await fs.readFile(wsPath, 'utf8'));
57
+ const config = await readConfig();
58
+ const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
59
+ logger.log(t('workspace.already_linked', { slug: ws.slug, url: `${baseUrl}/workspaces/${ws.slug}` }));
60
+ return { ok: true, slug: ws.slug, alreadyExists: true };
61
+ }
62
+
63
+ const config = await readConfig();
64
+ const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
65
+ const username = slugify(config.aiosonUsername || 'local');
66
+ const projectName = slugify(options.name || path.basename(projectDir));
67
+ const baseSlug = `${username}-${projectName}`;
68
+ const token = config.aiosonToken;
69
+
70
+ let workspaceId = `wks_local_${Date.now()}`;
71
+ let finalSlug = baseSlug;
72
+
73
+ if (token) {
74
+ try {
75
+ logger.log(t('workspace.registering'));
76
+ const response = await fetch(`${baseUrl}/api/workspaces`, {
77
+ method: 'POST',
78
+ headers: {
79
+ authorization: `Bearer ${token}`,
80
+ 'content-type': 'application/json',
81
+ accept: 'application/json'
82
+ },
83
+ body: JSON.stringify({ slug: baseSlug, projectName }),
84
+ signal: AbortSignal.timeout(10000)
85
+ });
86
+ if (response.ok) {
87
+ const data = await response.json();
88
+ // /api/workspaces POST returns { ok, workspace: { id, name, slug } }
89
+ workspaceId = data.workspace?.id || data.workspaceId || workspaceId;
90
+ finalSlug = data.workspace?.slug || data.slug || baseSlug;
91
+ }
92
+ } catch {
93
+ // Offline — use local ID, will sync later
94
+ }
95
+ }
96
+
97
+ const wsData = { slug: finalSlug, workspaceId, createdAt: new Date().toISOString() };
98
+ const writtenPath = await writeWorkspace(projectDir, wsData);
99
+
100
+ logger.log(t('workspace.init_ok', { slug: finalSlug, path: writtenPath, url: `${baseUrl}/workspaces/${finalSlug}` }));
101
+ return { ok: true, slug: finalSlug, workspaceId, path: writtenPath };
102
+ }
103
+
104
+ async function runWorkspaceStatus({ args, options, logger, t }) {
105
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
106
+ const projectDir = await findProjectRoot(targetDir);
107
+ const ws = await readWorkspace(projectDir);
108
+
109
+ if (!ws) {
110
+ logger.log(t('workspace.not_linked'));
111
+ logger.log(t('workspace.init_hint'));
112
+ return { ok: true, linked: false };
113
+ }
114
+
115
+ const config = await readConfig();
116
+ const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
117
+
118
+ logger.log(t('workspace.status_slug', { slug: ws.slug }));
119
+ logger.log(t('workspace.status_id', { id: ws.workspaceId }));
120
+ logger.log(t('workspace.status_url', { url: `${baseUrl}/workspaces/${ws.slug}` }));
121
+ logger.log(t('workspace.status_created', { date: ws.createdAt }));
122
+
123
+ return { ok: true, linked: true, ...ws };
124
+ }
125
+
126
+ async function runWorkspaceOpen({ args, options, logger, t }) {
127
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
128
+ const projectDir = await findProjectRoot(targetDir);
129
+ const ws = await readWorkspace(projectDir);
130
+
131
+ if (!ws) {
132
+ logger.log(t('workspace.not_linked'));
133
+ logger.log(t('workspace.init_hint'));
134
+ return { ok: false, error: { code: 'not_linked' } };
135
+ }
136
+
137
+ const config = await readConfig();
138
+ const baseUrl = String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
139
+ const url = `${baseUrl}/workspaces/${ws.slug}`;
140
+ logger.log(t('workspace.open_url', { url }));
141
+ return { ok: true, url };
142
+ }
143
+
144
+ module.exports = { runWorkspaceInit, runWorkspaceStatus, runWorkspaceOpen, readWorkspace, findProjectRoot };
package/src/constants.js CHANGED
@@ -29,7 +29,9 @@ const MANAGED_FILES = [
29
29
  '.aioson/agents/pm.md',
30
30
  '.aioson/agents/dev.md',
31
31
  '.aioson/agents/qa.md',
32
+ '.aioson/agents/tester.md',
32
33
  '.aioson/agents/orchestrator.md',
34
+ '.aioson/agents/pentester.md',
33
35
  '.aioson/agents/squad.md',
34
36
  '.aioson/agents/orache.md',
35
37
  '.aioson/agents/genome.md',
@@ -39,78 +41,28 @@ const MANAGED_FILES = [
39
41
  '.aioson/agents/profiler-enricher.md',
40
42
  '.aioson/agents/profiler-forge.md',
41
43
  '.aioson/agents/copywriter.md',
42
- '.aioson/locales/en/agents/setup.md',
43
- '.aioson/locales/en/agents/discovery-design-doc.md',
44
- '.aioson/locales/en/agents/analyst.md',
45
- '.aioson/locales/en/agents/architect.md',
46
- '.aioson/locales/en/agents/ux-ui.md',
47
- '.aioson/locales/en/agents/product.md',
48
- '.aioson/locales/en/agents/deyvin.md',
49
- '.aioson/locales/en/agents/pair.md',
50
- '.aioson/locales/en/agents/pm.md',
51
- '.aioson/locales/en/agents/dev.md',
52
- '.aioson/locales/en/agents/qa.md',
53
- '.aioson/locales/en/agents/orchestrator.md',
54
- '.aioson/locales/en/agents/squad.md',
55
- '.aioson/locales/en/agents/orache.md',
56
- '.aioson/locales/en/agents/genome.md',
57
- '.aioson/locales/en/agents/profiler-researcher.md',
58
- '.aioson/locales/en/agents/profiler-enricher.md',
59
- '.aioson/locales/en/agents/profiler-forge.md',
60
- '.aioson/locales/pt-BR/agents/setup.md',
61
- '.aioson/locales/pt-BR/agents/discovery-design-doc.md',
62
- '.aioson/locales/pt-BR/agents/analyst.md',
63
- '.aioson/locales/pt-BR/agents/architect.md',
64
- '.aioson/locales/pt-BR/agents/ux-ui.md',
65
- '.aioson/locales/pt-BR/agents/product.md',
66
- '.aioson/locales/pt-BR/agents/deyvin.md',
67
- '.aioson/locales/pt-BR/agents/pair.md',
68
- '.aioson/locales/pt-BR/agents/pm.md',
69
- '.aioson/locales/pt-BR/agents/dev.md',
70
- '.aioson/locales/pt-BR/agents/qa.md',
71
- '.aioson/locales/pt-BR/agents/orchestrator.md',
72
- '.aioson/locales/pt-BR/agents/squad.md',
73
- '.aioson/locales/pt-BR/agents/orache.md',
74
- '.aioson/locales/pt-BR/agents/genome.md',
75
- '.aioson/locales/pt-BR/agents/profiler-researcher.md',
76
- '.aioson/locales/pt-BR/agents/profiler-enricher.md',
77
- '.aioson/locales/pt-BR/agents/profiler-forge.md',
78
- '.aioson/locales/es/agents/setup.md',
79
- '.aioson/locales/es/agents/discovery-design-doc.md',
80
- '.aioson/locales/es/agents/analyst.md',
81
- '.aioson/locales/es/agents/architect.md',
82
- '.aioson/locales/es/agents/ux-ui.md',
83
- '.aioson/locales/es/agents/product.md',
84
- '.aioson/locales/es/agents/deyvin.md',
85
- '.aioson/locales/es/agents/pair.md',
86
- '.aioson/locales/es/agents/pm.md',
87
- '.aioson/locales/es/agents/dev.md',
88
- '.aioson/locales/es/agents/qa.md',
89
- '.aioson/locales/es/agents/orchestrator.md',
90
- '.aioson/locales/es/agents/squad.md',
91
- '.aioson/locales/es/agents/orache.md',
92
- '.aioson/locales/es/agents/genome.md',
93
- '.aioson/locales/es/agents/profiler-researcher.md',
94
- '.aioson/locales/es/agents/profiler-enricher.md',
95
- '.aioson/locales/es/agents/profiler-forge.md',
96
- '.aioson/locales/fr/agents/setup.md',
97
- '.aioson/locales/fr/agents/discovery-design-doc.md',
98
- '.aioson/locales/fr/agents/analyst.md',
99
- '.aioson/locales/fr/agents/architect.md',
100
- '.aioson/locales/fr/agents/ux-ui.md',
101
- '.aioson/locales/fr/agents/product.md',
102
- '.aioson/locales/fr/agents/deyvin.md',
103
- '.aioson/locales/fr/agents/pair.md',
104
- '.aioson/locales/fr/agents/pm.md',
105
- '.aioson/locales/fr/agents/dev.md',
106
- '.aioson/locales/fr/agents/qa.md',
107
- '.aioson/locales/fr/agents/orchestrator.md',
108
- '.aioson/locales/fr/agents/squad.md',
109
- '.aioson/locales/fr/agents/orache.md',
110
- '.aioson/locales/fr/agents/genome.md',
111
- '.aioson/locales/fr/agents/profiler-researcher.md',
112
- '.aioson/locales/fr/agents/profiler-enricher.md',
113
- '.aioson/locales/fr/agents/profiler-forge.md',
44
+ '.aioson/docs/squad/package-contract.md',
45
+ '.aioson/docs/squad/creation-flow.md',
46
+ '.aioson/docs/squad/research-loop.md',
47
+ '.aioson/docs/squad/quality-lens.md',
48
+ '.aioson/docs/squad/workflow-quality.md',
49
+ '.aioson/docs/squad/content-output.md',
50
+ '.aioson/docs/squad/session-operations.md',
51
+ '.aioson/docs/squad/genome-bindings.md',
52
+ '.aioson/docs/product/conversation-playbook.md',
53
+ '.aioson/docs/product/research-loop.md',
54
+ '.aioson/docs/product/quality-lens.md',
55
+ '.aioson/docs/product/prd-contract.md',
56
+ '.aioson/docs/deyvin/continuity-recovery.md',
57
+ '.aioson/docs/deyvin/pair-execution.md',
58
+ '.aioson/docs/deyvin/runtime-handoffs.md',
59
+ '.aioson/docs/deyvin/debugging-escalation.md',
60
+ '.aioson/docs/sheldon/research-loop.md',
61
+ '.aioson/docs/sheldon/web-intelligence.md',
62
+ '.aioson/docs/sheldon/quality-lens.md',
63
+ '.aioson/docs/sheldon/enrichment-paths.md',
64
+ '.aioson/docs/dev/stack-conventions.md',
65
+ '.aioson/docs/dev/execution-discipline.md',
114
66
  '.aioson/skills/static/laravel-conventions.md',
115
67
  '.aioson/skills/static/tall-stack-patterns.md',
116
68
  '.aioson/skills/static/jetstream-setup.md',
@@ -217,7 +169,7 @@ const CONTEXT_REQUIRED_FIELDS = [
217
169
  ];
218
170
 
219
171
  const CONTEXT_ALLOWED_CLASSIFICATIONS = ['MICRO', 'SMALL', 'MEDIUM'];
220
- const CONTEXT_ALLOWED_PROJECT_TYPES = ['web_app', 'api', 'site', 'script', 'dapp'];
172
+ const CONTEXT_ALLOWED_PROJECT_TYPES = ['web_app', 'api', 'site', 'script', 'dapp', 'desktop_app'];
221
173
  const CONTEXT_ALLOWED_PROFILES = ['developer', 'beginner', 'team'];
222
174
 
223
175
  const AGENT_DEFINITIONS = [
@@ -295,7 +247,8 @@ const AGENT_DEFINITIONS = [
295
247
  '.aioson/context/project.context.md',
296
248
  '.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
297
249
  '.aioson/context/discovery.md',
298
- '.aioson/context/architecture.md'
250
+ '.aioson/context/architecture.md',
251
+ '.aioson/context/ui-spec.md (when present)'
299
252
  ],
300
253
  output: '.aioson/context/prd.md or prd-{slug}.md (enriched with delivery plan and acceptance criteria)'
301
254
  },
@@ -311,6 +264,17 @@ const AGENT_DEFINITIONS = [
311
264
  ],
312
265
  output: 'code changes'
313
266
  },
267
+ {
268
+ id: 'pentester',
269
+ displayName: 'Pentester',
270
+ command: '@pentester',
271
+ path: '.aioson/agents/pentester.md',
272
+ dependsOn: [
273
+ '.aioson/context/project.context.md',
274
+ '.aioson/context/spec-{slug}.md (active feature)'
275
+ ],
276
+ output: '.aioson/context/security-findings-{slug}.json'
277
+ },
314
278
  {
315
279
  id: 'qa',
316
280
  displayName: 'QA',
@@ -333,9 +297,12 @@ const AGENT_DEFINITIONS = [
333
297
  command: '@orchestrator',
334
298
  path: '.aioson/agents/orchestrator.md',
335
299
  dependsOn: [
300
+ '.aioson/context/project.context.md',
336
301
  '.aioson/context/discovery.md',
337
302
  '.aioson/context/architecture.md',
338
- '.aioson/context/prd.md'
303
+ '.aioson/context/prd.md or .aioson/context/prd-{slug}.md',
304
+ '.aioson/context/ui-spec.md (when present)',
305
+ '.aioson/context/implementation-plan.md or implementation-plan-{slug}.md (when present)'
339
306
  ],
340
307
  output: '.aioson/context/parallel/*.status.md'
341
308
  },
@@ -21,6 +21,11 @@ const SCAN_INDEX_FILE = `${CONTEXT_DIR}/scan-index.md`;
21
21
  const SCAN_FOLDERS_FILE = `${CONTEXT_DIR}/scan-folders.md`;
22
22
  const SCAN_AIOSON_FILE = `${CONTEXT_DIR}/scan-aioson.md`;
23
23
  const CONTEXT_PACK_FILE = `${CONTEXT_DIR}/context-pack.md`;
24
+ const BOOTSTRAP_DIR = '.aioson/context/bootstrap';
25
+ const BOOTSTRAP_WHAT_IS = `${BOOTSTRAP_DIR}/what-is.md`;
26
+ const BOOTSTRAP_HOW_IT_WORKS = `${BOOTSTRAP_DIR}/how-it-works.md`;
27
+ const BOOTSTRAP_WHAT_IT_DOES = `${BOOTSTRAP_DIR}/what-it-does.md`;
28
+ const BOOTSTRAP_CURRENT_STATE = `${BOOTSTRAP_DIR}/current-state.md`;
24
29
 
25
30
  const SPEC_SECTION_ALIASES = {
26
31
  stack: ['stack'],
@@ -138,6 +143,34 @@ const CONTEXT_DOC_SPECS = [
138
143
  group: 'scan',
139
144
  readWhen: 'you need generated context pages, squads, genomes or local MCP artifacts',
140
145
  tags: ['scan', 'brownfield', 'aioson']
146
+ },
147
+ {
148
+ relPath: BOOTSTRAP_WHAT_IS,
149
+ title: 'System Identity',
150
+ group: 'bootstrap',
151
+ readWhen: 'you need to understand what the system IS, who uses it, and why it exists',
152
+ tags: ['bootstrap', 'identity', 'semantic']
153
+ },
154
+ {
155
+ relPath: BOOTSTRAP_HOW_IT_WORKS,
156
+ title: 'System Mechanics',
157
+ group: 'bootstrap',
158
+ readWhen: 'you need to understand how the system works — architecture, modules, data flow',
159
+ tags: ['bootstrap', 'architecture', 'semantic']
160
+ },
161
+ {
162
+ relPath: BOOTSTRAP_WHAT_IT_DOES,
163
+ title: 'System Features',
164
+ group: 'bootstrap',
165
+ readWhen: 'you need to know what features exist, business rules, and user workflows',
166
+ tags: ['bootstrap', 'features', 'semantic']
167
+ },
168
+ {
169
+ relPath: BOOTSTRAP_CURRENT_STATE,
170
+ title: 'System Current State',
171
+ group: 'bootstrap',
172
+ readWhen: 'you need to know what is implemented, in progress, or planned',
173
+ tags: ['bootstrap', 'state', 'semantic']
141
174
  }
142
175
  ];
143
176
 
@@ -499,9 +532,10 @@ function buildMemoryIndexMarkdown({ generatedAt, catalog }) {
499
532
  ''
500
533
  ];
501
534
 
502
- const groupOrder = ['foundation', 'system', 'development', 'scope', 'modules', 'scan'];
535
+ const groupOrder = ['foundation', 'bootstrap', 'system', 'development', 'scope', 'modules', 'scan'];
503
536
  const groupTitles = {
504
537
  foundation: 'Foundation Docs',
538
+ bootstrap: 'Bootstrap — Semantic Knowledge Cache',
505
539
  system: 'System Memory',
506
540
  development: 'Development Memory',
507
541
  scope: 'Scope Docs',
@@ -534,6 +568,7 @@ function rankContextDoc(doc, { agent, goal, module }) {
534
568
  const lowerGoal = normalizeForLookup(goal);
535
569
  const lowerAgent = normalizeForLookup(agent);
536
570
  const lowerModule = normalizeForLookup(module);
571
+ const lookupText = `${lowerAgent} ${lowerGoal}`.trim();
537
572
 
538
573
  if (doc.relPath === PROJECT_CONTEXT_FILE) {
539
574
  score += 100;
@@ -579,6 +614,24 @@ function rankContextDoc(doc, { agent, goal, module }) {
579
614
  score += 35;
580
615
  reasons.push('readiness signal');
581
616
  }
617
+ if (doc.group === 'bootstrap') {
618
+ if (doc.relPath === BOOTSTRAP_WHAT_IS && /(product|analyst|what|identity|understand|discover|bootstrap|memory|continuity)/.test(lookupText)) {
619
+ score += 70;
620
+ reasons.push('semantic system identity');
621
+ }
622
+ if (doc.relPath === BOOTSTRAP_HOW_IT_WORKS && /(dev|architect|how|architecture|implement|refactor|bootstrap|memory|continuity)/.test(lookupText)) {
623
+ score += 70;
624
+ reasons.push('semantic system mechanics');
625
+ }
626
+ if (doc.relPath === BOOTSTRAP_WHAT_IT_DOES && /(product|analyst|feature|business|rule|workflow|bootstrap|memory|continuity)/.test(lookupText)) {
627
+ score += 65;
628
+ reasons.push('semantic features and business rules');
629
+ }
630
+ if (doc.relPath === BOOTSTRAP_CURRENT_STATE && /(dev|qa|state|current|progress|status|bootstrap|memory|continuity)/.test(lookupText)) {
631
+ score += 65;
632
+ reasons.push('semantic current state');
633
+ }
634
+ }
582
635
  if (/module-/.test(doc.relPath) && lowerModule) {
583
636
  if (normalizeForLookup(doc.relPath).includes(lowerModule)) {
584
637
  score += 80;
@@ -737,6 +790,67 @@ async function writeDerivedContextMemory({
737
790
  };
738
791
  }
739
792
 
793
+ async function collectActiveDossiers(targetDir) {
794
+ const featuresDir = path.join(targetDir, CONTEXT_DIR, 'features');
795
+ let slugs = [];
796
+ try {
797
+ const entries = await fs.readdir(featuresDir, { withFileTypes: true });
798
+ slugs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
799
+ } catch {
800
+ return [];
801
+ }
802
+
803
+ const active = [];
804
+ for (const slug of slugs) {
805
+ const p = path.join(featuresDir, slug, 'dossier.md');
806
+ try {
807
+ const raw = await fs.readFile(p, 'utf8');
808
+ const statusMatch = raw.match(/^status:\s*(\S+)\s*$/m);
809
+ const updatedMatch = raw.match(/^last_updated_at:\s*(\S+)\s*$/m);
810
+ if (!statusMatch || statusMatch[1] !== 'active') continue;
811
+ const relPath = `${CONTEXT_DIR}/features/${slug}/dossier.md`;
812
+ active.push({
813
+ relPath,
814
+ slug,
815
+ lastUpdatedAt: updatedMatch ? updatedMatch[1] : null,
816
+ title: `Feature Dossier (${slug})`,
817
+ group: 'dossier',
818
+ readWhen: `active feature "${slug}" synthesis — why, what, code map, agent trail`,
819
+ tags: ['dossier', 'feature', 'active'],
820
+ exists: true
821
+ });
822
+ } catch {
823
+ // skip unreadable
824
+ }
825
+ }
826
+
827
+ // Sort by last_updated_at descending (most recent first)
828
+ active.sort((a, b) => {
829
+ if (!a.lastUpdatedAt && !b.lastUpdatedAt) return 0;
830
+ if (!a.lastUpdatedAt) return 1;
831
+ if (!b.lastUpdatedAt) return -1;
832
+ return b.lastUpdatedAt.localeCompare(a.lastUpdatedAt);
833
+ });
834
+
835
+ return active;
836
+ }
837
+
838
+ function rankDossier(dossier, { agent, goal }, rank) {
839
+ // Base score: between PRD (45) and bootstrap (65). Most recent dossier gets 60.
840
+ let score = 60 - rank * 5;
841
+ const reasons = [`active feature dossier (${dossier.slug})`];
842
+ const lookupText = `${normalizeForLookup(agent)} ${normalizeForLookup(goal)}`.trim();
843
+ if (lookupText.includes(dossier.slug.replace(/-/g, ' '))) {
844
+ score += 15;
845
+ reasons.push('matches active feature slug');
846
+ }
847
+ if (/(dev|architect|qa|implement|feature|dossier)/.test(lookupText)) {
848
+ score += 10;
849
+ reasons.push('agent/goal matches dossier context');
850
+ }
851
+ return { score: Math.max(score, 0), reasons };
852
+ }
853
+
740
854
  async function createContextPack({
741
855
  targetDir,
742
856
  agent = '',
@@ -752,15 +866,25 @@ async function createContextPack({
752
866
  : 8;
753
867
 
754
868
  const catalog = (await collectContextCatalog(targetDir)).filter((doc) => doc.exists);
755
- const ranked = catalog
756
- .map((doc) => {
869
+
870
+ // Inject active dossiers as ranked sources (reference, not inline copy)
871
+ const activeDossiers = await collectActiveDossiers(targetDir);
872
+ const dossierDocs = activeDossiers.map((d, i) => {
873
+ const rank = rankDossier(d, { agent, goal }, i);
874
+ return { ...d, score: rank.score, reason: rank.reasons.join('; ') };
875
+ });
876
+
877
+ const ranked = [
878
+ ...catalog.map((doc) => {
757
879
  const rank = rankContextDoc(doc, { agent, goal, module });
758
880
  return {
759
881
  ...doc,
760
882
  score: rank.score,
761
883
  reason: rank.reasons.join('; ') || doc.readWhen
762
884
  };
763
- })
885
+ }),
886
+ ...dossierDocs
887
+ ]
764
888
  .filter((doc) => doc.score > 0)
765
889
  .sort((a, b) => b.score - a.score || a.relPath.localeCompare(b.relPath));
766
890
 
@@ -826,6 +950,11 @@ module.exports = {
826
950
  SCAN_FOLDERS_FILE,
827
951
  SCAN_AIOSON_FILE,
828
952
  CONTEXT_PACK_FILE,
953
+ BOOTSTRAP_DIR,
954
+ BOOTSTRAP_WHAT_IS,
955
+ BOOTSTRAP_HOW_IT_WORKS,
956
+ BOOTSTRAP_WHAT_IT_DOES,
957
+ BOOTSTRAP_CURRENT_STATE,
829
958
  buildModuleMemoryRelativePath,
830
959
  buildSpecCurrentMarkdown,
831
960
  buildSpecHistoryMarkdown,
@@ -60,7 +60,7 @@ function normalizeBoolean(value, fallback = false) {
60
60
  }
61
61
 
62
62
  function renderProjectContext(data) {
63
- const language = data.conversationLanguage || 'en';
63
+ const language = data.interactionLanguage || data.conversationLanguage || 'en';
64
64
  const codeCommentLanguage = data.codeCommentLanguage || language;
65
65
  const generatedAt = data.generatedAt || new Date().toISOString();
66
66
  const designSkill = data.designSkill || '';
@@ -80,6 +80,7 @@ profile: "${data.profile}"
80
80
  framework: "${data.framework}"
81
81
  framework_installed: ${data.frameworkInstalled ? 'true' : 'false'}
82
82
  classification: "${data.classification}"
83
+ interaction_language: "${language}"
83
84
  conversation_language: "${language}"
84
85
  design_skill: "${designSkill}"
85
86
  test_runner: "${testRunner}"
package/src/context.js CHANGED
@@ -86,6 +86,23 @@ function isValidLanguageTag(value) {
86
86
  return /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$/.test(tag);
87
87
  }
88
88
 
89
+ function normalizeLanguageTag(value, fallback = 'en') {
90
+ const tag = String(value || '').trim().replace(/_/g, '-');
91
+ if (!tag) return fallback;
92
+ return isValidLanguageTag(tag) ? tag : fallback;
93
+ }
94
+
95
+ function getInteractionLanguage(data, fallback = 'en') {
96
+ if (!data || typeof data !== 'object') return fallback;
97
+ if (Object.prototype.hasOwnProperty.call(data, 'interaction_language')) {
98
+ return normalizeLanguageTag(data.interaction_language, fallback);
99
+ }
100
+ if (Object.prototype.hasOwnProperty.call(data, 'conversation_language')) {
101
+ return normalizeLanguageTag(data.conversation_language, fallback);
102
+ }
103
+ return fallback;
104
+ }
105
+
89
106
  function validateContextData(data) {
90
107
  const issues = [];
91
108
 
@@ -148,6 +165,18 @@ function validateContextData(data) {
148
165
  });
149
166
  }
150
167
 
168
+ if (
169
+ Object.prototype.hasOwnProperty.call(data, 'interaction_language') &&
170
+ !isValidLanguageTag(data.interaction_language)
171
+ ) {
172
+ issues.push({
173
+ id: 'context:interaction_language:format',
174
+ key: 'doctor.context_interaction_language_format',
175
+ params: {},
176
+ hintKey: 'doctor.context_interaction_language_format_hint'
177
+ });
178
+ }
179
+
151
180
  if (
152
181
  Object.prototype.hasOwnProperty.call(data, 'conversation_language') &&
153
182
  !isValidLanguageTag(data.conversation_language)
@@ -212,6 +241,7 @@ module.exports = {
212
241
  parseYamlFrontmatter,
213
242
  validateContextData,
214
243
  validateProjectContextFile,
215
- isValidLanguageTag
244
+ isValidLanguageTag,
245
+ normalizeLanguageTag,
246
+ getInteractionLanguage
216
247
  };
217
-
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({