@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,189 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { openRuntimeDb } = require('../runtime-store');
5
+ const {
6
+ ensureRunnerQueue,
7
+ addTask,
8
+ listTasks,
9
+ nextPending,
10
+ updateTaskStatus,
11
+ clearQueue,
12
+ exportQueueMarkdown
13
+ } = require('../runner/queue-store');
14
+ const { launchCLI } = require('../runner/cli-launcher');
15
+ const { runWithCascade, parseCascadeChain } = require('../runner/cascade');
16
+
17
+ const STATUS_ICON = {
18
+ pending: '○',
19
+ running: '▶',
20
+ completed: '✓',
21
+ failed: '✗',
22
+ skipped: '—'
23
+ };
24
+
25
+ /**
26
+ * aioson runner:queue — gerencia e executa a fila de tasks do runner.
27
+ *
28
+ * Subcomandos:
29
+ * add <path> "task description" [--agent=dev] [--cascade=haiku,sonnet]
30
+ * list <path>
31
+ * run <path> [--agent=dev] [--timeout=120]
32
+ * export <path>
33
+ * clear <path>
34
+ */
35
+ async function runRunnerQueue({ args, options = {}, logger }) {
36
+ const sub = options.sub || args[1] || 'list';
37
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
38
+
39
+ const handle = await openRuntimeDb(projectDir, {});
40
+ if (!handle) {
41
+ logger.error('Could not open runtime database.');
42
+ return { ok: false };
43
+ }
44
+ const { db } = handle;
45
+ ensureRunnerQueue(db);
46
+
47
+ try {
48
+ switch (sub) {
49
+ case 'add': return await handleAdd(db, args, options, logger);
50
+ case 'list': return handleList(db, logger);
51
+ case 'run': return await handleRun(db, projectDir, options, logger);
52
+ case 'export': return handleExport(db, logger);
53
+ case 'clear': return handleClear(db, logger);
54
+ default:
55
+ logger.error(`Unknown subcommand: ${sub}. Use add, list, run, export, or clear.`);
56
+ return { ok: false };
57
+ }
58
+ } finally {
59
+ try { db.close(); } catch { /* noop */ }
60
+ }
61
+ }
62
+
63
+ function handleAdd(db, args, options, logger) {
64
+ // Task pode vir de args[2] ou --task
65
+ const task = options.task || args[2];
66
+ if (!task) {
67
+ logger.error('Task description required. Usage: aioson runner:queue add . "task description"');
68
+ return { ok: false };
69
+ }
70
+ const agent = options.agent || 'dev';
71
+ const cascade = options.cascade || null;
72
+ const priority = options.priority ? Number(options.priority) : 0;
73
+
74
+ const id = addTask(db, { task, agent, cascade, priority });
75
+ logger.log(`[runner:queue] Added task #${id}: ${task}`);
76
+ logger.log(` Agent: @${agent}${cascade ? ' | Cascade: ' + cascade : ''}`);
77
+ return { ok: true, id };
78
+ }
79
+
80
+ function handleList(db, logger) {
81
+ const tasks = listTasks(db);
82
+ if (tasks.length === 0) {
83
+ logger.log('[runner:queue] Queue is empty. Use `runner:queue add` to add tasks.');
84
+ return { ok: true, tasks: [] };
85
+ }
86
+
87
+ logger.log(`[runner:queue] ${tasks.length} task(s):`);
88
+ for (const t of tasks) {
89
+ const icon = STATUS_ICON[t.status] || '?';
90
+ const cascade = t.cascade ? ` [cascade: ${t.cascade}]` : '';
91
+ logger.log(` ${icon} ${t.id} @${t.agent}${cascade} ${t.task}`);
92
+ }
93
+ return { ok: true, tasks };
94
+ }
95
+
96
+ async function handleRun(db, projectDir, options, logger) {
97
+ const defaultAgent = options.agent || 'dev';
98
+ const timeout = options.timeout ? Number(options.timeout) * 1000 : 120000;
99
+
100
+ let processed = 0;
101
+ let failed = 0;
102
+
103
+ logger.log('[runner:queue] Starting queue execution...');
104
+
105
+ // eslint-disable-next-line no-constant-condition
106
+ while (true) {
107
+ const task = nextPending(db);
108
+ if (!task) {
109
+ logger.log(`[runner:queue] Queue exhausted. ${processed} completed, ${failed} failed.`);
110
+ break;
111
+ }
112
+
113
+ const agent = task.agent || defaultAgent;
114
+ const agentFile = path.join(projectDir, '.aioson', 'agents', `${agent}.md`);
115
+ const prompt = buildQueuePrompt(task.task, agentFile);
116
+
117
+ logger.log(`\n[runner:queue] Running task #${task.id}: ${task.task}`);
118
+ logger.log(` Agent: @${agent}`);
119
+
120
+ updateTaskStatus(db, task.id, { status: 'running' });
121
+
122
+ let result;
123
+ const cascadeChain = parseCascadeChain(task.cascade);
124
+
125
+ try {
126
+ if (cascadeChain.length > 0) {
127
+ const cascadeResult = await runWithCascade(projectDir, prompt, cascadeChain, {
128
+ timeout,
129
+ onProgress: ({ model, attempt, maxAttempts, status, reason }) => {
130
+ if (status === 'running') {
131
+ logger.log(` [cascade] ${model} attempt ${attempt}/${maxAttempts}...`);
132
+ } else if (status === 'gate_failed') {
133
+ logger.log(` [cascade] ${model} attempt ${attempt} — gate failed${reason ? ': ' + reason : ''}, escalating...`);
134
+ }
135
+ }
136
+ });
137
+ result = cascadeResult.ok
138
+ ? cascadeResult.result
139
+ : { ok: false, output: '', error: cascadeResult.error };
140
+ } else {
141
+ result = await launchCLI(projectDir, prompt, {
142
+ timeout,
143
+ onData: (chunk) => process.stdout.write(chunk)
144
+ });
145
+ }
146
+ } catch (err) {
147
+ result = { ok: false, output: '', error: err.message };
148
+ }
149
+
150
+ if (result.ok) {
151
+ updateTaskStatus(db, task.id, { status: 'completed', resultOk: true });
152
+ logger.log(` [runner:queue] Task #${task.id} completed`);
153
+ processed++;
154
+ } else {
155
+ const errorMsg = result.error || result.stderr || 'unknown error';
156
+ updateTaskStatus(db, task.id, { status: 'failed', resultOk: false, errorMsg });
157
+ logger.error(` [runner:queue] Task #${task.id} failed: ${errorMsg}`);
158
+ failed++;
159
+ }
160
+ }
161
+
162
+ return { ok: true, processed, failed };
163
+ }
164
+
165
+ function handleExport(db, logger) {
166
+ const markdown = exportQueueMarkdown(db);
167
+ process.stdout.write(markdown);
168
+ return { ok: true };
169
+ }
170
+
171
+ function handleClear(db, logger) {
172
+ clearQueue(db);
173
+ logger.log('[runner:queue] Queue cleared.');
174
+ return { ok: true };
175
+ }
176
+
177
+ function buildQueuePrompt(task, agentFile) {
178
+ return [
179
+ 'You are operating in autonomous headless mode. Complete the following task independently.',
180
+ `Agent role: read ${agentFile} for your operating instructions.`,
181
+ '',
182
+ `Task: ${task}`,
183
+ '',
184
+ 'When the task is complete, write TASK_COMPLETE on a new line as the final output.',
185
+ 'If you cannot complete the task, write TASK_FAILED: [reason].'
186
+ ].join('\n');
187
+ }
188
+
189
+ module.exports = { runRunnerQueue };
@@ -0,0 +1,129 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { launchCLI, detectCLI } = require('../runner/cli-launcher');
5
+ const { runWithCascade, parseCascadeChain } = require('../runner/cascade');
6
+ const { openRuntimeDb, startRun, updateRun, createRunKey } = require('../runtime-store');
7
+
8
+ /**
9
+ * aioson runner:run — executa uma única task headless usando o CLI de AI ativo.
10
+ *
11
+ * Usage:
12
+ * aioson runner:run . --task="Fix the auth modal" --agent=dev
13
+ * aioson runner:run . --task="..." --agent=qa --timeout=300
14
+ * aioson runner:run . --task="..." --agent=dev --cascade=haiku,sonnet
15
+ * aioson runner:run . --task="..." --dry-run
16
+ */
17
+ async function runRunnerRun({ args, options = {}, logger }) {
18
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
19
+ const { task, agent = 'dev', dryRun, cascade: cascadeStr } = options;
20
+ const timeout = options.timeout ? Number(options.timeout) * 1000 : 120000;
21
+
22
+ if (!task) {
23
+ logger.error('--task is required. Example: aioson runner:run . --task="Fix the login modal"');
24
+ return { ok: false };
25
+ }
26
+
27
+ const agentFile = path.join(projectDir, '.aioson', 'agents', `${agent}.md`);
28
+ const prompt = buildRunnerPrompt(task, agentFile);
29
+
30
+ if (dryRun) {
31
+ let cli;
32
+ try { cli = await detectCLI(); } catch { cli = 'claude'; }
33
+ logger.log(`[dry-run] Would run: ${cli} -p "${prompt.slice(0, 120)}..."`);
34
+ logger.log(`[dry-run] Agent: @${agent} | Timeout: ${timeout / 1000}s`);
35
+ if (cascadeStr) logger.log(`[dry-run] Cascade: ${cascadeStr}`);
36
+ return { ok: true, dryRun: true };
37
+ }
38
+
39
+ logger.log(`[runner] Task: ${task}`);
40
+ logger.log(`[runner] Agent: @${agent} | Timeout: ${timeout / 1000}s`);
41
+ if (cascadeStr) logger.log(`[runner] Cascade: ${cascadeStr}`);
42
+
43
+ const start = Date.now();
44
+
45
+ // Abre DB para registrar evento (melhor esforço — não bloqueia se não existir)
46
+ let db = null;
47
+ let runKey = null;
48
+ try {
49
+ const handle = await openRuntimeDb(projectDir, {});
50
+ if (handle) {
51
+ db = handle.db;
52
+ runKey = createRunKey(agent);
53
+ startRun(db, {
54
+ runKey,
55
+ agentName: agent,
56
+ agentKind: 'runner',
57
+ source: 'runner',
58
+ title: task.slice(0, 80),
59
+ status: 'running',
60
+ message: `Runner task started: ${task.slice(0, 80)}`
61
+ });
62
+ }
63
+ } catch { /* dashboard logging is best-effort */ }
64
+
65
+ let result;
66
+ const cascadeChain = parseCascadeChain(cascadeStr);
67
+
68
+ if (cascadeChain.length > 0) {
69
+ const cascadeResult = await runWithCascade(projectDir, prompt, cascadeChain, {
70
+ timeout,
71
+ onProgress: ({ model, attempt, maxAttempts, status, reason }) => {
72
+ if (status === 'running') {
73
+ logger.log(`[cascade] ${model} attempt ${attempt}/${maxAttempts}...`);
74
+ } else if (status === 'gate_failed') {
75
+ logger.log(`[cascade] ${model} attempt ${attempt} — gate failed${reason ? ': ' + reason : ''}, escalating...`);
76
+ } else if (status === 'cli_failed') {
77
+ logger.log(`[cascade] ${model} attempt ${attempt} — CLI failed, retrying...`);
78
+ }
79
+ }
80
+ });
81
+ if (cascadeResult.ok) {
82
+ result = cascadeResult.result;
83
+ logger.log(`[runner] Completed via ${cascadeResult.modelUsed} (attempt ${cascadeResult.attempts})`);
84
+ } else {
85
+ result = { ok: false, output: '', completionMarker: false };
86
+ logger.error(`[runner] ${cascadeResult.error}`);
87
+ }
88
+ } else {
89
+ result = await launchCLI(projectDir, prompt, {
90
+ timeout,
91
+ onData: (chunk) => process.stdout.write(chunk)
92
+ });
93
+ }
94
+
95
+ const elapsed = Math.round((Date.now() - start) / 1000);
96
+ const status = result.ok ? 'completed' : 'failed';
97
+
98
+ logger.log(`\n[runner] Task ${status} in ${elapsed}s`);
99
+ if (result.completionMarker) logger.log('[runner] TASK_COMPLETE marker detected');
100
+
101
+ // Atualiza run no dashboard
102
+ if (db && runKey) {
103
+ try {
104
+ updateRun(db, {
105
+ runKey,
106
+ status,
107
+ message: `Runner task ${status}: ${task.slice(0, 80)}`,
108
+ payload: { task, agent, elapsed, ok: result.ok, completionMarker: result.completionMarker }
109
+ });
110
+ } catch { /* best-effort */ }
111
+ try { db.close(); } catch { /* noop */ }
112
+ }
113
+
114
+ return { ok: result.ok, output: result.output, elapsed, completionMarker: result.completionMarker };
115
+ }
116
+
117
+ function buildRunnerPrompt(task, agentFile) {
118
+ return [
119
+ 'You are operating in autonomous headless mode. Complete the following task independently.',
120
+ `Agent role: read ${agentFile} for your operating instructions.`,
121
+ '',
122
+ `Task: ${task}`,
123
+ '',
124
+ 'When the task is complete, write TASK_COMPLETE on a new line as the final output.',
125
+ 'If you cannot complete the task, write TASK_FAILED: [reason].'
126
+ ].join('\n');
127
+ }
128
+
129
+ module.exports = { runRunnerRun };
@@ -1179,6 +1179,11 @@ async function runAgentDone({ args, options = {}, logger, t }) {
1179
1179
  const summary = String(options.summary || options.message || `${normalizedAgent} session completed`).trim();
1180
1180
  const title = options.title ? String(options.title).trim() : null;
1181
1181
  const status = options.status || 'completed';
1182
+ const verdict = options.verdict ? String(options.verdict).trim().toUpperCase() : null;
1183
+ const planStepId = options['plan-step'] ? String(options['plan-step']).trim() : null;
1184
+ const artifactPaths = options.artifacts
1185
+ ? String(options.artifacts).split(',').map((p) => p.trim()).filter(Boolean)
1186
+ : [];
1182
1187
 
1183
1188
  const { db, dbPath, runtimeDir } = await openRuntimeDb(targetDir);
1184
1189
 
@@ -1194,9 +1199,24 @@ async function runAgentDone({ args, options = {}, logger, t }) {
1194
1199
  eventType: 'agent_done',
1195
1200
  phase: 'live',
1196
1201
  status: 'running',
1197
- message: summary
1202
+ message: summary,
1203
+ verdict,
1204
+ planStepId
1198
1205
  });
1199
1206
 
1207
+ if (artifactPaths.length > 0) {
1208
+ for (const filePath of artifactPaths) {
1209
+ try {
1210
+ attachArtifact(db, {
1211
+ runKey: session.runKey,
1212
+ agentName: normalizedAgent,
1213
+ kind: 'output',
1214
+ filePath
1215
+ });
1216
+ } catch { /* non-fatal */ }
1217
+ }
1218
+ }
1219
+
1200
1220
  if (!options.json) {
1201
1221
  logger.log(`agent:done — ${normalizedAgent} | live session active, event logged | run: ${session.runKey} (${dbPath})`);
1202
1222
  }
@@ -1219,6 +1239,32 @@ async function runAgentDone({ args, options = {}, logger, t }) {
1219
1239
  summary
1220
1240
  });
1221
1241
 
1242
+ if (verdict || planStepId) {
1243
+ appendRunEvent(db, {
1244
+ runKey,
1245
+ eventType: 'agent_done',
1246
+ phase: 'direct',
1247
+ status: 'completed',
1248
+ message: summary,
1249
+ verdict,
1250
+ planStepId
1251
+ });
1252
+ }
1253
+
1254
+ if (artifactPaths.length > 0) {
1255
+ for (const filePath of artifactPaths) {
1256
+ try {
1257
+ attachArtifact(db, {
1258
+ runKey,
1259
+ taskKey,
1260
+ agentName: normalizedAgent,
1261
+ kind: 'output',
1262
+ filePath
1263
+ });
1264
+ } catch { /* non-fatal */ }
1265
+ }
1266
+ }
1267
+
1222
1268
  if (!options.json) {
1223
1269
  logger.log(`agent:done — ${normalizedAgent} | task: ${taskKey} | run: ${runKey} (${dbPath})`);
1224
1270
  }
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { executeInSandbox } = require('../sandbox');
5
+
6
+ async function runSandboxExec({ args, options, logger }) {
7
+ const command = args[0] || options.command || '';
8
+ const cwd = path.resolve(process.cwd(), options.cwd || '.');
9
+ const timeout = Number(options.timeout) || 30_000;
10
+ const intent = options.intent || undefined;
11
+
12
+ if (!command) {
13
+ logger.error('Usage: aioson sandbox:exec "<command>" [--timeout=30000] [--cwd=.]');
14
+ return { ok: false, error: 'missing_command' };
15
+ }
16
+
17
+ const result = await executeInSandbox(command, { cwd, timeout, intent });
18
+
19
+ if (options.json) {
20
+ return { ok: result.ok, ...result };
21
+ }
22
+
23
+ if (result.stdout) {
24
+ logger.log(result.stdout);
25
+ }
26
+ if (result.stderr) {
27
+ logger.error(result.stderr);
28
+ }
29
+
30
+ if (result.timedOut) {
31
+ logger.error(`Command timed out after ${timeout}ms`);
32
+ }
33
+
34
+ return { ok: result.ok, ...result };
35
+ }
36
+
37
+ module.exports = { runSandboxExec };
@@ -0,0 +1,256 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson self:loop — Autonomous implement + verify loop
5
+ *
6
+ * Runs an agent task, verifies with verify-gate in a fresh context,
7
+ * and retries with feedback injection on failure.
8
+ *
9
+ * Usage:
10
+ * aioson self:loop . --agent=dev --task="implement stripe webhook handler" --max-iterations=3
11
+ * aioson self:loop . --agent=dev --task="..." --verification-criteria="all tests pass"
12
+ * aioson self:loop . --agent=dev --task="..." --spec=briefs/phase-1.md --artifact=src/
13
+ *
14
+ * Integrates with:
15
+ * - verify-gate.js for tiered verification (tiers 1–4)
16
+ * - intra-bus.js for recording attempts
17
+ * - state-manager.js for recording final result
18
+ */
19
+
20
+ const path = require('node:path');
21
+ const { execSync, execFileSync } = require('node:child_process');
22
+ const { randomUUID } = require('node:crypto');
23
+ const fs = require('node:fs/promises');
24
+
25
+ const bus = require('../squad/intra-bus');
26
+ const stateManager = require('../squad/state-manager');
27
+
28
+ // ─── Agent execution ─────────────────────────────────────────────────────────
29
+
30
+ /**
31
+ * Execute an agent task via the aioson CLI.
32
+ * Returns { ok, output, error }.
33
+ */
34
+ function executeAgent(projectDir, agent, task, feedbackContext, timeoutMs) {
35
+ const prompt = feedbackContext
36
+ ? `${task}\n\n---\nPrevious attempt feedback:\n${feedbackContext}`
37
+ : task;
38
+
39
+ try {
40
+ const output = execSync(
41
+ `aioson agent:prompt ${agent} . --tool=claude`,
42
+ {
43
+ cwd: projectDir,
44
+ input: prompt,
45
+ timeout: timeoutMs,
46
+ encoding: 'utf8',
47
+ maxBuffer: 1024 * 1024 * 5,
48
+ stdio: ['pipe', 'pipe', 'pipe']
49
+ }
50
+ );
51
+ return { ok: true, output: output.trim() };
52
+ } catch (err) {
53
+ return { ok: false, output: '', error: err.message.slice(0, 500) };
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Run verify-gate on the result.
59
+ * Returns { ok, verdict, issues }.
60
+ */
61
+ async function runVerification(projectDir, spec, artifact, criteria) {
62
+ if (!spec || !artifact) {
63
+ // Fallback: criteria-only verification
64
+ return criteriaOnlyVerify(projectDir, artifact, criteria);
65
+ }
66
+
67
+ try {
68
+ const output = execSync(
69
+ `aioson verify:gate . --spec="${spec}" --artifact="${artifact}" --json`,
70
+ {
71
+ cwd: projectDir,
72
+ timeout: 30_000,
73
+ encoding: 'utf8',
74
+ maxBuffer: 1024 * 1024
75
+ }
76
+ );
77
+ const result = JSON.parse(output);
78
+ return {
79
+ ok: result.verdict === 'PASS' || result.verdict === 'PASS_WITH_NOTES',
80
+ verdict: result.verdict,
81
+ issues: result.issues || []
82
+ };
83
+ } catch (err) {
84
+ return { ok: false, verdict: 'BLOCKED', issues: [{ message: err.message.slice(0, 200) }] };
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Simple criteria-based verification when no spec/artifact is given.
90
+ * Checks if verification criteria strings are present in the output directory.
91
+ */
92
+ async function criteriaOnlyVerify(projectDir, artifactPath, criteria) {
93
+ if (!criteria) {
94
+ return { ok: true, verdict: 'PASS', issues: [] };
95
+ }
96
+
97
+ const issues = [];
98
+ const criteriaList = criteria.split(',').map((c) => c.trim());
99
+
100
+ for (const criterion of criteriaList) {
101
+ if (/test/i.test(criterion)) {
102
+ // Check if tests pass
103
+ try {
104
+ execSync('npm test --if-present 2>&1', {
105
+ cwd: projectDir,
106
+ timeout: 60_000,
107
+ encoding: 'utf8'
108
+ });
109
+ } catch {
110
+ issues.push({ message: `Test criterion failed: "${criterion}"` });
111
+ }
112
+ }
113
+ }
114
+
115
+ return {
116
+ ok: issues.length === 0,
117
+ verdict: issues.length === 0 ? 'PASS' : 'FAIL_WITH_ISSUES',
118
+ issues
119
+ };
120
+ }
121
+
122
+ // ─── Public API ──────────────────────────────────────────────────────────────
123
+
124
+ /**
125
+ * Run the self-implement loop.
126
+ *
127
+ * @param {object} params
128
+ * @returns {Promise<object>} — { ok, iterations, verdict, feedback[] }
129
+ */
130
+ async function runSelfLoop({ args, options = {}, logger }) {
131
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
132
+ const agent = String(options.agent || options.a || 'dev').trim();
133
+ const task = String(options.task || options.t || '').trim();
134
+ const maxIterations = Math.min(Math.max(Number(options['max-iterations'] || 3), 1), 5);
135
+ const spec = options.spec ? String(options.spec).trim() : null;
136
+ const artifact = options.artifact ? String(options.artifact).trim() : null;
137
+ const criteria = options['verification-criteria'] || options.criteria || '';
138
+ const squad = options.squad ? String(options.squad).trim() : null;
139
+ const timeoutMs = (Number(options.timeout) || 300) * 1000;
140
+
141
+ if (!task) {
142
+ logger.error('Error: --task is required');
143
+ return { ok: false, error: 'missing_task' };
144
+ }
145
+
146
+ const sessionId = randomUUID();
147
+ const feedbackHistory = [];
148
+
149
+ logger.log(`Self-implement loop: @${agent} — "${task.slice(0, 60)}${task.length > 60 ? '...' : ''}"`);
150
+ logger.log(`Max iterations: ${maxIterations}`);
151
+ if (spec) logger.log(`Spec: ${spec}`);
152
+ if (artifact) logger.log(`Artifact: ${artifact}`);
153
+ logger.log('');
154
+
155
+ for (let iteration = 1; iteration <= maxIterations; iteration++) {
156
+ logger.log(`── Iteration ${iteration}/${maxIterations} ──────────────────────────`);
157
+
158
+ // Step 1: Execute agent
159
+ const feedbackContext = feedbackHistory.length > 0
160
+ ? feedbackHistory.map((f) => `[Iteration ${f.iteration}] ${f.verdict}: ${f.issues.map((i) => i.message).join('; ')}`).join('\n')
161
+ : null;
162
+
163
+ logger.log(` Running @${agent}...`);
164
+ const agentResult = executeAgent(targetDir, agent, task, feedbackContext, timeoutMs);
165
+
166
+ if (!agentResult.ok) {
167
+ logger.log(` ✗ Agent execution failed: ${agentResult.error?.slice(0, 100)}`);
168
+ // Record on bus if squad context
169
+ if (squad) {
170
+ await bus.post(targetDir, squad, sessionId, {
171
+ from: 'self-loop',
172
+ type: 'status',
173
+ content: `Iteration ${iteration} — agent failed: ${agentResult.error?.slice(0, 200)}`
174
+ }).catch(() => {});
175
+ }
176
+ continue;
177
+ }
178
+
179
+ // Step 2: Verify (fresh context)
180
+ logger.log(' Verifying...');
181
+ const verifyResult = await runVerification(targetDir, spec, artifact, criteria);
182
+
183
+ // Record on bus
184
+ if (squad) {
185
+ await bus.post(targetDir, squad, sessionId, {
186
+ from: 'self-loop',
187
+ type: verifyResult.ok ? 'result' : 'gap_closure_attempt',
188
+ content: `Iteration ${iteration}: ${verifyResult.verdict}`,
189
+ metadata: {
190
+ iteration,
191
+ verdict: verifyResult.verdict,
192
+ issues_count: verifyResult.issues.length
193
+ }
194
+ }).catch(() => {});
195
+ }
196
+
197
+ // Step 3: Check result
198
+ if (verifyResult.ok) {
199
+ logger.log(` ✓ PASS${iteration > 1 ? ` (after ${iteration} iteration${iteration > 1 ? 's' : ''})` : ''}`);
200
+
201
+ // Record success in state
202
+ if (squad) {
203
+ await stateManager.updateState(targetDir, squad, {
204
+ addDecision: [`self-loop: "${task.slice(0, 50)}" completed in ${iteration} iteration(s)`]
205
+ }).catch(() => {});
206
+ }
207
+
208
+ if (options.json) {
209
+ return { ok: true, iterations: iteration, verdict: verifyResult.verdict, feedback: feedbackHistory };
210
+ }
211
+
212
+ return { ok: true, iterations: iteration, verdict: verifyResult.verdict };
213
+ }
214
+
215
+ // Step 4: Collect feedback for next iteration
216
+ logger.log(` ✗ ${verifyResult.verdict} — ${verifyResult.issues.length} issue(s)`);
217
+ for (const issue of verifyResult.issues.slice(0, 5)) {
218
+ logger.log(` - ${issue.message}`);
219
+ }
220
+
221
+ feedbackHistory.push({
222
+ iteration,
223
+ verdict: verifyResult.verdict,
224
+ issues: verifyResult.issues
225
+ });
226
+ }
227
+
228
+ // Step 5: Exhausted — escalate
229
+ logger.log('');
230
+ logger.log(`✗ Max iterations (${maxIterations}) exhausted — escalating to user`);
231
+
232
+ if (squad) {
233
+ await bus.post(targetDir, squad, sessionId, {
234
+ from: 'self-loop',
235
+ type: 'block',
236
+ content: `Self-implement loop exhausted ${maxIterations} iterations for: "${task.slice(0, 100)}"`,
237
+ metadata: { exhausted: true, iterations: maxIterations }
238
+ }).catch(() => {});
239
+
240
+ await stateManager.updateState(targetDir, squad, {
241
+ addBlocker: [`self-loop exhausted: "${task.slice(0, 50)}" (${maxIterations} iterations)`]
242
+ }).catch(() => {});
243
+ }
244
+
245
+ const result = {
246
+ ok: false,
247
+ iterations: maxIterations,
248
+ verdict: 'EXHAUSTED',
249
+ feedback: feedbackHistory
250
+ };
251
+
252
+ if (options.json) return result;
253
+ return result;
254
+ }
255
+
256
+ module.exports = { runSelfLoop };