@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,344 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson briefing:approve — Mark a draft briefing as approved
5
+ * aioson briefing:unapprove — Return approved briefing(s) to draft
6
+ *
7
+ * Usage:
8
+ * aioson briefing:approve .
9
+ * aioson briefing:approve . --slug=cypher-agent
10
+ * aioson briefing:unapprove .
11
+ * aioson briefing:unapprove . --slug=cypher-agent
12
+ *
13
+ * Config file: .aioson/briefings/config.md
14
+ * Format: YAML frontmatter (briefings: array) + Markdown table
15
+ */
16
+
17
+ const fs = require('node:fs/promises');
18
+ const path = require('node:path');
19
+ const readline = require('node:readline');
20
+
21
+ // ─── Config path ──────────────────────────────────────────────────────────────
22
+
23
+ function configPath(projectDir) {
24
+ return path.join(projectDir, '.aioson', 'briefings', 'config.md');
25
+ }
26
+
27
+ // ─── YAML frontmatter parser (briefings-specific) ────────────────────────────
28
+
29
+ /**
30
+ * Parse .aioson/briefings/config.md frontmatter.
31
+ * Returns { updated_at, briefings: [...] }
32
+ *
33
+ * Expected format:
34
+ * ---
35
+ * updated_at: 2026-04-10
36
+ * briefings:
37
+ * - slug: foo
38
+ * status: draft
39
+ * source_plans: [plans/x.md]
40
+ * created_at: "2026-04-10"
41
+ * approved_at: null
42
+ * prd_generated: null
43
+ * ---
44
+ */
45
+ function parseConfigFrontmatter(content) {
46
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
47
+ if (!match) return null;
48
+
49
+ const raw = match[1];
50
+ const lines = raw.split(/\r?\n/);
51
+
52
+ const result = { updated_at: null, briefings: [] };
53
+ let inBriefings = false;
54
+ let currentItem = null;
55
+
56
+ for (const line of lines) {
57
+ if (/^updated_at:\s*(.*)$/.test(line)) {
58
+ result.updated_at = line.replace(/^updated_at:\s*/, '').trim().replace(/^["']|["']$/g, '');
59
+ continue;
60
+ }
61
+
62
+ if (/^briefings:/.test(line)) {
63
+ inBriefings = true;
64
+ continue;
65
+ }
66
+
67
+ if (!inBriefings) continue;
68
+
69
+ // New item in array
70
+ if (/^\s{2}-\s+slug:\s*(.+)/.test(line)) {
71
+ if (currentItem) result.briefings.push(currentItem);
72
+ const slug = line.replace(/^\s{2}-\s+slug:\s*/, '').trim().replace(/^["']|["']$/g, '');
73
+ currentItem = { slug, status: 'draft', source_plans: [], created_at: null, approved_at: null, prd_generated: null };
74
+ continue;
75
+ }
76
+
77
+ if (currentItem) {
78
+ const fieldMatch = line.match(/^\s{4}(\w+):\s*(.*)/);
79
+ if (!fieldMatch) continue;
80
+ const [, key, rawVal] = fieldMatch;
81
+ const val = rawVal.trim().replace(/^["']|["']$/g, '');
82
+
83
+ if (key === 'source_plans') {
84
+ // Parse inline array: [plans/x.md, plans/y.md]
85
+ const arrMatch = val.match(/^\[(.+)\]$/);
86
+ currentItem.source_plans = arrMatch
87
+ ? arrMatch[1].split(',').map((s) => s.trim().replace(/^["']|["']$/g, ''))
88
+ : val === '' ? [] : [val];
89
+ } else if (val === 'null' || val === '') {
90
+ currentItem[key] = null;
91
+ } else {
92
+ currentItem[key] = val;
93
+ }
94
+ }
95
+ }
96
+
97
+ if (currentItem) result.briefings.push(currentItem);
98
+ return result;
99
+ }
100
+
101
+ // ─── Config serializer ────────────────────────────────────────────────────────
102
+
103
+ function serializeSourcePlans(plans) {
104
+ if (!plans || plans.length === 0) return '[]';
105
+ const items = plans.map((p) => `"${p}"`).join(', ');
106
+ return `[${items}]`;
107
+ }
108
+
109
+ function serializeConfigFrontmatter(data) {
110
+ const lines = ['---', `updated_at: ${data.updated_at || new Date().toISOString().slice(0, 10)}`, 'briefings:'];
111
+
112
+ for (const b of data.briefings) {
113
+ lines.push(` - slug: ${b.slug}`);
114
+ lines.push(` status: ${b.status}`);
115
+ lines.push(` source_plans: ${serializeSourcePlans(b.source_plans)}`);
116
+ lines.push(` created_at: "${b.created_at || ''}"`);
117
+ lines.push(` approved_at: ${b.approved_at ? `"${b.approved_at}"` : 'null'}`);
118
+ lines.push(` prd_generated: ${b.prd_generated ? `"${b.prd_generated}"` : 'null'}`);
119
+ }
120
+
121
+ lines.push('---');
122
+ return lines.join('\n');
123
+ }
124
+
125
+ // ─── Markdown table builder ───────────────────────────────────────────────────
126
+
127
+ function buildMarkdownTable(briefings) {
128
+ const header = '| slug | status | source_plans | created | approved | prd |';
129
+ const sep = '|------|--------|-------------|---------|----------|-----|';
130
+ const rows = briefings.map((b) => {
131
+ const sources = (b.source_plans || []).join(', ') || '—';
132
+ return `| ${b.slug} | ${b.status} | ${sources} | ${b.created_at || '—'} | ${b.approved_at || '—'} | ${b.prd_generated || '—'} |`;
133
+ });
134
+ return [header, sep, ...rows].join('\n');
135
+ }
136
+
137
+ // ─── Config writer ────────────────────────────────────────────────────────────
138
+
139
+ async function writeConfig(configFile, data) {
140
+ const frontmatter = serializeConfigFrontmatter(data);
141
+ const table = buildMarkdownTable(data.briefings);
142
+ const body = `\n# Briefings Registry\n\n${table}\n`;
143
+ await fs.writeFile(configFile, `${frontmatter}\n${body}`, 'utf8');
144
+ }
145
+
146
+ // ─── Interactive prompt helpers ───────────────────────────────────────────────
147
+
148
+ /**
149
+ * Show a numbered list and ask user to pick one by number.
150
+ * Returns the 0-based index of the selected item, or -1 on cancel.
151
+ */
152
+ function promptSelect(items, promptText) {
153
+ return new Promise((resolve) => {
154
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
155
+
156
+ process.stdout.write('\n');
157
+ items.forEach((item, i) => {
158
+ process.stdout.write(` ${i + 1}. ${item}\n`);
159
+ });
160
+ process.stdout.write('\n');
161
+
162
+ rl.question(`${promptText} `, (answer) => {
163
+ rl.close();
164
+ const num = parseInt(answer.trim(), 10);
165
+ if (!answer.trim() || isNaN(num) || num < 1 || num > items.length) {
166
+ resolve(-1);
167
+ } else {
168
+ resolve(num - 1);
169
+ }
170
+ });
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Show a numbered list (all selected by default) and ask user to type
176
+ * comma-separated numbers to DESELECT. Returns indices to deselect.
177
+ */
178
+ function promptCheckboxDeselect(items, promptText) {
179
+ return new Promise((resolve) => {
180
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
181
+
182
+ process.stdout.write('\n');
183
+ items.forEach((item, i) => {
184
+ process.stdout.write(` [${i + 1}] ${item}\n`);
185
+ });
186
+ process.stdout.write('\n');
187
+
188
+ rl.question(`${promptText} `, (answer) => {
189
+ rl.close();
190
+ if (!answer.trim()) {
191
+ resolve([]);
192
+ return;
193
+ }
194
+ const indices = answer
195
+ .split(',')
196
+ .map((s) => parseInt(s.trim(), 10) - 1)
197
+ .filter((n) => !isNaN(n) && n >= 0 && n < items.length);
198
+ resolve(indices);
199
+ });
200
+ });
201
+ }
202
+
203
+ // ─── briefing:approve ─────────────────────────────────────────────────────────
204
+
205
+ async function runBriefingApprove({ args, options = {}, logger }) {
206
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
207
+ const slugOpt = String(options.slug || '').trim() || null;
208
+ const configFile = configPath(projectDir);
209
+
210
+ // ── Read config ────────────────────────────────────────────────────────────
211
+ let raw;
212
+ try {
213
+ raw = await fs.readFile(configFile, 'utf8');
214
+ } catch {
215
+ logger.error('Nenhum briefing encontrado. Ative @cypher para criar o primeiro briefing.');
216
+ return { ok: false, error: 'no_config' };
217
+ }
218
+
219
+ const data = parseConfigFrontmatter(raw);
220
+ if (!data) {
221
+ logger.error('config.md com frontmatter inválido. Verifique o arquivo manualmente.');
222
+ return { ok: false, error: 'invalid_frontmatter' };
223
+ }
224
+
225
+ const drafts = data.briefings.filter((b) => b.status === 'draft');
226
+
227
+ if (drafts.length === 0) {
228
+ logger.log('Nenhum briefing aguardando aprovação.');
229
+ return { ok: true, approved: null };
230
+ }
231
+
232
+ // ── Select briefing ────────────────────────────────────────────────────────
233
+ let target;
234
+
235
+ if (slugOpt) {
236
+ target = drafts.find((b) => b.slug === slugOpt);
237
+ if (!target) {
238
+ logger.error(`Briefing "${slugOpt}" não encontrado ou não está em status draft.`);
239
+ logger.log(`Briefings draft disponíveis: ${drafts.map((b) => b.slug).join(', ')}`);
240
+ return { ok: false, error: 'slug_not_found' };
241
+ }
242
+ } else {
243
+ const labels = drafts.map((b) => `${b.slug} — criado em ${b.created_at || '?'}`);
244
+ logger.log('Briefings aguardando aprovação:');
245
+ const idx = await promptSelect(labels, 'Digite o número do briefing para aprovar (Enter = cancelar):');
246
+
247
+ if (idx === -1) {
248
+ logger.log('Operação cancelada.');
249
+ return { ok: true, approved: null };
250
+ }
251
+ target = drafts[idx];
252
+ }
253
+
254
+ // ── Approve ────────────────────────────────────────────────────────────────
255
+ const today = new Date().toISOString().slice(0, 10);
256
+
257
+ const briefingEntry = data.briefings.find((b) => b.slug === target.slug);
258
+ briefingEntry.status = 'approved';
259
+ briefingEntry.approved_at = today;
260
+ data.updated_at = today;
261
+
262
+ await writeConfig(configFile, data);
263
+
264
+ logger.log(`✓ Briefing "${target.slug}" aprovado.`);
265
+ logger.log(' Ative @product para gerar o PRD — ele detectará o briefing aprovado automaticamente.');
266
+
267
+ return { ok: true, approved: target.slug };
268
+ }
269
+
270
+ // ─── briefing:unapprove ───────────────────────────────────────────────────────
271
+
272
+ async function runBriefingUnapprove({ args, options = {}, logger }) {
273
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
274
+ const slugOpt = String(options.slug || '').trim() || null;
275
+ const configFile = configPath(projectDir);
276
+
277
+ // ── Read config ────────────────────────────────────────────────────────────
278
+ let raw;
279
+ try {
280
+ raw = await fs.readFile(configFile, 'utf8');
281
+ } catch {
282
+ logger.error('Nenhum briefing encontrado. Ative @cypher para criar o primeiro briefing.');
283
+ return { ok: false, error: 'no_config' };
284
+ }
285
+
286
+ const data = parseConfigFrontmatter(raw);
287
+ if (!data) {
288
+ logger.error('config.md com frontmatter inválido. Verifique o arquivo manualmente.');
289
+ return { ok: false, error: 'invalid_frontmatter' };
290
+ }
291
+
292
+ // Only approved and non-implemented briefings can be unapproved
293
+ const approveds = data.briefings.filter((b) => b.status === 'approved');
294
+
295
+ if (approveds.length === 0) {
296
+ logger.log('Nenhum briefing aprovado disponível para retornar a draft.');
297
+ return { ok: true, unapproved: [] };
298
+ }
299
+
300
+ // ── Select briefings to unapprove ──────────────────────────────────────────
301
+ let targets;
302
+
303
+ if (slugOpt) {
304
+ const found = approveds.find((b) => b.slug === slugOpt);
305
+ if (!found) {
306
+ logger.error(`Briefing "${slugOpt}" não encontrado ou não está em status approved.`);
307
+ logger.log(`Briefings approved disponíveis: ${approveds.map((b) => b.slug).join(', ')}`);
308
+ return { ok: false, error: 'slug_not_found' };
309
+ }
310
+ targets = [found];
311
+ } else {
312
+ const labels = approveds.map((b) => `${b.slug} — aprovado em ${b.approved_at || '?'}`);
313
+ logger.log('Briefings aprovados (todos marcados). Digite os números para DESMARCAR:');
314
+ const toDeselect = await promptCheckboxDeselect(
315
+ labels,
316
+ 'Números para retornar a draft (vírgula-separados, Enter = sem mudanças):'
317
+ );
318
+
319
+ if (toDeselect.length === 0) {
320
+ logger.log('Nenhuma mudança aplicada.');
321
+ return { ok: true, unapproved: [] };
322
+ }
323
+ targets = toDeselect.map((i) => approveds[i]);
324
+ }
325
+
326
+ // ── Unapprove ──────────────────────────────────────────────────────────────
327
+ const today = new Date().toISOString().slice(0, 10);
328
+
329
+ for (const target of targets) {
330
+ const entry = data.briefings.find((b) => b.slug === target.slug);
331
+ entry.status = 'draft';
332
+ entry.approved_at = null;
333
+ }
334
+ data.updated_at = today;
335
+
336
+ await writeConfig(configFile, data);
337
+
338
+ const names = targets.map((b) => b.slug);
339
+ logger.log(`✓ ${names.length === 1 ? `Briefing "${names[0]}" retornado` : `Briefings retornados`} para draft: ${names.join(', ')}`);
340
+
341
+ return { ok: true, unapproved: names };
342
+ }
343
+
344
+ module.exports = { runBriefingApprove, runBriefingUnapprove };