@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,392 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { exists, ensureDir } = require('../utils');
6
+ const { readConfig } = require('./config');
7
+ const { readWorkspace, findProjectRoot } = require('./workspace');
8
+
9
+ const DEFAULT_BASE_URL = 'https://aioson.com';
10
+ const SYSTEM_PACKAGES_DIR = '.aioson/system-packages';
11
+ const BACKUPS_DIR = '.aioson/.backups';
12
+
13
+ // Extensions allowed in a system package (Vite React source tree)
14
+ const SYSTEM_ALLOWED_EXTS = new Set([
15
+ '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
16
+ '.json', '.jsonc',
17
+ '.css', '.scss', '.sass', '.less',
18
+ '.html',
19
+ '.svg', '.ico',
20
+ '.md', '.txt',
21
+ '.sql',
22
+ '.env', '.env.example', '.env.template',
23
+ '.yaml', '.yml',
24
+ '.toml',
25
+ '.gitignore',
26
+ ]);
27
+
28
+ // Dirs/files to skip when collecting sources
29
+ const SKIP_DIRS = new Set([
30
+ 'node_modules', '.git', 'dist', 'build', '.turbo', '.next',
31
+ '.cache', 'coverage', '.nyc_output', 'out',
32
+ // AIOSON tooling — não faz parte do código-fonte do sistema
33
+ '.aioson', '.claude', '.gemini', '.codex', 'researchs',
34
+ ]);
35
+
36
+ const SKIP_FILES = new Set([
37
+ 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml',
38
+ 'bun.lockb',
39
+ ]);
40
+
41
+ const MAX_FILE_BYTES = 512 * 1024; // 512 KB per file
42
+ const MAX_PACKAGE_BYTES = 20 * 1024 * 1024; // 20 MB total
43
+
44
+ /**
45
+ * Parseia lista de emails autorizados a partir de:
46
+ * 1. Flag CLI --invite="email1,email2,email3" (string com separadores , ; espaço quebra)
47
+ * 2. Fallback: campo `authorized_emails` no system.json (array ou string)
48
+ * Devolve array dedup, lowercase, trimmed, validado (contém @).
49
+ */
50
+ function parseInviteEmails(cliInvite, manifestEmails) {
51
+ const raw = cliInvite ?? manifestEmails;
52
+ if (!raw) return [];
53
+ let parts;
54
+ if (Array.isArray(raw)) {
55
+ parts = raw.map(String);
56
+ } else {
57
+ parts = String(raw).split(/[,;\s\n]+/);
58
+ }
59
+ return Array.from(new Set(
60
+ parts.map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0 && s.includes('@'))
61
+ ));
62
+ }
63
+
64
+ function resolveBaseUrl(config) {
65
+ return String(config.aiosonBaseUrl || DEFAULT_BASE_URL).replace(/\/+$/, '');
66
+ }
67
+
68
+ function requireToken(config, t) {
69
+ const token = config.aiosonToken;
70
+ if (!token) throw new Error(t('store.error_not_authenticated'));
71
+ return token;
72
+ }
73
+
74
+ async function storePost(url, payload, token) {
75
+ const response = await fetch(url, {
76
+ method: 'POST',
77
+ headers: {
78
+ authorization: `Bearer ${token}`,
79
+ 'content-type': 'application/json',
80
+ accept: 'application/json',
81
+ },
82
+ body: JSON.stringify(payload),
83
+ signal: AbortSignal.timeout(120000),
84
+ });
85
+
86
+ const text = await response.text();
87
+ let parsed = null;
88
+ try { parsed = JSON.parse(text); } catch { /* */ }
89
+
90
+ if (!response.ok) {
91
+ const detail = (parsed && parsed.error) ? String(parsed.error) : `${response.status} ${response.statusText}`;
92
+ throw new Error(`HTTP ${response.status}: ${detail}`);
93
+ }
94
+
95
+ return parsed;
96
+ }
97
+
98
+ async function storeGet(url, token) {
99
+ const response = await fetch(url, {
100
+ headers: { authorization: `Bearer ${token}`, accept: 'application/json' },
101
+ signal: AbortSignal.timeout(15000),
102
+ });
103
+ const text = await response.text();
104
+ let parsed = null;
105
+ try { parsed = JSON.parse(text); } catch { /* */ }
106
+ if (!response.ok) {
107
+ const detail = (parsed && parsed.error) ? String(parsed.error) : `${response.status} ${response.statusText}`;
108
+ throw new Error(`HTTP ${response.status}: ${detail}`);
109
+ }
110
+ return parsed;
111
+ }
112
+
113
+ /**
114
+ * Collect all eligible source files under `dir`.
115
+ * Returns { relativePath: content } — only text files with allowed extensions.
116
+ */
117
+ async function collectSystemFiles(dir) {
118
+ const files = {};
119
+ let totalBytes = 0;
120
+ const errors = [];
121
+
122
+ async function walk(current, rel) {
123
+ const entries = await fs.readdir(current, { withFileTypes: true });
124
+ for (const entry of entries) {
125
+ if (SKIP_DIRS.has(entry.name)) continue;
126
+ if (SKIP_FILES.has(entry.name)) continue;
127
+
128
+ const fullPath = path.join(current, entry.name);
129
+ const relPath = rel ? `${rel}/${entry.name}` : entry.name;
130
+
131
+ if (entry.isDirectory()) {
132
+ await walk(fullPath, relPath);
133
+ continue;
134
+ }
135
+
136
+ const ext = entry.name.includes('.')
137
+ ? `.${entry.name.split('.').pop().toLowerCase()}`
138
+ : '';
139
+
140
+ // Allow dotfiles with no extension (like .gitignore) that match skip list check
141
+ if (!SYSTEM_ALLOWED_EXTS.has(ext) && ext !== '') continue;
142
+
143
+ try {
144
+ const stat = await fs.stat(fullPath);
145
+ if (stat.size > MAX_FILE_BYTES) {
146
+ errors.push(`File too large (skipped): "${relPath}" (${(stat.size / 1024).toFixed(0)} KB)`);
147
+ continue;
148
+ }
149
+ totalBytes += stat.size;
150
+ if (totalBytes > MAX_PACKAGE_BYTES) {
151
+ errors.push(`Package exceeds ${MAX_PACKAGE_BYTES / 1024 / 1024} MB limit — stop collecting.`);
152
+ return;
153
+ }
154
+ const content = await fs.readFile(fullPath, 'utf8');
155
+ files[relPath] = content;
156
+ } catch {
157
+ // binary or unreadable — skip silently
158
+ }
159
+ }
160
+ }
161
+
162
+ await walk(dir, '');
163
+ return { files, totalBytes, errors };
164
+ }
165
+
166
+ /**
167
+ * Parse and validate system.json.
168
+ * Returns the parsed manifest or throws.
169
+ */
170
+ async function readSystemJson(dir, t) {
171
+ const manifestPath = path.join(dir, 'system.json');
172
+ if (!(await exists(manifestPath))) {
173
+ throw new Error(t('system.error_no_manifest', { path: manifestPath }));
174
+ }
175
+ let manifest;
176
+ try {
177
+ manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
178
+ } catch {
179
+ throw new Error(t('system.error_invalid_manifest'));
180
+ }
181
+ if (!manifest.slug) throw new Error(t('system.error_manifest_missing_slug'));
182
+ if (!manifest.version) throw new Error(t('system.error_manifest_missing_version'));
183
+ if (!manifest.name) throw new Error(t('system.error_manifest_missing_name'));
184
+ return manifest;
185
+ }
186
+
187
+ // ── system:package ──────────────────────────────────────────────────────────
188
+
189
+ async function runSystemPackage({ args, options, logger, t }) {
190
+ const dir = path.resolve(process.cwd(), args[0] || '.');
191
+
192
+ logger.log(t('system.package_reading_manifest'));
193
+ const manifest = await readSystemJson(dir, t);
194
+ logger.log(t('system.package_manifest_ok', { slug: manifest.slug, version: manifest.version, name: manifest.name }));
195
+
196
+ logger.log(t('system.package_collecting_files'));
197
+ const { files, totalBytes, errors } = await collectSystemFiles(dir);
198
+
199
+ if (errors.length > 0) {
200
+ for (const e of errors) logger.log(` [WARN] ${e}`);
201
+ }
202
+
203
+ const fileCount = Object.keys(files).length;
204
+ logger.log(t('system.package_files_found', { count: fileCount, kb: (totalBytes / 1024).toFixed(1) }));
205
+
206
+ if (!files['system.json']) {
207
+ throw new Error(t('system.error_no_manifest', { path: path.join(dir, 'system.json') }));
208
+ }
209
+
210
+ if (options['dry-run']) {
211
+ logger.log(t('system.package_dry_run', { slug: manifest.slug, version: manifest.version }));
212
+ for (const f of Object.keys(files).sort()) logger.log(` ${f}`);
213
+ return { ok: true, dryRun: true, manifest, fileCount, totalBytes };
214
+ }
215
+
216
+ // Save package descriptor locally
217
+ const projectDir = await findProjectRoot(dir);
218
+ const pkgDir = path.join(projectDir, SYSTEM_PACKAGES_DIR, manifest.slug);
219
+ await ensureDir(pkgDir);
220
+
221
+ const pkgFile = path.join(pkgDir, `${manifest.slug}-${manifest.version}.json`);
222
+ await fs.writeFile(pkgFile, JSON.stringify({ manifest, files }, null, 2), 'utf8');
223
+
224
+ logger.log(t('system.package_saved', { path: pkgFile }));
225
+ return { ok: true, manifest, fileCount, totalBytes, path: pkgFile };
226
+ }
227
+
228
+ // ── system:publish ──────────────────────────────────────────────────────────
229
+
230
+ async function runSystemPublish({ args, options, logger, t }) {
231
+ const config = await readConfig();
232
+ const token = requireToken(config, t);
233
+ const dir = path.resolve(process.cwd(), args[0] || '.');
234
+
235
+ logger.log(t('system.publish_reading_manifest'));
236
+ const manifest = await readSystemJson(dir, t);
237
+ logger.log(t('system.package_manifest_ok', { slug: manifest.slug, version: manifest.version, name: manifest.name }));
238
+
239
+ logger.log(t('system.package_collecting_files'));
240
+ const { files, totalBytes, errors } = await collectSystemFiles(dir);
241
+
242
+ if (errors.length > 0) {
243
+ for (const e of errors) logger.log(` [WARN] ${e}`);
244
+ }
245
+
246
+ const fileCount = Object.keys(files).length;
247
+ logger.log(t('system.package_files_found', { count: fileCount, kb: (totalBytes / 1024).toFixed(1) }));
248
+
249
+ // Basic integrity checks
250
+ if (!files['system.json']) {
251
+ throw new Error(t('system.error_no_manifest', { path: path.join(dir, 'system.json') }));
252
+ }
253
+ if (!files['package.json']) {
254
+ throw new Error(t('system.error_missing_package_json'));
255
+ }
256
+
257
+ const visibility = options.private ? 'private' : 'public';
258
+ const paid = Boolean(options.paid);
259
+ const ws = await readWorkspace(dir);
260
+
261
+ // Lista de emails autorizados a instalar quando visibility=private.
262
+ // Aceita via --invite="email1,email2" OU campo `authorized_emails` no
263
+ // manifest (system.json). Sem efeito quando visibility !== private.
264
+ const authorizedEmails = parseInviteEmails(options.invite, manifest.authorized_emails);
265
+
266
+ if (options['dry-run']) {
267
+ logger.log(t('system.publish_dry_run', { slug: manifest.slug, version: manifest.version, visibility }));
268
+ return { ok: true, dryRun: true, manifest, fileCount, totalBytes, visibility, authorizedEmails };
269
+ }
270
+
271
+ logger.log(t('system.publish_sending'));
272
+ const baseUrl = resolveBaseUrl(config);
273
+ const response = await storePost(`${baseUrl}/api/store/systems/publish`, {
274
+ kind: 'aioson.store.system',
275
+ slug: manifest.slug,
276
+ version: manifest.version,
277
+ files,
278
+ manifest,
279
+ visibility,
280
+ paid,
281
+ authorizedEmails,
282
+ workspaceSlug: ws?.slug || null,
283
+ }, token);
284
+
285
+ logger.log(t('system.publish_done', { slug: manifest.slug, url: `${baseUrl}/store/systems/${manifest.slug}` }));
286
+ logger.log(t('system.publish_summary', { files: fileCount, kb: (totalBytes / 1024).toFixed(1) }));
287
+ return { ok: true, manifest, fileCount, totalBytes, visibility, paid, response };
288
+ }
289
+
290
+ // ── system:list ─────────────────────────────────────────────────────────────
291
+
292
+ async function runSystemList({ args, options, logger, t }) {
293
+ if (options.remote) {
294
+ const config = await readConfig();
295
+ const token = requireToken(config, t);
296
+ const baseUrl = resolveBaseUrl(config);
297
+ logger.log(t('list_remote_fetching', { type: 'systems' }));
298
+ const response = await storeGet(`${baseUrl}/api/store/systems`, token);
299
+ const systems = response.systems || [];
300
+ if (systems.length === 0) {
301
+ logger.log(t('system.list_remote_empty'));
302
+ } else {
303
+ logger.log(t('system.list_remote_header', { count: systems.length }));
304
+ for (const s of systems) {
305
+ logger.log(t('system.list_remote_item', { slug: s.slug, name: s.name || s.slug, version: s.version || '?', visibility: s.visibility || '?' }));
306
+ }
307
+ }
308
+ return { ok: true, systems, remote: true };
309
+ }
310
+
311
+ // Local: list cached system packages
312
+ const projectDir = await findProjectRoot(path.resolve(process.cwd(), args[0] || '.'));
313
+ const pkgsDir = path.join(projectDir, SYSTEM_PACKAGES_DIR);
314
+
315
+ if (!(await exists(pkgsDir))) {
316
+ logger.log(t('system.list_local_empty'));
317
+ return { ok: true, systems: [] };
318
+ }
319
+
320
+ const entries = await fs.readdir(pkgsDir, { withFileTypes: true });
321
+ const systems = entries
322
+ .filter(e => e.isDirectory())
323
+ .map(e => ({ slug: e.name }));
324
+
325
+ if (systems.length === 0) {
326
+ logger.log(t('system.list_local_empty'));
327
+ } else {
328
+ logger.log(t('system.list_local_header', { count: systems.length }));
329
+ for (const s of systems) {
330
+ logger.log(t('system.list_local_item', { slug: s.slug }));
331
+ }
332
+ }
333
+
334
+ return { ok: true, systems };
335
+ }
336
+
337
+ // ── system:install (developer use — downloads source from store) ─────────────
338
+
339
+ async function runSystemInstall({ args, options, logger, t }) {
340
+ const config = await readConfig();
341
+ const token = requireToken(config, t);
342
+ const projectDir = await findProjectRoot(path.resolve(process.cwd(), args[0] || '.'));
343
+ const baseUrl = resolveBaseUrl(config);
344
+
345
+ const ref = String(options.slug || options.code || args[1] || '').trim();
346
+ if (!ref) throw new Error(t('store.error_missing_code_or_slug'));
347
+
348
+ logger.log(t('system.install_fetching', { ref }));
349
+
350
+ const response = await storePost(`${baseUrl}/api/store/systems/install`, {
351
+ ref,
352
+ workspaceSlug: (await readWorkspace(projectDir))?.slug || null,
353
+ }, token);
354
+
355
+ const slug = response.manifest?.slug || response.slug;
356
+ if (!slug || !response.files) throw new Error(t('store.error_invalid_response'));
357
+
358
+ const version = response.manifest?.version || '?';
359
+ const publisher = response.publisher || 'unknown';
360
+ logger.log(t('store.install_preview_header', { slug, version, publisher }));
361
+
362
+ if (options.inspect) {
363
+ logger.log(t('store.install_inspect_files', { count: Object.keys(response.files).length }));
364
+ for (const f of Object.keys(response.files).sort()) logger.log(` ${f}`);
365
+ logger.log(t('store.install_inspect_hint'));
366
+ return { ok: true, slug, inspect: true, files: Object.keys(response.files) };
367
+ }
368
+
369
+ const pkgDir = path.join(projectDir, SYSTEM_PACKAGES_DIR, slug);
370
+
371
+ if ((await exists(pkgDir)) && !options.force) {
372
+ const backupDir = path.join(projectDir, BACKUPS_DIR, `system-packages/${slug}`);
373
+ logger.log(t('store.install_backing_up', { path: backupDir }));
374
+ await fs.rm(backupDir, { recursive: true, force: true });
375
+ await fs.cp(pkgDir, backupDir, { recursive: true });
376
+ await fs.rm(pkgDir, { recursive: true, force: true });
377
+ }
378
+
379
+ // Write files
380
+ logger.log(t('system.install_writing'));
381
+ for (const [relPath, content] of Object.entries(response.files)) {
382
+ if (typeof content !== 'string') continue;
383
+ const destPath = path.join(pkgDir, relPath);
384
+ await ensureDir(path.dirname(destPath));
385
+ await fs.writeFile(destPath, content, 'utf8');
386
+ }
387
+
388
+ logger.log(t('system.install_done', { slug, path: pkgDir }));
389
+ return { ok: true, slug, path: pkgDir, manifest: response.manifest };
390
+ }
391
+
392
+ module.exports = { runSystemPackage, runSystemPublish, runSystemList, runSystemInstall };
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ const { TOOL_CAPS, getToolCapabilities, listSupportedTools } = require('../lib/tool-capabilities');
4
+
5
+ // Expose the per-tool capability map (resume support, install command, etc.)
6
+ // so external clients (AIOSON Play, IDE extensions) can drive UI without
7
+ // hard-coding their own copy of this lookup.
8
+ //
9
+ // Usage:
10
+ // aioson tool:capabilities --json
11
+ // aioson tool:capabilities --tool=claude --json
12
+ async function runToolCapabilities({ args: _args, options = {}, logger, t: _t }) {
13
+ const tool = options.tool ? String(options.tool).trim() : null;
14
+
15
+ let payload;
16
+ if (tool) {
17
+ const caps = getToolCapabilities(tool);
18
+ if (!caps) {
19
+ const supported = listSupportedTools();
20
+ throw new Error(`tool_unknown:${tool} (supported: ${supported.join(', ')})`);
21
+ }
22
+ payload = { tool: tool.toLowerCase(), capabilities: caps };
23
+ } else {
24
+ payload = {
25
+ tools: TOOL_CAPS,
26
+ schema_version: 1,
27
+ };
28
+ }
29
+
30
+ if (options.json) {
31
+ logger.log(JSON.stringify(payload, null, 2));
32
+ return { ok: true, payload };
33
+ }
34
+
35
+ // Human-readable fallback
36
+ if (tool) {
37
+ const caps = payload.capabilities;
38
+ logger.log(`Tool: ${payload.tool}`);
39
+ logger.log(` binary: ${caps.binary}`);
40
+ logger.log(` install_command: ${caps.install_command}`);
41
+ logger.log(` supports_resume: ${caps.supports_resume}`);
42
+ if (caps.supports_resume) {
43
+ logger.log(` resume_last: ${(caps.resume_last || []).join(' ')}`);
44
+ logger.log(` supports_session_id: ${caps.supports_session_id}`);
45
+ if (caps.supports_session_id) {
46
+ logger.log(` resume_session_id: ${(caps.resume_session_id || []).join(' ')}`);
47
+ }
48
+ logger.log(` supports_session_picker: ${caps.supports_session_picker}`);
49
+ if (caps.supports_session_picker) {
50
+ logger.log(` session_picker: ${(caps.session_picker || []).join(' ')}`);
51
+ }
52
+ }
53
+ } else {
54
+ logger.log(`Supported tools: ${listSupportedTools().join(', ')}`);
55
+ logger.log(`Run with --tool=<name> for details, or --json for the full map.`);
56
+ }
57
+
58
+ return { ok: true, payload };
59
+ }
60
+
61
+ module.exports = {
62
+ runToolCapabilities,
63
+ };
@@ -3,7 +3,7 @@
3
3
  const path = require('node:path');
4
4
  const { detectFramework } = require('../detector');
5
5
  const { updateInstallation } = require('../updater');
6
- const { validateProjectContextFile } = require('../context');
6
+ const { validateProjectContextFile, getInteractionLanguage } = require('../context');
7
7
  const { applyAgentLocale } = require('../locales');
8
8
 
9
9
  async function runUpdate({ args, options, logger, t }) {
@@ -28,8 +28,8 @@ async function runUpdate({ args, options, logger, t }) {
28
28
  const context = await validateProjectContextFile(targetDir);
29
29
  const language =
30
30
  requestedLanguage ||
31
- (context.parsed && context.data && context.data.conversation_language
32
- ? context.data.conversation_language
31
+ (context.parsed && context.data
32
+ ? getInteractionLanguage(context.data, '')
33
33
  : null) ||
34
34
  (result.savedProfile && result.savedProfile.locale
35
35
  ? result.savedProfile.locale
@@ -454,6 +454,35 @@ async function runVerifyGate({ args, options = {}, logger }) {
454
454
  // ── Parse spec requirements ───────────────────────────────────────────────
455
455
  const requirements = parseSpecRequirements(specContent);
456
456
 
457
+ // ── Harness Integration ───────────────────────────────────────────────────
458
+ let contractCriteria = [];
459
+ if (options.contract) {
460
+ try {
461
+ const contractContent = await fs.readFile(path.resolve(targetDir, options.contract), 'utf8');
462
+ const contract = JSON.parse(contractContent);
463
+ if (contract.criteria && Array.isArray(contract.criteria)) {
464
+ contractCriteria = contract.criteria;
465
+ for (const c of contract.criteria) {
466
+ let mapped = false;
467
+ // Map assertion to deterministic check if possible
468
+ // Pattern mapping: if assertion looks like "path/to/file.js", add to required files
469
+ if (c.assertion.includes('/') && !c.assertion.includes(' ')) {
470
+ requirements.required_files.push(c.assertion.trim());
471
+ mapped = true;
472
+ }
473
+
474
+ // Only add to acceptance criteria for reporting if not deterministically mapped
475
+ // This prevents "Unchecked criterion" issues for things already checked via files/patterns
476
+ if (!mapped) {
477
+ requirements.acceptance_criteria.push({ text: `[Harness ${c.id}] ${c.description}`, checked: false });
478
+ }
479
+ }
480
+ }
481
+ } catch (err) {
482
+ logger.warn(`[VerifyGate] Falha ao ler contrato: ${err.message}`);
483
+ }
484
+ }
485
+
457
486
  // ── Collect artifact files ────────────────────────────────────────────────
458
487
  const allFiles = await collectFiles(artifactPath);
459
488
 
@@ -499,6 +528,16 @@ async function runVerifyGate({ args, options = {}, logger }) {
499
528
  const relOut = path.relative(targetDir, outPath);
500
529
 
501
530
  if (options.json) {
531
+ // Map issues/passes back to contract IDs if possible
532
+ const criteriaResults = contractCriteria.map(c => {
533
+ const passed = !allIssues.some(i => i.includes(c.id) || i.includes(c.assertion));
534
+ return {
535
+ id: c.id,
536
+ passed,
537
+ reason: passed ? null : allIssues.find(i => i.includes(c.id) || i.includes(c.assertion))
538
+ };
539
+ });
540
+
502
541
  return {
503
542
  ok: verdict === 'PASS' || verdict === 'PASS_WITH_NOTES',
504
543
  verdict,
@@ -509,6 +548,7 @@ async function runVerifyGate({ args, options = {}, logger }) {
509
548
  issues: allIssues,
510
549
  notes: allNotes,
511
550
  passes: allPasses,
551
+ criteria_results: criteriaResults,
512
552
  requirements: {
513
553
  required_files: requirements.required_files.length,
514
554
  acceptance_criteria: requirements.acceptance_criteria.length,