@jaimevalasek/aioson 1.5.1 → 1.7.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 (341) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +729 -226
  3. package/docs/design-previews/aurora-command-ui-website.html +884 -0
  4. package/docs/design-previews/aurora-command-ui.html +682 -0
  5. package/docs/design-previews/bold-editorial-ui-website.html +658 -0
  6. package/docs/design-previews/bold-editorial-ui.html +717 -0
  7. package/docs/design-previews/clean-saas-ui-website.html +1202 -0
  8. package/docs/design-previews/clean-saas-ui.html +549 -0
  9. package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
  10. package/docs/design-previews/cognitive-core-ui.html +463 -0
  11. package/docs/design-previews/glassmorphism-ui-website.html +572 -0
  12. package/docs/design-previews/glassmorphism-ui.html +886 -0
  13. package/docs/design-previews/index.html +699 -0
  14. package/docs/design-previews/interface-design-website.html +1187 -0
  15. package/docs/design-previews/interface-design.html +513 -0
  16. package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
  17. package/docs/design-previews/neo-brutalist-ui.html +797 -0
  18. package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
  19. package/docs/design-previews/premium-command-center-ui.html +552 -0
  20. package/docs/design-previews/pt.squarespace.com-homepage.html +889 -0
  21. package/docs/design-previews/warm-craft-ui-website.html +684 -0
  22. package/docs/design-previews/warm-craft-ui.html +739 -0
  23. package/docs/en/cli-reference.md +20 -9
  24. package/docs/integrations/sdlc-genius-boundary.md +76 -0
  25. package/docs/integrations/sdlc-genius-eval-matrix.md +75 -0
  26. package/docs/integrations/sdlc-genius-install-checklist.md +93 -0
  27. package/docs/integrations/sdlc-genius-review-samples.md +86 -0
  28. package/docs/pt/README.md +10 -0
  29. package/docs/pt/agent-sharding.md +132 -0
  30. package/docs/pt/agentes.md +9 -2
  31. package/docs/pt/busca-de-contexto.md +129 -0
  32. package/docs/pt/cache-de-contexto.md +156 -0
  33. package/docs/pt/comandos-cli.md +915 -1
  34. package/docs/pt/design-hybrid-forge.md +356 -0
  35. package/docs/pt/devlog-pipeline.md +270 -0
  36. package/docs/pt/fluxo-artefatos.md +178 -0
  37. package/docs/pt/hooks-session-guard.md +454 -0
  38. package/docs/pt/inicio-rapido.md +54 -3
  39. package/docs/pt/inteligencia-adaptativa.md +324 -0
  40. package/docs/pt/monitor-de-contexto.md +158 -0
  41. package/docs/pt/recuperacao-de-sessao.md +125 -0
  42. package/docs/pt/sandbox.md +125 -0
  43. package/docs/pt/sdd-automation-scripts.md +557 -0
  44. package/docs/pt/site-forge.md +309 -0
  45. package/docs/pt/skills.md +98 -6
  46. package/docs/pt/spec-learnings-pipeline.md +265 -0
  47. package/package.json +1 -1
  48. package/src/a2a/client.js +165 -0
  49. package/src/a2a/server.js +223 -0
  50. package/src/agent-loader.js +280 -0
  51. package/src/cli.js +329 -1
  52. package/src/commands/agent-audit.js +397 -0
  53. package/src/commands/agent-export-skill.js +229 -0
  54. package/src/commands/agent-loader.js +85 -0
  55. package/src/commands/artifact-validate.js +189 -0
  56. package/src/commands/brief-gen.js +405 -0
  57. package/src/commands/brief-validate.js +65 -0
  58. package/src/commands/classify.js +256 -0
  59. package/src/commands/context-cache.js +90 -0
  60. package/src/commands/context-compact.js +49 -0
  61. package/src/commands/context-health.js +175 -0
  62. package/src/commands/context-monitor.js +163 -0
  63. package/src/commands/context-search.js +66 -0
  64. package/src/commands/context-trim.js +177 -0
  65. package/src/commands/design-hybrid-options.js +385 -0
  66. package/src/commands/detect-test-runner.js +55 -0
  67. package/src/commands/devlog-export-brains.js +27 -0
  68. package/src/commands/devlog-process.js +292 -0
  69. package/src/commands/devlog-watch.js +131 -0
  70. package/src/commands/feature-close.js +165 -0
  71. package/src/commands/gate-check.js +228 -0
  72. package/src/commands/health.js +214 -0
  73. package/src/commands/hooks-emit.js +253 -0
  74. package/src/commands/hooks-install.js +347 -0
  75. package/src/commands/init.js +54 -13
  76. package/src/commands/install.js +52 -13
  77. package/src/commands/learning-auto-promote.js +195 -0
  78. package/src/commands/learning-evolve.js +364 -0
  79. package/src/commands/learning-export.js +103 -0
  80. package/src/commands/learning-rollback.js +164 -0
  81. package/src/commands/live.js +59 -1
  82. package/src/commands/pattern-detect.js +33 -0
  83. package/src/commands/preflight-context.js +30 -0
  84. package/src/commands/preflight.js +208 -0
  85. package/src/commands/pulse-update.js +130 -0
  86. package/src/commands/recovery.js +43 -0
  87. package/src/commands/runner-daemon.js +274 -0
  88. package/src/commands/runner-plan.js +70 -0
  89. package/src/commands/runner-queue-from-plan.js +166 -0
  90. package/src/commands/runner-queue.js +189 -0
  91. package/src/commands/runner-run.js +129 -0
  92. package/src/commands/runtime.js +47 -1
  93. package/src/commands/sandbox.js +37 -0
  94. package/src/commands/self-implement-loop.js +256 -0
  95. package/src/commands/session-guard.js +218 -0
  96. package/src/commands/setup-context.js +22 -2
  97. package/src/commands/setup.js +178 -0
  98. package/src/commands/sizing.js +165 -0
  99. package/src/commands/skill.js +144 -32
  100. package/src/commands/spec-checkpoint.js +177 -0
  101. package/src/commands/spec-status.js +79 -0
  102. package/src/commands/spec-sync.js +190 -0
  103. package/src/commands/spec-tasks.js +288 -0
  104. package/src/commands/squad-autorun.js +1220 -0
  105. package/src/commands/squad-bus.js +217 -0
  106. package/src/commands/squad-card.js +149 -0
  107. package/src/commands/squad-daemon.js +134 -0
  108. package/src/commands/squad-dependency-graph.js +164 -0
  109. package/src/commands/squad-review.js +106 -0
  110. package/src/commands/squad-scaffold.js +55 -0
  111. package/src/commands/squad-tool-register.js +157 -0
  112. package/src/commands/state-save.js +122 -0
  113. package/src/commands/tool-registry-cmd.js +232 -0
  114. package/src/commands/update.js +9 -0
  115. package/src/commands/verify-gate.js +572 -0
  116. package/src/commands/workflow-execute.js +241 -0
  117. package/src/constants.js +18 -0
  118. package/src/context-cache.js +159 -0
  119. package/src/context-search.js +326 -0
  120. package/src/design-variation-catalog.js +503 -0
  121. package/src/i18n/messages/en.js +32 -2
  122. package/src/i18n/messages/es.js +30 -2
  123. package/src/i18n/messages/fr.js +30 -2
  124. package/src/i18n/messages/pt-BR.js +32 -2
  125. package/src/install-animation.js +260 -0
  126. package/src/install-profile.js +143 -0
  127. package/src/install-wizard.js +475 -0
  128. package/src/installer.js +44 -10
  129. package/src/lib/health-check.js +158 -0
  130. package/src/lib/hook-protocol.js +76 -0
  131. package/src/mcp/apps/squad-dashboard/app.js +163 -0
  132. package/src/mcp/apps/squad-dashboard/index.html +261 -0
  133. package/src/mcp/apps/squad-dashboard/mcp-manifest.json +23 -0
  134. package/src/mcp/resources/squad-state.js +130 -0
  135. package/src/parser.js +7 -1
  136. package/src/preflight-engine.js +443 -0
  137. package/src/recovery-context-session.js +154 -0
  138. package/src/runner/cascade.js +97 -0
  139. package/src/runner/cli-launcher.js +109 -0
  140. package/src/runner/plan-importer.js +63 -0
  141. package/src/runner/queue-store.js +159 -0
  142. package/src/runtime-store.js +158 -4
  143. package/src/sandbox.js +177 -0
  144. package/src/squad/agent-teams-adapter.js +264 -0
  145. package/src/squad/brief-validator.js +350 -0
  146. package/src/squad/bus-bridge.js +140 -0
  147. package/src/squad/context-compactor.js +265 -0
  148. package/src/squad/cross-ai-synthesizer.js +250 -0
  149. package/src/squad/hooks-generator.js +196 -0
  150. package/src/squad/inter-squad-events.js +175 -0
  151. package/src/squad/intra-bus.js +345 -0
  152. package/src/squad/learning-extractor.js +213 -0
  153. package/src/squad/pattern-detector.js +365 -0
  154. package/src/squad/preflight-context.js +296 -0
  155. package/src/squad/recovery-context.js +242 -71
  156. package/src/squad/reflection.js +365 -0
  157. package/src/squad/squad-scaffold.js +177 -0
  158. package/src/squad/state-manager.js +310 -0
  159. package/src/squad/task-decomposer.js +652 -0
  160. package/src/squad/verify-gate.js +303 -0
  161. package/src/tool-executor.js +94 -0
  162. package/src/updater.js +10 -3
  163. package/src/worker-runner.js +186 -1
  164. package/template/.aioson/agents/analyst.md +119 -3
  165. package/template/.aioson/agents/architect.md +98 -0
  166. package/template/.aioson/agents/design-hybrid-forge.md +141 -0
  167. package/template/.aioson/agents/dev.md +335 -14
  168. package/template/.aioson/agents/deyvin.md +117 -2
  169. package/template/.aioson/agents/discovery-design-doc.md +44 -0
  170. package/template/.aioson/agents/genome.md +14 -0
  171. package/template/.aioson/agents/neo.md +78 -1
  172. package/template/.aioson/agents/orache.md +50 -4
  173. package/template/.aioson/agents/orchestrator.md +197 -1
  174. package/template/.aioson/agents/pm.md +93 -0
  175. package/template/.aioson/agents/product.md +77 -4
  176. package/template/.aioson/agents/profiler-enricher.md +14 -0
  177. package/template/.aioson/agents/profiler-forge.md +14 -0
  178. package/template/.aioson/agents/profiler-researcher.md +14 -0
  179. package/template/.aioson/agents/qa.md +249 -19
  180. package/template/.aioson/agents/setup.md +144 -12
  181. package/template/.aioson/agents/sheldon.md +237 -11
  182. package/template/.aioson/agents/site-forge.md +1753 -0
  183. package/template/.aioson/agents/squad.md +162 -0
  184. package/template/.aioson/agents/tester.md +209 -0
  185. package/template/.aioson/agents/ux-ui.md +34 -1
  186. package/template/.aioson/brains/README.md +128 -0
  187. package/template/.aioson/brains/_index.json +16 -0
  188. package/template/.aioson/brains/scripts/query.js +103 -0
  189. package/template/.aioson/brains/site-forge/visual-patterns.brain.json +205 -0
  190. package/template/.aioson/config.md +158 -13
  191. package/template/.aioson/constitution.md +33 -0
  192. package/template/.aioson/context/forensics/.gitkeep +0 -0
  193. package/template/.aioson/context/project-pulse.md +34 -0
  194. package/template/.aioson/context/seeds/seed-example.md +27 -0
  195. package/template/.aioson/context/user-profile.md +42 -0
  196. package/template/.aioson/docs/LAYERS.md +79 -0
  197. package/template/.aioson/docs/README.md +76 -0
  198. package/template/.aioson/docs/example-external-api-context.md +72 -0
  199. package/template/.aioson/locales/en/agents/architect.md +17 -0
  200. package/template/.aioson/locales/en/agents/dev.md +79 -13
  201. package/template/.aioson/locales/en/agents/orache.md +6 -0
  202. package/template/.aioson/locales/en/agents/orchestrator.md +24 -0
  203. package/template/.aioson/locales/en/agents/product.md +50 -0
  204. package/template/.aioson/locales/en/agents/setup.md +33 -1
  205. package/template/.aioson/locales/en/agents/sheldon.md +115 -0
  206. package/template/.aioson/locales/en/agents/squad.md +14 -0
  207. package/template/.aioson/locales/en/agents/tester.md +6 -0
  208. package/template/.aioson/locales/es/agents/analyst.md +2 -0
  209. package/template/.aioson/locales/es/agents/architect.md +19 -0
  210. package/template/.aioson/locales/es/agents/dev.md +64 -4
  211. package/template/.aioson/locales/es/agents/deyvin.md +2 -0
  212. package/template/.aioson/locales/es/agents/discovery-design-doc.md +2 -0
  213. package/template/.aioson/locales/es/agents/genome.md +2 -0
  214. package/template/.aioson/locales/es/agents/neo.md +2 -0
  215. package/template/.aioson/locales/es/agents/orache.md +2 -0
  216. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  217. package/template/.aioson/locales/es/agents/pair.md +2 -0
  218. package/template/.aioson/locales/es/agents/pm.md +2 -0
  219. package/template/.aioson/locales/es/agents/product.md +52 -0
  220. package/template/.aioson/locales/es/agents/profiler-enricher.md +2 -0
  221. package/template/.aioson/locales/es/agents/profiler-forge.md +2 -0
  222. package/template/.aioson/locales/es/agents/profiler-researcher.md +2 -0
  223. package/template/.aioson/locales/es/agents/qa.md +2 -0
  224. package/template/.aioson/locales/es/agents/setup.md +35 -1
  225. package/template/.aioson/locales/es/agents/sheldon.md +117 -0
  226. package/template/.aioson/locales/es/agents/squad.md +16 -0
  227. package/template/.aioson/locales/es/agents/tester.md +9 -0
  228. package/template/.aioson/locales/es/agents/ux-ui.md +2 -0
  229. package/template/.aioson/locales/fr/agents/analyst.md +2 -0
  230. package/template/.aioson/locales/fr/agents/architect.md +19 -0
  231. package/template/.aioson/locales/fr/agents/dev.md +64 -4
  232. package/template/.aioson/locales/fr/agents/deyvin.md +2 -0
  233. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +2 -0
  234. package/template/.aioson/locales/fr/agents/genome.md +2 -0
  235. package/template/.aioson/locales/fr/agents/neo.md +2 -0
  236. package/template/.aioson/locales/fr/agents/orache.md +2 -0
  237. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  238. package/template/.aioson/locales/fr/agents/pair.md +2 -0
  239. package/template/.aioson/locales/fr/agents/pm.md +2 -0
  240. package/template/.aioson/locales/fr/agents/product.md +52 -0
  241. package/template/.aioson/locales/fr/agents/profiler-enricher.md +2 -0
  242. package/template/.aioson/locales/fr/agents/profiler-forge.md +2 -0
  243. package/template/.aioson/locales/fr/agents/profiler-researcher.md +2 -0
  244. package/template/.aioson/locales/fr/agents/qa.md +2 -0
  245. package/template/.aioson/locales/fr/agents/setup.md +35 -1
  246. package/template/.aioson/locales/fr/agents/sheldon.md +117 -0
  247. package/template/.aioson/locales/fr/agents/squad.md +16 -0
  248. package/template/.aioson/locales/fr/agents/tester.md +9 -0
  249. package/template/.aioson/locales/fr/agents/ux-ui.md +2 -0
  250. package/template/.aioson/locales/pt-BR/agents/analyst.md +64 -3
  251. package/template/.aioson/locales/pt-BR/agents/architect.md +42 -0
  252. package/template/.aioson/locales/pt-BR/agents/dev.md +147 -14
  253. package/template/.aioson/locales/pt-BR/agents/deyvin.md +47 -0
  254. package/template/.aioson/locales/pt-BR/agents/neo.md +62 -1
  255. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +158 -2
  256. package/template/.aioson/locales/pt-BR/agents/pm.md +95 -1
  257. package/template/.aioson/locales/pt-BR/agents/product.md +145 -18
  258. package/template/.aioson/locales/pt-BR/agents/qa.md +16 -0
  259. package/template/.aioson/locales/pt-BR/agents/setup.md +134 -19
  260. package/template/.aioson/locales/pt-BR/agents/sheldon.md +132 -1
  261. package/template/.aioson/locales/pt-BR/agents/squad.md +14 -0
  262. package/template/.aioson/locales/pt-BR/agents/tester.md +449 -0
  263. package/template/.aioson/rules/README.md +69 -0
  264. package/template/.aioson/rules/data-format-convention.md +136 -0
  265. package/template/.aioson/rules/example-monetary-values.md +30 -0
  266. package/template/.aioson/schemas/squad-manifest.schema.json +124 -3
  267. package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
  268. package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
  269. package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
  270. package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
  271. package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
  272. package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
  273. package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
  274. package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
  275. package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
  276. package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
  277. package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
  278. package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
  279. package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
  280. package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
  281. package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
  282. package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
  283. package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
  284. package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
  285. package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
  286. package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
  287. package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
  288. package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
  289. package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
  290. package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -0
  291. package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -0
  292. package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +66 -0
  293. package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +368 -0
  294. package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -0
  295. package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -0
  296. package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -0
  297. package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +165 -0
  298. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +46 -0
  299. package/template/.aioson/skills/process/aioson-spec-driven/references/analyst.md +30 -0
  300. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
  301. package/template/.aioson/skills/process/aioson-spec-driven/references/architect.md +23 -0
  302. package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
  303. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
  304. package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +47 -0
  305. package/template/.aioson/skills/process/aioson-spec-driven/references/deyvin.md +27 -0
  306. package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
  307. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +101 -0
  308. package/template/.aioson/skills/process/aioson-spec-driven/references/product.md +25 -0
  309. package/template/.aioson/skills/process/aioson-spec-driven/references/qa.md +30 -0
  310. package/template/.aioson/skills/process/aioson-spec-driven/references/sheldon.md +25 -0
  311. package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
  312. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +147 -0
  313. package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
  314. package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
  315. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +306 -0
  316. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +149 -0
  317. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +208 -0
  318. package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -0
  319. package/template/.aioson/skills/process/simplify/SKILL.md +173 -0
  320. package/template/.aioson/skills/static/context-budget-guide.md +46 -0
  321. package/template/.aioson/skills/static/harness-sensors.md +74 -0
  322. package/template/.aioson/skills/static/multi-agent-patterns.md +43 -0
  323. package/template/.aioson/skills/static/react-motion-patterns.md +22 -0
  324. package/template/.aioson/skills/static/static-html-patterns/checklists.md +43 -0
  325. package/template/.aioson/skills/static/static-html-patterns/css-tokens.md +609 -0
  326. package/template/.aioson/skills/static/static-html-patterns/motion.md +193 -0
  327. package/template/.aioson/skills/static/static-html-patterns/premium.md +711 -0
  328. package/template/.aioson/skills/static/static-html-patterns/structure.md +209 -0
  329. package/template/.aioson/skills/static/static-html-patterns/utilities.md +190 -0
  330. package/template/.aioson/skills/static/static-html-patterns.md +58 -1913
  331. package/template/.aioson/skills/static/threejs-patterns.md +929 -0
  332. package/template/.aioson/skills/static/web-research-cache.md +112 -0
  333. package/template/.aioson/tasks/implementation-plan.md +21 -1
  334. package/template/.claude/commands/aioson/agent/design-hybrid-forge.md +5 -0
  335. package/template/.claude/commands/aioson/agent/orache.md +5 -0
  336. package/template/.claude/commands/aioson/agent/sheldon.md +5 -0
  337. package/template/.claude/commands/aioson/agent/site-forge.md +5 -0
  338. package/template/AGENTS.md +75 -1
  339. package/template/CLAUDE.md +31 -0
  340. package/template/OPENCODE.md +4 -0
  341. package/template/researchs/.gitkeep +0 -0
@@ -0,0 +1,154 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { execFile } = require('node:child_process');
6
+ const { promisify } = require('node:util');
7
+
8
+ const execFileAsync = promisify(execFile);
9
+
10
+ const CONTEXT_DIR = path.join('.aioson', 'context');
11
+ const RECOVERY_FILE = 'recovery-context.md';
12
+ const MAX_TOKENS = 2000;
13
+
14
+ function estimateTokens(str) {
15
+ return Math.ceil(str.length / 4);
16
+ }
17
+
18
+ async function readRecentGitLog(cwd, limit = 10) {
19
+ try {
20
+ const { stdout } = await execFileAsync('git', [
21
+ 'log', `--max-count=${limit}`, '--oneline', '--no-merges'
22
+ ], { cwd });
23
+ return stdout.trim().split('\n').filter(Boolean);
24
+ } catch {
25
+ return [];
26
+ }
27
+ }
28
+
29
+ async function readModifiedFiles(cwd) {
30
+ try {
31
+ const { stdout } = await execFileAsync('git', [
32
+ 'diff', '--name-only', 'HEAD'
33
+ ], { cwd });
34
+ return stdout.trim().split('\n').filter(Boolean);
35
+ } catch {
36
+ return [];
37
+ }
38
+ }
39
+
40
+ function buildSessionRecoveryMarkdown(sessionState, gitLog, modifiedFiles) {
41
+ const lines = [];
42
+
43
+ lines.push('# Recovery Context — Direct Session');
44
+ lines.push(`> Generated: ${new Date().toISOString()}`);
45
+ lines.push('');
46
+
47
+ // Session goal/task
48
+ if (sessionState.goal) {
49
+ lines.push('## Current Goal');
50
+ lines.push(sessionState.goal);
51
+ lines.push('');
52
+ }
53
+
54
+ // Active agent
55
+ if (sessionState.agent) {
56
+ lines.push('## Active Agent');
57
+ lines.push(sessionState.agent);
58
+ lines.push('');
59
+ }
60
+
61
+ // Tasks
62
+ const tasks = Array.isArray(sessionState.tasks) ? sessionState.tasks : [];
63
+ if (tasks.length > 0) {
64
+ lines.push('## Tasks');
65
+ for (const t of tasks.slice(-5)) {
66
+ const status = t.status || 'unknown';
67
+ const title = t.title || t.id || '(untitled)';
68
+ lines.push(`- [${status}] ${title}`);
69
+ }
70
+ lines.push('');
71
+ }
72
+
73
+ // Notes
74
+ const notes = Array.isArray(sessionState.notes) ? sessionState.notes : [];
75
+ if (notes.length > 0) {
76
+ lines.push('## Notes');
77
+ for (const note of notes.slice(-5)) {
78
+ lines.push(`- ${note}`);
79
+ }
80
+ lines.push('');
81
+ }
82
+
83
+ // Modified files
84
+ if (modifiedFiles.length > 0) {
85
+ lines.push('## Modified Files');
86
+ for (const f of modifiedFiles.slice(0, 10)) {
87
+ lines.push(`- ${f}`);
88
+ }
89
+ lines.push('');
90
+ }
91
+
92
+ // Recent git commits
93
+ if (gitLog.length > 0) {
94
+ lines.push('## Recent Commits');
95
+ for (const entry of gitLog.slice(0, 5)) {
96
+ lines.push(`- ${entry}`);
97
+ }
98
+ lines.push('');
99
+ }
100
+
101
+ lines.push('---');
102
+ lines.push('*Inject this file at the top of your next session to restore context after a compact.*');
103
+
104
+ return lines.join('\n');
105
+ }
106
+
107
+ /**
108
+ * Generate and write recovery-context.md for a direct session (no squad).
109
+ * @param {string} cwd — project root directory
110
+ * @param {object} sessionState — { goal?, agent?, tasks?, notes? }
111
+ * @returns {{ ok: boolean, path: string, tokens: number }}
112
+ */
113
+ async function generateSessionRecovery(cwd, sessionState = {}) {
114
+ const [gitLog, modifiedFiles] = await Promise.all([
115
+ readRecentGitLog(cwd),
116
+ readModifiedFiles(cwd)
117
+ ]);
118
+
119
+ let content = buildSessionRecoveryMarkdown(sessionState, gitLog, modifiedFiles);
120
+
121
+ // Enforce token budget
122
+ if (estimateTokens(content) > MAX_TOKENS) {
123
+ content = buildSessionRecoveryMarkdown(sessionState, gitLog.slice(0, 3), modifiedFiles.slice(0, 5));
124
+ }
125
+
126
+ const tokens = estimateTokens(content);
127
+ const outDir = path.join(cwd, CONTEXT_DIR);
128
+ const outPath = path.join(outDir, RECOVERY_FILE);
129
+
130
+ try {
131
+ await fs.mkdir(outDir, { recursive: true });
132
+ await fs.writeFile(outPath, content, 'utf8');
133
+ } catch (err) {
134
+ return { ok: false, error: err.message, path: outPath, tokens };
135
+ }
136
+
137
+ return { ok: true, path: outPath, tokens };
138
+ }
139
+
140
+ /**
141
+ * Read the current session recovery-context.md (returns null if missing).
142
+ * @param {string} cwd
143
+ * @returns {string|null}
144
+ */
145
+ async function readSessionRecovery(cwd) {
146
+ const p = path.join(cwd, CONTEXT_DIR, RECOVERY_FILE);
147
+ try {
148
+ return await fs.readFile(p, 'utf8');
149
+ } catch {
150
+ return null;
151
+ }
152
+ }
153
+
154
+ module.exports = { generateSessionRecovery, readSessionRecovery };
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ const { launchCLI } = require('./cli-launcher');
4
+
5
+ const DEFAULT_ATTEMPTS = { haiku: 3, sonnet: 2, opus: 1 };
6
+
7
+ // Model IDs por alias. Injetados via ANTHROPIC_MODEL env var para Claude Code.
8
+ const MODEL_MAP = {
9
+ haiku: 'claude-haiku-4-5-20251001',
10
+ sonnet: 'claude-sonnet-4-6',
11
+ opus: 'claude-opus-4-6'
12
+ };
13
+
14
+ /**
15
+ * Executa uma task com cascade de modelos.
16
+ *
17
+ * Para cada modelo na cadeia:
18
+ * 1. Tenta até N vezes (DEFAULT_ATTEMPTS ou customizado)
19
+ * 2. Se result.ok: verifica via gateConfig (opcional)
20
+ * 3. Se aprovado: retorna resultado imediatamente
21
+ * 4. Se reprovado ou falha: tenta próximo modelo
22
+ *
23
+ * @param {string} projectDir
24
+ * @param {string} prompt
25
+ * @param {string[]} modelChain ex: ['haiku', 'sonnet', 'opus']
26
+ * @param {object} options
27
+ * @param {string} [options.tool] CLI a usar (padrão: auto-detectado)
28
+ * @param {Function} [options.gateCheck] fn(output: string) → {passed: boolean, reason?: string}
29
+ * @param {Function} [options.onProgress] fn({model, attempt, maxAttempts, status, reason?})
30
+ * @param {number} [options.timeout] Timeout em ms por tentativa
31
+ * @returns {Promise<{ok: boolean, result?, modelUsed?: string, attempts?: number, error?: string}>}
32
+ */
33
+ async function runWithCascade(projectDir, prompt, modelChain, options = {}) {
34
+ const { tool, gateCheck, onProgress, timeout } = options;
35
+
36
+ for (const modelAlias of modelChain) {
37
+ const maxAttempts = DEFAULT_ATTEMPTS[modelAlias] ?? 1;
38
+ const modelId = MODEL_MAP[modelAlias];
39
+
40
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
41
+ if (onProgress) {
42
+ onProgress({ model: modelAlias, attempt, maxAttempts, status: 'running' });
43
+ }
44
+
45
+ // Injeta o modelo via ANTHROPIC_MODEL (compatível com Claude Code)
46
+ const extraEnv = modelId ? { ANTHROPIC_MODEL: modelId } : {};
47
+
48
+ const result = await launchCLI(projectDir, prompt, {
49
+ tool,
50
+ timeout,
51
+ env: extraEnv
52
+ });
53
+
54
+ if (!result.ok) {
55
+ if (onProgress) {
56
+ onProgress({ model: modelAlias, attempt, maxAttempts, status: 'cli_failed' });
57
+ }
58
+ continue;
59
+ }
60
+
61
+ // Verifica qualidade se gate configurado
62
+ if (gateCheck) {
63
+ const gateResult = gateCheck(result.output);
64
+ if (gateResult.passed) {
65
+ return { ok: true, result, modelUsed: modelAlias, attempts: attempt };
66
+ }
67
+ if (onProgress) {
68
+ onProgress({
69
+ model: modelAlias,
70
+ attempt,
71
+ maxAttempts,
72
+ status: 'gate_failed',
73
+ reason: gateResult.reason || 'quality gate failed'
74
+ });
75
+ }
76
+ // Não retorna — tenta próxima tentativa ou próximo modelo
77
+ } else {
78
+ // Sem gate: aceita o resultado
79
+ return { ok: true, result, modelUsed: modelAlias, attempts: attempt };
80
+ }
81
+ }
82
+ }
83
+
84
+ return { ok: false, error: 'All cascade models exhausted without passing quality gate' };
85
+ }
86
+
87
+ /**
88
+ * Parseia uma string de cascade como "haiku,sonnet,opus" para um array.
89
+ * @param {string} cascadeStr
90
+ * @returns {string[]}
91
+ */
92
+ function parseCascadeChain(cascadeStr) {
93
+ if (!cascadeStr) return [];
94
+ return cascadeStr.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean);
95
+ }
96
+
97
+ module.exports = { runWithCascade, parseCascadeChain, MODEL_MAP, DEFAULT_ATTEMPTS };
@@ -0,0 +1,109 @@
1
+ 'use strict';
2
+
3
+ const { spawn } = require('node:child_process');
4
+
5
+ /**
6
+ * Detecta qual CLI de AI está disponível no sistema.
7
+ * Usa AIOSON_RUNNER_TOOL env var se definida, depois tenta
8
+ * claude, codex, gemini, opencode em sequência.
9
+ */
10
+ async function detectCLI() {
11
+ const envTool = process.env.AIOSON_RUNNER_TOOL;
12
+ if (envTool) return envTool;
13
+
14
+ for (const cli of ['claude', 'codex', 'gemini', 'opencode']) {
15
+ const found = await new Promise((resolve) => {
16
+ const child = spawn('which', [cli], { stdio: 'pipe' });
17
+ child.on('close', (code) => resolve(code === 0));
18
+ child.on('error', () => resolve(false));
19
+ });
20
+ if (found) return cli;
21
+ }
22
+ throw new Error('No AI CLI found. Install claude, codex, gemini, or opencode.');
23
+ }
24
+
25
+ /**
26
+ * Monta os argumentos de headless para cada CLI.
27
+ */
28
+ function buildArgs(cli, prompt, options = {}) {
29
+ const { allowedTools, outputFormat } = options;
30
+
31
+ switch (cli) {
32
+ case 'claude':
33
+ return [
34
+ '-p', prompt,
35
+ '--output-format', outputFormat || 'stream-json',
36
+ '--dangerously-skip-permissions',
37
+ ...(allowedTools ? ['--allowedTools', allowedTools] : [])
38
+ ];
39
+ case 'codex':
40
+ return ['-p', prompt, '--quiet', '--no-interactive'];
41
+ case 'gemini':
42
+ return ['-p', prompt, '--quiet'];
43
+ default:
44
+ return ['-p', prompt];
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Spawna o CLI de AI com o prompt headless e retorna o output.
50
+ * Detecta TASK_COMPLETE no stream para sinalizar conclusão.
51
+ *
52
+ * @param {string} projectDir
53
+ * @param {string} prompt
54
+ * @param {object} options
55
+ * @returns {Promise<{ok: boolean, output: string, stderr: string, completionMarker: boolean, exitCode: number}>}
56
+ */
57
+ async function launchCLI(projectDir, prompt, options = {}) {
58
+ const { tool, timeout = 120000, onData, env: extraEnv } = options;
59
+ const cli = tool || await detectCLI();
60
+ const args = buildArgs(cli, prompt, options);
61
+
62
+ return new Promise((resolve) => {
63
+ const child = spawn(cli, args, {
64
+ cwd: projectDir,
65
+ env: { ...process.env, ...(extraEnv || {}) },
66
+ stdio: ['ignore', 'pipe', 'pipe']
67
+ });
68
+
69
+ let stdout = '';
70
+ let stderr = '';
71
+ let completionMarker = false;
72
+ let settled = false;
73
+
74
+ const timer = timeout > 0
75
+ ? setTimeout(() => {
76
+ if (!settled) child.kill('SIGTERM');
77
+ }, timeout)
78
+ : null;
79
+
80
+ child.stdout.on('data', (chunk) => {
81
+ const text = chunk.toString();
82
+ stdout += text;
83
+ if (onData) onData(text);
84
+ if (text.includes('TASK_COMPLETE')) completionMarker = true;
85
+ });
86
+
87
+ child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
88
+
89
+ child.on('close', (code) => {
90
+ settled = true;
91
+ if (timer) clearTimeout(timer);
92
+ resolve({
93
+ ok: code === 0,
94
+ output: stdout.trim(),
95
+ stderr: stderr.trim(),
96
+ completionMarker,
97
+ exitCode: code ?? -1
98
+ });
99
+ });
100
+
101
+ child.on('error', (err) => {
102
+ settled = true;
103
+ if (timer) clearTimeout(timer);
104
+ resolve({ ok: false, output: '', stderr: err.message, completionMarker: false, exitCode: -1 });
105
+ });
106
+ });
107
+ }
108
+
109
+ module.exports = { launchCLI, detectCLI, buildArgs };
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+
6
+ /**
7
+ * Parseia um implementation-plan-{slug}.md e extrai as phases como tasks.
8
+ *
9
+ * Formatos suportados:
10
+ * ## Phase 1 — Title
11
+ * ## Phase 1 - Title
12
+ * ## Phase 1: Title
13
+ *
14
+ * @param {string} projectDir
15
+ * @param {string} slug
16
+ * @param {{ agent?: string }} options
17
+ * @returns {Promise<Array<{task: string, agent: string, status: string}>>}
18
+ */
19
+ async function importFromPlan(projectDir, slug, options = {}) {
20
+ const { agent = 'dev' } = options;
21
+
22
+ const candidates = [
23
+ path.join(projectDir, '.aioson', 'context', `implementation-plan-${slug}.md`),
24
+ path.join(projectDir, '.aioson', 'plans', `implementation-plan-${slug}.md`),
25
+ path.join(projectDir, `implementation-plan-${slug}.md`)
26
+ ];
27
+
28
+ let content = null;
29
+ let foundPath = null;
30
+ for (const candidate of candidates) {
31
+ try {
32
+ content = await fs.readFile(candidate, 'utf8');
33
+ foundPath = candidate;
34
+ break;
35
+ } catch { /* try next */ }
36
+ }
37
+
38
+ if (!content) {
39
+ throw new Error(
40
+ `implementation-plan-${slug}.md not found. Tried:\n` +
41
+ candidates.map((c) => ` ${c}`).join('\n') +
42
+ '\n\nRun `aioson plan . --slug=' + slug + '` to create one.'
43
+ );
44
+ }
45
+
46
+ const tasks = [];
47
+
48
+ // Captura ## Phase N seguido de separador (—, -, :) e título
49
+ // Exemplos: "## Phase 1 — Create migration" "## Phase 1 - Foo" "## Phase 1: Bar"
50
+ const phaseRegex = /^##\s+Phase\s+\d+\s*(?:[—\-:])\s*(.+)$/gim;
51
+ let match;
52
+
53
+ while ((match = phaseRegex.exec(content)) !== null) {
54
+ const title = match[1].trim().replace(/\s*\(.*?\)\s*$/, '').trim(); // remove sufixos como "(2-3 days)"
55
+ if (title) {
56
+ tasks.push({ task: title, agent, status: 'pending' });
57
+ }
58
+ }
59
+
60
+ return { tasks, planPath: foundPath };
61
+ }
62
+
63
+ module.exports = { importFromPlan };
@@ -0,0 +1,159 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * CRUD para a tabela runner_queue no SQLite existente.
5
+ * A tabela é criada automaticamente via openRuntimeDb — este módulo
6
+ * apenas lida com a DDL adicional e os queries da fila do runner.
7
+ */
8
+
9
+ const RUNNER_QUEUE_DDL = `
10
+ CREATE TABLE IF NOT EXISTS runner_queue (
11
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
12
+ task TEXT NOT NULL,
13
+ agent TEXT NOT NULL DEFAULT 'dev',
14
+ status TEXT NOT NULL DEFAULT 'pending',
15
+ cascade TEXT,
16
+ priority INTEGER NOT NULL DEFAULT 0,
17
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
18
+ started_at TEXT,
19
+ finished_at TEXT,
20
+ result_ok INTEGER,
21
+ error_msg TEXT,
22
+ session_id TEXT
23
+ );
24
+ `;
25
+
26
+ /**
27
+ * Garante que a tabela runner_queue existe no DB aberto.
28
+ * @param {import('better-sqlite3').Database} db
29
+ */
30
+ function ensureRunnerQueue(db) {
31
+ db.exec(RUNNER_QUEUE_DDL);
32
+ }
33
+
34
+ /**
35
+ * Adiciona uma task à fila.
36
+ * @param {import('better-sqlite3').Database} db
37
+ * @param {{ task: string, agent?: string, cascade?: string, priority?: number }} options
38
+ * @returns {number} id da task inserida
39
+ */
40
+ function addTask(db, options) {
41
+ ensureRunnerQueue(db);
42
+ const { task, agent = 'dev', cascade = null, priority = 0 } = options;
43
+ const result = db.prepare(`
44
+ INSERT INTO runner_queue (task, agent, cascade, priority)
45
+ VALUES (?, ?, ?, ?)
46
+ `).run(task, agent, cascade, priority);
47
+ return result.lastInsertRowid;
48
+ }
49
+
50
+ /**
51
+ * Lista todas as tasks da fila, ordenadas por prioridade DESC, criação ASC.
52
+ * @param {import('better-sqlite3').Database} db
53
+ * @param {{ status?: string }} options
54
+ */
55
+ function listTasks(db, options = {}) {
56
+ ensureRunnerQueue(db);
57
+ if (options.status) {
58
+ return db.prepare(`
59
+ SELECT * FROM runner_queue WHERE status = ? ORDER BY priority DESC, id ASC
60
+ `).all(options.status);
61
+ }
62
+ return db.prepare(`
63
+ SELECT * FROM runner_queue ORDER BY priority DESC, id ASC
64
+ `).all();
65
+ }
66
+
67
+ /**
68
+ * Busca a próxima task com status pending.
69
+ * @param {import('better-sqlite3').Database} db
70
+ */
71
+ function nextPending(db) {
72
+ ensureRunnerQueue(db);
73
+ return db.prepare(`
74
+ SELECT * FROM runner_queue WHERE status = 'pending' ORDER BY priority DESC, id ASC LIMIT 1
75
+ `).get();
76
+ }
77
+
78
+ /**
79
+ * Atualiza o status de uma task.
80
+ * @param {import('better-sqlite3').Database} db
81
+ * @param {number} id
82
+ * @param {{ status: string, resultOk?: boolean, errorMsg?: string, sessionId?: string }} options
83
+ */
84
+ function updateTaskStatus(db, id, options) {
85
+ ensureRunnerQueue(db);
86
+ const now = new Date().toISOString();
87
+ const status = options.status;
88
+ const isFinished = status === 'completed' || status === 'failed' || status === 'skipped';
89
+ const isStarted = status === 'running';
90
+
91
+ db.prepare(`
92
+ UPDATE runner_queue
93
+ SET status = ?,
94
+ result_ok = COALESCE(?, result_ok),
95
+ error_msg = COALESCE(?, error_msg),
96
+ session_id = COALESCE(?, session_id),
97
+ started_at = CASE WHEN ? = 1 THEN ? ELSE started_at END,
98
+ finished_at = CASE WHEN ? = 1 THEN ? ELSE finished_at END
99
+ WHERE id = ?
100
+ `).run(
101
+ status,
102
+ options.resultOk != null ? (options.resultOk ? 1 : 0) : null,
103
+ options.errorMsg ?? null,
104
+ options.sessionId ?? null,
105
+ isStarted ? 1 : 0, now,
106
+ isFinished ? 1 : 0, now,
107
+ id
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Remove todas as tasks da fila (clear).
113
+ * @param {import('better-sqlite3').Database} db
114
+ */
115
+ function clearQueue(db) {
116
+ ensureRunnerQueue(db);
117
+ db.prepare('DELETE FROM runner_queue').run();
118
+ }
119
+
120
+ /**
121
+ * Exporta todas as tasks como Markdown.
122
+ * @param {import('better-sqlite3').Database} db
123
+ */
124
+ function exportQueueMarkdown(db) {
125
+ const tasks = listTasks(db);
126
+ if (tasks.length === 0) return '# Runner Queue\n\n_Queue is empty._\n';
127
+
128
+ const STATUS_ICON = {
129
+ pending: '○',
130
+ running: '▶',
131
+ completed: '✓',
132
+ failed: '✗',
133
+ skipped: '—'
134
+ };
135
+
136
+ const lines = ['# Runner Queue', ''];
137
+ for (const t of tasks) {
138
+ const icon = STATUS_ICON[t.status] || '?';
139
+ const cascade = t.cascade ? ` [cascade: ${t.cascade}]` : '';
140
+ lines.push(`- ${icon} **${t.id}** \`@${t.agent}\`${cascade} — ${t.task}`);
141
+ if (t.status !== 'pending') {
142
+ lines.push(` - Status: ${t.status} | Created: ${t.created_at}`);
143
+ if (t.finished_at) lines.push(` - Finished: ${t.finished_at}`);
144
+ if (t.error_msg) lines.push(` - Error: ${t.error_msg}`);
145
+ }
146
+ }
147
+ lines.push('');
148
+ return lines.join('\n');
149
+ }
150
+
151
+ module.exports = {
152
+ ensureRunnerQueue,
153
+ addTask,
154
+ listTasks,
155
+ nextPending,
156
+ updateTaskStatus,
157
+ clearQueue,
158
+ exportQueueMarkdown
159
+ };