@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,416 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson compress:agents — Compress agent instruction files to reduce token usage
5
+ *
6
+ * Usage:
7
+ * aioson compress:agents . # compress all agents (structural)
8
+ * aioson compress:agents . --agent=dev # compress specific agent
9
+ * aioson compress:agents . --agent=dev,analyst # compress multiple agents
10
+ * aioson compress:agents . --rules # also compress .aioson/rules/
11
+ * aioson compress:agents . --dry-run # preview savings without writing
12
+ * aioson compress:agents . --llm # LLM-assisted (needs ANTHROPIC_API_KEY)
13
+ * aioson compress:agents . --llm --model=haiku # choose model: haiku | sonnet | opus
14
+ * aioson compress:agents . --restore # restore from .original.md backups
15
+ * aioson compress:agents . --stats # show stats only (no changes)
16
+ */
17
+
18
+ const fs = require('node:fs/promises');
19
+ const path = require('node:path');
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // Structural compression — no LLM required
23
+ // ---------------------------------------------------------------------------
24
+
25
+ // Section headers that are purely explanatory with no actionable content.
26
+ // Their rules are already implied by the surrounding content.
27
+ const REMOVABLE_SECTION_HEADERS = [
28
+ 'por que isso importa',
29
+ 'why this matters',
30
+ 'why this is important',
31
+ 'por que isso é importante',
32
+ 'por que isso é relevante',
33
+ ];
34
+
35
+ // Filler phrase prefixes to strip from the start of prose lines
36
+ const FILLER_PREFIXES = [
37
+ /^É importante (notar|ressaltar|observar|destacar) que\s*/i,
38
+ /^Vale (ressaltar|notar|destacar|observar) que\s*/i,
39
+ /^Deve-se (observar|notar|ressaltar) que\s*/i,
40
+ /^Cabe (notar|ressaltar|observar) que\s*/i,
41
+ /^It is important to (note|remember|understand) that\s*/i,
42
+ /^Note that\s*/i,
43
+ /^Please note that\s*/i,
44
+ /^Keep in mind that\s*/i,
45
+ /^As mentioned (earlier|above|before|previously)?,?\s*/i,
46
+ /^Observe que\s*/i,
47
+ /^Ressaltamos que\s*/i,
48
+ /^Destacamos que\s*/i,
49
+ ];
50
+
51
+ // Trailing qualifiers that add no information — strip to end of sentence
52
+ const FILLER_TRAILERS = [
53
+ / — o que (garante|assegura|permite|significa|implica)[^.]*\./g,
54
+ / — isso (é|se torna|se tornou) (fundamental|importante|necessário|crítico) porque[^.]*\./g,
55
+ /, o que (é|se torna) (esperado|natural|correto)\./g,
56
+ / como mencionado anteriormente/g,
57
+ / como dito anteriormente/g,
58
+ / as (previously|already) mentioned/g,
59
+ ];
60
+
61
+ /**
62
+ * Split markdown into an array of sections.
63
+ * Each section: { header: string|null, level: number|null, body: string }
64
+ * Respects fenced code blocks — headings inside code blocks are not treated as section boundaries.
65
+ */
66
+ function splitSections(text) {
67
+ const sections = [];
68
+ const lines = text.split('\n');
69
+ let currentHeader = null;
70
+ let currentLevel = null;
71
+ let currentBody = [];
72
+ let inCodeBlock = false;
73
+ let frontmatterDone = false;
74
+ let frontmatterLines = [];
75
+ let inFrontmatter = false;
76
+
77
+ // Handle YAML frontmatter at the very top
78
+ if (lines[0] === '---') {
79
+ inFrontmatter = true;
80
+ frontmatterLines.push(lines[0]);
81
+ for (let i = 1; i < lines.length; i++) {
82
+ frontmatterLines.push(lines[i]);
83
+ if (lines[i] === '---') {
84
+ frontmatterDone = true;
85
+ // Emit as a special section with no header
86
+ sections.push({ header: null, level: null, body: frontmatterLines.join('\n') + '\n' });
87
+ frontmatterLines = [];
88
+ inFrontmatter = false;
89
+ // Process remaining lines normally
90
+ const remaining = lines.slice(i + 1);
91
+ return [...sections, ...splitSections(remaining.join('\n'))];
92
+ }
93
+ }
94
+ if (inFrontmatter) {
95
+ // Malformed frontmatter — treat as body
96
+ return [{ header: null, level: null, body: text }];
97
+ }
98
+ }
99
+
100
+ for (const line of lines) {
101
+ if (line.startsWith('```')) {
102
+ inCodeBlock = !inCodeBlock;
103
+ currentBody.push(line);
104
+ continue;
105
+ }
106
+
107
+ if (!inCodeBlock) {
108
+ const headingMatch = line.match(/^(#{1,3}) (.+)$/);
109
+ if (headingMatch) {
110
+ sections.push({ header: currentHeader, level: currentLevel, body: currentBody.join('\n') });
111
+ currentHeader = line;
112
+ currentLevel = headingMatch[1].length;
113
+ currentBody = [];
114
+ continue;
115
+ }
116
+ }
117
+
118
+ currentBody.push(line);
119
+ }
120
+
121
+ sections.push({ header: currentHeader, level: currentLevel, body: currentBody.join('\n') });
122
+ return sections;
123
+ }
124
+
125
+ function shouldRemoveSection(header) {
126
+ if (!header) return false;
127
+ const normalized = header.replace(/^#+\s*/, '').toLowerCase().trim();
128
+ return REMOVABLE_SECTION_HEADERS.some(h => normalized === h);
129
+ }
130
+
131
+ function compressBody(body) {
132
+ let inCodeBlock = false;
133
+ const lines = body.split('\n').map(line => {
134
+ if (line.startsWith('```')) {
135
+ inCodeBlock = !inCodeBlock;
136
+ return line;
137
+ }
138
+ if (inCodeBlock) return line;
139
+
140
+ // Skip: headers, table rows, list items, blockquotes, empty lines
141
+ if (
142
+ line.startsWith('#') || line.startsWith('|') || line.startsWith('>') ||
143
+ line.startsWith('- ') || line.startsWith('* ') || line.startsWith(' - ') ||
144
+ line.startsWith(' * ') || line.trim() === ''
145
+ ) return line;
146
+
147
+ let out = line;
148
+
149
+ for (const pattern of FILLER_PREFIXES) {
150
+ const replaced = out.replace(pattern, '');
151
+ if (replaced !== out) {
152
+ out = replaced.charAt(0).toUpperCase() + replaced.slice(1);
153
+ break;
154
+ }
155
+ }
156
+
157
+ for (const pattern of FILLER_TRAILERS) {
158
+ out = out.replace(pattern, (m) => '.');
159
+ }
160
+
161
+ return out;
162
+ });
163
+
164
+ return lines.join('\n');
165
+ }
166
+
167
+ function compressStructural(text) {
168
+ const sections = splitSections(text);
169
+ const kept = sections.filter(s => !shouldRemoveSection(s.header));
170
+
171
+ const parts = kept.map(({ header, body }) => {
172
+ const h = header ? header + '\n' : '';
173
+ return h + compressBody(body);
174
+ });
175
+
176
+ return parts.join('').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
177
+ }
178
+
179
+ // ---------------------------------------------------------------------------
180
+ // LLM compression — calls Anthropic Messages API via fetch
181
+ // ---------------------------------------------------------------------------
182
+
183
+ const MODEL_MAP = {
184
+ haiku: 'claude-haiku-4-5-20251001',
185
+ sonnet: 'claude-sonnet-4-6',
186
+ opus: 'claude-opus-4-6',
187
+ };
188
+
189
+ const LLM_SYSTEM = `You are a markdown compression expert specializing in AI agent instruction files.
190
+
191
+ Compress the file the user sends. Goal: smallest possible file that preserves 100% of the technical meaning.
192
+
193
+ ALWAYS PRESERVE — never touch these:
194
+ - YAML frontmatter (--- blocks)
195
+ - All fenced code blocks (\`\`\` ... \`\`\`)
196
+ - All markdown tables (| ... |)
197
+ - File paths, URLs, bash commands, CLI flags
198
+ - Every rule, constraint, and actionable instruction
199
+ - Section headers that introduce actionable content
200
+
201
+ REMOVE OR COMPRESS:
202
+ - Sections titled "Por que isso importa" / "Why this matters" / "Rationale" — only if the rule already makes the reason obvious
203
+ - Preamble paragraphs that just restate what the section header says
204
+ - Filler phrase openers: "É importante notar que", "Vale ressaltar que", "It is important to note that", "Note that", "Keep in mind that", etc.
205
+ - Multi-paragraph explanations reducible to 1 dense sentence
206
+ - Trailing qualifiers that add no information
207
+
208
+ OUTPUT: Only the compressed markdown. No preamble, no commentary, no explanation.`;
209
+
210
+ async function compressWithLLM(text, apiKey, model) {
211
+ const resp = await fetch('https://api.anthropic.com/v1/messages', {
212
+ method: 'POST',
213
+ headers: {
214
+ 'Content-Type': 'application/json',
215
+ 'x-api-key': apiKey,
216
+ 'anthropic-version': '2023-06-01',
217
+ },
218
+ body: JSON.stringify({
219
+ model,
220
+ max_tokens: 8192,
221
+ system: LLM_SYSTEM,
222
+ messages: [{ role: 'user', content: text }],
223
+ }),
224
+ });
225
+
226
+ if (!resp.ok) {
227
+ const body = await resp.text().catch(() => '');
228
+ throw new Error(`API ${resp.status}: ${body.slice(0, 200)}`);
229
+ }
230
+
231
+ const data = await resp.json();
232
+ return data.content[0].text;
233
+ }
234
+
235
+ // ---------------------------------------------------------------------------
236
+ // Restore from backups
237
+ // ---------------------------------------------------------------------------
238
+
239
+ async function runRestore(dir, agentFilter, logger) {
240
+ const files = (await fs.readdir(dir)).filter(f => f.endsWith('.original.md'));
241
+ const targets = agentFilter
242
+ ? files.filter(f => agentFilter.some(a => f === `${a}.original.md`))
243
+ : files;
244
+
245
+ if (targets.length === 0) {
246
+ logger.log('No .original.md backup files found.');
247
+ return { ok: true, restored: 0 };
248
+ }
249
+
250
+ for (const file of targets) {
251
+ const src = path.join(dir, file);
252
+ const dest = path.join(dir, file.replace('.original.md', '.md'));
253
+ await fs.copyFile(src, dest);
254
+ await fs.unlink(src);
255
+ logger.log(` Restored: ${file.replace('.original.md', '.md')}`);
256
+ }
257
+
258
+ logger.log(`\nRestored ${targets.length} file(s). Backup files removed.`);
259
+ return { ok: true, restored: targets.length };
260
+ }
261
+
262
+ // ---------------------------------------------------------------------------
263
+ // Compress a single directory of .md files
264
+ // ---------------------------------------------------------------------------
265
+
266
+ async function compressDir(dir, { agentFilter, dryRun, useLLM, apiKey, model, logger }) {
267
+ let files;
268
+ try {
269
+ files = (await fs.readdir(dir)).filter(f => f.endsWith('.md') && !f.endsWith('.original.md'));
270
+ } catch {
271
+ return [];
272
+ }
273
+
274
+ const targets = agentFilter
275
+ ? files.filter(f => agentFilter.some(a => f === `${a}.md`))
276
+ : files;
277
+
278
+ const results = [];
279
+
280
+ for (const file of targets) {
281
+ const filePath = path.join(dir, file);
282
+ const backupPath = path.join(dir, file.replace('.md', '.original.md'));
283
+
284
+ const original = await fs.readFile(filePath, 'utf8');
285
+ const originalSize = Buffer.byteLength(original, 'utf8');
286
+
287
+ let compressed;
288
+ try {
289
+ compressed = useLLM
290
+ ? await compressWithLLM(original, apiKey, model)
291
+ : compressStructural(original);
292
+ } catch (err) {
293
+ logger.error(` ✗ ${file}: ${err.message}`);
294
+ results.push({ file, ok: false, error: err.message });
295
+ continue;
296
+ }
297
+
298
+ const compressedSize = Buffer.byteLength(compressed, 'utf8');
299
+ const saved = originalSize - compressedSize;
300
+ const pct = Math.round((saved / originalSize) * 100);
301
+
302
+ if (pct < 2) {
303
+ logger.log(` · ${file}: ${(originalSize / 1024).toFixed(1)}KB — already compact, skipped`);
304
+ results.push({ file, ok: true, skipped: true, originalSize });
305
+ continue;
306
+ }
307
+
308
+ if (dryRun) {
309
+ logger.log(` ~ ${file}: ${(originalSize / 1024).toFixed(1)}KB → ${(compressedSize / 1024).toFixed(1)}KB (−${pct}%)`);
310
+ } else {
311
+ // Write backup only if none exists
312
+ let backedUp = false;
313
+ try {
314
+ await fs.access(backupPath);
315
+ } catch {
316
+ await fs.writeFile(backupPath, original, 'utf8');
317
+ backedUp = true;
318
+ }
319
+
320
+ await fs.writeFile(filePath, compressed, 'utf8');
321
+ const tag = backedUp ? ' ← backup saved' : '';
322
+ logger.log(` ✓ ${file}: ${(originalSize / 1024).toFixed(1)}KB → ${(compressedSize / 1024).toFixed(1)}KB (−${pct}%)${tag}`);
323
+ }
324
+
325
+ results.push({ file, ok: true, skipped: false, originalSize, compressedSize, saved, pct });
326
+ }
327
+
328
+ return results;
329
+ }
330
+
331
+ // ---------------------------------------------------------------------------
332
+ // Main entry point
333
+ // ---------------------------------------------------------------------------
334
+
335
+ async function runCompressAgents({ args, options = {}, logger }) {
336
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
337
+ const agentsDir = path.join(targetDir, '.aioson', 'agents');
338
+ const rulesDir = path.join(targetDir, '.aioson', 'rules');
339
+
340
+ const dryRun = Boolean(options['dry-run'] || options.dry);
341
+ const useLLM = Boolean(options.llm);
342
+ const doRestore = Boolean(options.restore);
343
+ const alsoRules = Boolean(options.rules);
344
+ const statsOnly = Boolean(options.stats);
345
+ const agentFilter = options.agent
346
+ ? String(options.agent).split(',').map(a => a.trim()).filter(Boolean)
347
+ : null;
348
+
349
+ // Resolve model alias → full model ID
350
+ const modelAlias = String(options.model || 'haiku').toLowerCase();
351
+ const model = MODEL_MAP[modelAlias] || modelAlias;
352
+
353
+ // --- RESTORE MODE ---
354
+ if (doRestore) {
355
+ try { await fs.access(agentsDir); } catch {
356
+ logger.error(`No .aioson/agents/ directory found in ${targetDir}`);
357
+ return { ok: false, error: 'no_agents_dir' };
358
+ }
359
+ return runRestore(agentsDir, agentFilter, logger);
360
+ }
361
+
362
+ // --- VALIDATE ---
363
+ try {
364
+ await fs.access(agentsDir);
365
+ } catch {
366
+ logger.error(`No .aioson/agents/ directory found in ${targetDir}`);
367
+ return { ok: false, error: 'no_agents_dir' };
368
+ }
369
+
370
+ let apiKey = null;
371
+ if (useLLM) {
372
+ apiKey = process.env.ANTHROPIC_API_KEY;
373
+ if (!apiKey) {
374
+ logger.error('--llm requires ANTHROPIC_API_KEY to be set');
375
+ return { ok: false, error: 'missing_api_key' };
376
+ }
377
+ }
378
+
379
+ // --- COMPRESS ---
380
+ const mode = useLLM ? `LLM (${model})` : 'structural';
381
+ const action = dryRun ? 'Preview' : 'Compress';
382
+ logger.log(`${action} — mode: ${mode}`);
383
+ logger.log('');
384
+
385
+ const sharedOpts = { agentFilter, dryRun: dryRun || statsOnly, useLLM, apiKey, model, logger };
386
+
387
+ logger.log('Agents:');
388
+ const agentResults = await compressDir(agentsDir, sharedOpts);
389
+
390
+ let ruleResults = [];
391
+ if (alsoRules) {
392
+ logger.log('\nRules:');
393
+ ruleResults = await compressDir(rulesDir, { ...sharedOpts, agentFilter: null });
394
+ }
395
+
396
+ const allResults = [...agentResults, ...ruleResults];
397
+ const compressed = allResults.filter(r => r.ok && !r.skipped);
398
+ const totalSaved = compressed.reduce((sum, r) => sum + (r.saved || 0), 0);
399
+ const errors = allResults.filter(r => !r.ok);
400
+
401
+ logger.log('');
402
+ logger.log(`─────────────────────────────────────`);
403
+ logger.log(`Files processed : ${allResults.length}`);
404
+ logger.log(`Compressed : ${compressed.length}`);
405
+ if (errors.length) logger.log(`Errors : ${errors.length}`);
406
+ logger.log(`Total saved : ${(totalSaved / 1024).toFixed(1)} KB`);
407
+ if (!dryRun && !statsOnly && compressed.length > 0) {
408
+ logger.log('');
409
+ logger.log('Backups: <agent>.original.md');
410
+ logger.log('Restore: aioson compress:agents . --restore');
411
+ }
412
+
413
+ return { ok: true, results: allResults, totalSaved };
414
+ }
415
+
416
+ module.exports = { runCompressAgents };
@@ -93,7 +93,9 @@ async function runContextHealth({ args, options = {}, logger }) {
93
93
  return doneFeatures.has(slug);
94
94
  });
95
95
 
96
- const { db, dbPath } = await openRuntimeDb(targetDir, { mustExist: true }).catch(() => ({ db: null, dbPath: null }));
96
+ const dbResult = await openRuntimeDb(targetDir, { mustExist: true }).catch(() => ({ db: null, dbPath: null }));
97
+ const db = dbResult ? dbResult.db : null;
98
+ const dbPath = dbResult ? dbResult.dbPath : null;
97
99
  const cacheHitRate = await getCacheHitRate(db);
98
100
  if (db) db.close();
99
101
 
@@ -150,7 +152,7 @@ async function runContextHealth({ args, options = {}, logger }) {
150
152
  const slug = s.file.replace(/^spec-/, '').replace(/\.md$/, '');
151
153
  logger.log(` → ${s.file} (feature: ${slug} is done)`);
152
154
  }
153
- logger.log(` Run: aioson context:trim . to archive them`);
155
+ logger.log(` Run: aioson feature:archive . --feature=<slug> to archive them`);
154
156
  logger.log('');
155
157
  }
156
158
 
@@ -104,12 +104,27 @@ async function runContextTrim({ args, options = {}, logger }) {
104
104
 
105
105
  const totalStaleSaved = staleSpecs.reduce((s, r) => s + r.sizeBytes, 0);
106
106
 
107
+ // Archive stale specs (executed before any return, including JSON)
108
+ let archivedCount = 0;
109
+ if (staleSpecs.length > 0 && (force || dryRun)) {
110
+ if (!dryRun) {
111
+ await fs.mkdir(archiveDir, { recursive: true });
112
+ for (const s of staleSpecs) {
113
+ const src = path.join(contextDir, s.file);
114
+ const dest = path.join(archiveDir, s.file);
115
+ await fs.rename(src, dest);
116
+ }
117
+ archivedCount = staleSpecs.length;
118
+ }
119
+ }
120
+
107
121
  if (options.json) {
108
122
  return {
109
123
  ok: true,
110
124
  staleSpecs,
111
125
  largeSections,
112
126
  totalStaleSavedBytes: totalStaleSaved,
127
+ archived: archivedCount,
113
128
  dryRun
114
129
  };
115
130
  }
@@ -120,7 +135,7 @@ async function runContextTrim({ args, options = {}, logger }) {
120
135
  if (staleSpecs.length === 0 && largeSections.length === 0) {
121
136
  logger.log('✓ No stale specs or oversized sections found.');
122
137
  logger.log('');
123
- return { ok: true, staleSpecs: [], largeSections: [], totalStaleSavedBytes: 0, dryRun };
138
+ return { ok: true, staleSpecs: [], largeSections: [], totalStaleSavedBytes: 0, archived: 0, dryRun };
124
139
  }
125
140
 
126
141
  if (staleSpecs.length > 0) {
@@ -143,18 +158,9 @@ async function runContextTrim({ args, options = {}, logger }) {
143
158
  logger.log('');
144
159
  }
145
160
 
146
- // Archive stale specs
147
161
  if (staleSpecs.length > 0) {
148
162
  if (force || dryRun) {
149
163
  if (!dryRun) {
150
- await fs.mkdir(archiveDir, { recursive: true });
151
- for (const s of staleSpecs) {
152
- const src = path.join(contextDir, s.file);
153
- const dest = path.join(archiveDir, s.file);
154
- await fs.rename(src, dest);
155
- logger.log(` Archived: ${s.file} → context/archive/${s.file}`);
156
- }
157
- logger.log('');
158
164
  logger.log(`${staleSpecs.length} spec(s) archived to .aioson/context/archive/`);
159
165
  } else {
160
166
  logger.log(`[dry-run] Would archive ${staleSpecs.length} stale spec(s) to .aioson/context/archive/`);
@@ -169,7 +175,7 @@ async function runContextTrim({ args, options = {}, logger }) {
169
175
  staleSpecs,
170
176
  largeSections,
171
177
  totalStaleSavedBytes: totalStaleSaved,
172
- archived: force && !dryRun ? staleSpecs.length : 0,
178
+ archived: archivedCount,
173
179
  dryRun
174
180
  };
175
181
  }
@@ -3,7 +3,7 @@
3
3
  const fs = require('node:fs/promises');
4
4
  const path = require('node:path');
5
5
  const readline = require('node:readline');
6
- const { validateProjectContextFile } = require('../context');
6
+ const { validateProjectContextFile, getInteractionLanguage } = require('../context');
7
7
  const { resolveAgentLocale } = require('../locales');
8
8
  const { ensureDir } = require('../utils');
9
9
  const {
@@ -17,9 +17,9 @@ function resolveTargetDir(args) {
17
17
 
18
18
  async function detectProjectLocale(targetDir) {
19
19
  const context = await validateProjectContextFile(targetDir);
20
- if (context.parsed && context.data && context.data.conversation_language) {
20
+ if (context.parsed && context.data) {
21
21
  return {
22
- locale: resolveAgentLocale(context.data.conversation_language),
22
+ locale: resolveAgentLocale(getInteractionLanguage(context.data, 'en')),
23
23
  source: 'project-context'
24
24
  };
25
25
  }
@@ -27,10 +27,11 @@ function parseFrontmatter(content) {
27
27
  }
28
28
 
29
29
  function extractSection(content, sectionName) {
30
- const re = new RegExp(`^#{1,4}\\s+${sectionName}[\\s\\S]*?(?=^#{1,4}\\s|\\Z)`, 'im');
30
+ const escapedSection = String(sectionName).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
31
+ const re = new RegExp(`(?:^|\\r?\\n)#{1,4}\\s+${escapedSection}[^\\n]*\\r?\\n([\\s\\S]*?)(?=\\r?\\n#{1,4}\\s+|$)`, 'i');
31
32
  const match = content.match(re);
32
33
  if (!match) return '';
33
- return match[0].replace(/^#{1,4}\s+\S[^\n]*\n/, '').trim();
34
+ return match[1].trim();
34
35
  }
35
36
 
36
37
  function extractListItems(content, sectionName) {
@@ -186,14 +187,15 @@ async function processDevlogFile(db, filePath) {
186
187
  }
187
188
 
188
189
  // Close run
189
- updateRun(db, runKey, {
190
+ updateRun(db, {
191
+ runKey,
190
192
  status,
191
193
  summary,
192
194
  finishedAt
193
195
  });
194
196
 
195
197
  if (status === 'completed') {
196
- updateTask(db, taskKey, { status: 'completed', finishedAt });
198
+ updateTask(db, { taskKey, status: 'completed', finishedAt });
197
199
  }
198
200
 
199
201
  // Mark devlog as processed