@jaimevalasek/aioson 1.6.0 → 1.7.2

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 (275) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/README.md +729 -232
  3. package/docs/design-previews/pt.squarespace.com-homepage.html +889 -0
  4. package/docs/integrations/sdlc-genius-boundary.md +76 -0
  5. package/docs/integrations/sdlc-genius-eval-matrix.md +75 -0
  6. package/docs/integrations/sdlc-genius-install-checklist.md +93 -0
  7. package/docs/integrations/sdlc-genius-review-samples.md +86 -0
  8. package/docs/pt/README.md +3 -0
  9. package/docs/pt/agentes.md +1 -0
  10. package/docs/pt/comandos-cli.md +888 -2
  11. package/docs/pt/design-hybrid-forge.md +255 -6
  12. package/docs/pt/devlog-pipeline.md +270 -0
  13. package/docs/pt/fluxo-artefatos.md +178 -0
  14. package/docs/pt/hooks-session-guard.md +454 -0
  15. package/docs/pt/monitor-de-contexto.md +59 -5
  16. package/docs/pt/sdd-automation-scripts.md +557 -0
  17. package/docs/pt/site-forge.md +309 -0
  18. package/docs/pt/spec-learnings-pipeline.md +265 -0
  19. package/package.json +1 -1
  20. package/src/a2a/client.js +165 -0
  21. package/src/a2a/server.js +223 -0
  22. package/src/cli.js +235 -1
  23. package/src/commands/agent-audit.js +397 -0
  24. package/src/commands/agent-export-skill.js +229 -0
  25. package/src/commands/artifact-validate.js +189 -0
  26. package/src/commands/brief-gen.js +405 -0
  27. package/src/commands/brief-validate.js +65 -0
  28. package/src/commands/classify.js +256 -0
  29. package/src/commands/context-compact.js +49 -0
  30. package/src/commands/context-health.js +175 -0
  31. package/src/commands/context-monitor.js +71 -0
  32. package/src/commands/context-trim.js +177 -0
  33. package/src/commands/detect-test-runner.js +55 -0
  34. package/src/commands/devlog-export-brains.js +27 -0
  35. package/src/commands/devlog-process.js +292 -0
  36. package/src/commands/devlog-watch.js +131 -0
  37. package/src/commands/feature-close.js +165 -0
  38. package/src/commands/gate-check.js +228 -0
  39. package/src/commands/hooks-emit.js +253 -0
  40. package/src/commands/hooks-install.js +347 -0
  41. package/src/commands/learning-auto-promote.js +195 -0
  42. package/src/commands/learning-evolve.js +18 -9
  43. package/src/commands/learning-export.js +103 -0
  44. package/src/commands/learning-rollback.js +164 -0
  45. package/src/commands/live.js +25 -1
  46. package/src/commands/pattern-detect.js +33 -0
  47. package/src/commands/preflight-context.js +30 -0
  48. package/src/commands/preflight.js +208 -0
  49. package/src/commands/pulse-update.js +130 -0
  50. package/src/commands/runner-daemon.js +274 -0
  51. package/src/commands/runner-plan.js +70 -0
  52. package/src/commands/runner-queue-from-plan.js +166 -0
  53. package/src/commands/runner-queue.js +189 -0
  54. package/src/commands/runner-run.js +129 -0
  55. package/src/commands/runtime.js +47 -1
  56. package/src/commands/self-implement-loop.js +256 -0
  57. package/src/commands/session-guard.js +218 -0
  58. package/src/commands/sizing.js +165 -0
  59. package/src/commands/skill.js +65 -0
  60. package/src/commands/spec-checkpoint.js +177 -0
  61. package/src/commands/spec-status.js +79 -0
  62. package/src/commands/spec-sync.js +190 -0
  63. package/src/commands/spec-tasks.js +288 -0
  64. package/src/commands/squad-autorun.js +1220 -0
  65. package/src/commands/squad-bus.js +217 -0
  66. package/src/commands/squad-card.js +149 -0
  67. package/src/commands/squad-daemon.js +134 -0
  68. package/src/commands/squad-dependency-graph.js +164 -0
  69. package/src/commands/squad-review.js +106 -0
  70. package/src/commands/squad-scaffold.js +55 -0
  71. package/src/commands/squad-tool-register.js +157 -0
  72. package/src/commands/state-save.js +122 -0
  73. package/src/commands/update.js +2 -0
  74. package/src/commands/verify-gate.js +572 -0
  75. package/src/commands/workflow-execute.js +241 -0
  76. package/src/constants.js +22 -0
  77. package/src/install-profile.js +2 -2
  78. package/src/install-wizard.js +3 -2
  79. package/src/installer.js +6 -0
  80. package/src/lib/health-check.js +158 -0
  81. package/src/lib/hook-protocol.js +76 -0
  82. package/src/mcp/apps/squad-dashboard/app.js +163 -0
  83. package/src/mcp/apps/squad-dashboard/index.html +261 -0
  84. package/src/mcp/apps/squad-dashboard/mcp-manifest.json +23 -0
  85. package/src/mcp/resources/squad-state.js +130 -0
  86. package/src/preflight-engine.js +443 -0
  87. package/src/runner/cascade.js +97 -0
  88. package/src/runner/cli-launcher.js +109 -0
  89. package/src/runner/plan-importer.js +63 -0
  90. package/src/runner/queue-store.js +159 -0
  91. package/src/runtime-store.js +61 -3
  92. package/src/squad/agent-teams-adapter.js +264 -0
  93. package/src/squad/brief-validator.js +350 -0
  94. package/src/squad/bus-bridge.js +140 -0
  95. package/src/squad/context-compactor.js +265 -0
  96. package/src/squad/cross-ai-synthesizer.js +250 -0
  97. package/src/squad/hooks-generator.js +196 -0
  98. package/src/squad/inter-squad-events.js +175 -0
  99. package/src/squad/intra-bus.js +345 -0
  100. package/src/squad/learning-extractor.js +213 -0
  101. package/src/squad/pattern-detector.js +365 -0
  102. package/src/squad/preflight-context.js +296 -0
  103. package/src/squad/recovery-context.js +242 -71
  104. package/src/squad/reflection.js +365 -0
  105. package/src/squad/squad-scaffold.js +177 -0
  106. package/src/squad/state-manager.js +310 -0
  107. package/src/squad/task-decomposer.js +652 -0
  108. package/src/squad/verify-gate.js +303 -0
  109. package/src/updater.js +4 -5
  110. package/src/worker-runner.js +186 -1
  111. package/template/.aioson/agents/analyst.md +62 -1
  112. package/template/.aioson/agents/architect.md +61 -1
  113. package/template/.aioson/agents/copywriter.md +463 -0
  114. package/template/.aioson/agents/design-hybrid-forge.md +14 -0
  115. package/template/.aioson/agents/dev.md +271 -25
  116. package/template/.aioson/agents/deyvin.md +67 -8
  117. package/template/.aioson/agents/discovery-design-doc.md +44 -0
  118. package/template/.aioson/agents/genome.md +14 -0
  119. package/template/.aioson/agents/neo.md +83 -2
  120. package/template/.aioson/agents/orache.md +50 -4
  121. package/template/.aioson/agents/orchestrator.md +197 -1
  122. package/template/.aioson/agents/pm.md +35 -0
  123. package/template/.aioson/agents/product.md +50 -5
  124. package/template/.aioson/agents/profiler-enricher.md +14 -0
  125. package/template/.aioson/agents/profiler-forge.md +14 -0
  126. package/template/.aioson/agents/profiler-researcher.md +14 -0
  127. package/template/.aioson/agents/qa.md +273 -21
  128. package/template/.aioson/agents/setup.md +96 -10
  129. package/template/.aioson/agents/sheldon.md +131 -6
  130. package/template/.aioson/agents/site-forge.md +1753 -0
  131. package/template/.aioson/agents/squad.md +352 -0
  132. package/template/.aioson/agents/tester.md +53 -0
  133. package/template/.aioson/agents/ux-ui.md +203 -4
  134. package/template/.aioson/brains/README.md +128 -0
  135. package/template/.aioson/brains/_index.json +16 -0
  136. package/template/.aioson/brains/scripts/query.js +103 -0
  137. package/template/.aioson/brains/site-forge/visual-patterns.brain.json +205 -0
  138. package/template/.aioson/config.md +143 -13
  139. package/template/.aioson/constitution.md +33 -0
  140. package/template/.aioson/context/project-pulse.md +34 -0
  141. package/template/.aioson/docs/LAYERS.md +79 -0
  142. package/template/.aioson/docs/README.md +76 -0
  143. package/template/.aioson/docs/example-external-api-context.md +72 -0
  144. package/template/.aioson/genomes/copywriting.md +204 -0
  145. package/template/.aioson/locales/en/agents/architect.md +17 -0
  146. package/template/.aioson/locales/en/agents/dev.md +79 -13
  147. package/template/.aioson/locales/en/agents/orache.md +6 -0
  148. package/template/.aioson/locales/en/agents/orchestrator.md +24 -0
  149. package/template/.aioson/locales/en/agents/product.md +50 -0
  150. package/template/.aioson/locales/en/agents/sheldon.md +115 -0
  151. package/template/.aioson/locales/en/agents/squad.md +14 -0
  152. package/template/.aioson/locales/en/agents/tester.md +6 -0
  153. package/template/.aioson/locales/es/agents/analyst.md +2 -0
  154. package/template/.aioson/locales/es/agents/architect.md +19 -0
  155. package/template/.aioson/locales/es/agents/dev.md +64 -4
  156. package/template/.aioson/locales/es/agents/deyvin.md +2 -0
  157. package/template/.aioson/locales/es/agents/discovery-design-doc.md +2 -0
  158. package/template/.aioson/locales/es/agents/genome.md +2 -0
  159. package/template/.aioson/locales/es/agents/neo.md +2 -0
  160. package/template/.aioson/locales/es/agents/orache.md +2 -0
  161. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  162. package/template/.aioson/locales/es/agents/pair.md +2 -0
  163. package/template/.aioson/locales/es/agents/pm.md +2 -0
  164. package/template/.aioson/locales/es/agents/product.md +52 -0
  165. package/template/.aioson/locales/es/agents/profiler-enricher.md +2 -0
  166. package/template/.aioson/locales/es/agents/profiler-forge.md +2 -0
  167. package/template/.aioson/locales/es/agents/profiler-researcher.md +2 -0
  168. package/template/.aioson/locales/es/agents/qa.md +2 -0
  169. package/template/.aioson/locales/es/agents/setup.md +2 -0
  170. package/template/.aioson/locales/es/agents/sheldon.md +117 -0
  171. package/template/.aioson/locales/es/agents/squad.md +16 -0
  172. package/template/.aioson/locales/es/agents/tester.md +9 -0
  173. package/template/.aioson/locales/es/agents/ux-ui.md +2 -0
  174. package/template/.aioson/locales/fr/agents/analyst.md +2 -0
  175. package/template/.aioson/locales/fr/agents/architect.md +19 -0
  176. package/template/.aioson/locales/fr/agents/dev.md +64 -4
  177. package/template/.aioson/locales/fr/agents/deyvin.md +2 -0
  178. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +2 -0
  179. package/template/.aioson/locales/fr/agents/genome.md +2 -0
  180. package/template/.aioson/locales/fr/agents/neo.md +2 -0
  181. package/template/.aioson/locales/fr/agents/orache.md +2 -0
  182. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  183. package/template/.aioson/locales/fr/agents/pair.md +2 -0
  184. package/template/.aioson/locales/fr/agents/pm.md +2 -0
  185. package/template/.aioson/locales/fr/agents/product.md +52 -0
  186. package/template/.aioson/locales/fr/agents/profiler-enricher.md +2 -0
  187. package/template/.aioson/locales/fr/agents/profiler-forge.md +2 -0
  188. package/template/.aioson/locales/fr/agents/profiler-researcher.md +2 -0
  189. package/template/.aioson/locales/fr/agents/qa.md +2 -0
  190. package/template/.aioson/locales/fr/agents/setup.md +2 -0
  191. package/template/.aioson/locales/fr/agents/sheldon.md +117 -0
  192. package/template/.aioson/locales/fr/agents/squad.md +16 -0
  193. package/template/.aioson/locales/fr/agents/tester.md +9 -0
  194. package/template/.aioson/locales/fr/agents/ux-ui.md +2 -0
  195. package/template/.aioson/locales/pt-BR/agents/analyst.md +64 -3
  196. package/template/.aioson/locales/pt-BR/agents/architect.md +42 -0
  197. package/template/.aioson/locales/pt-BR/agents/dev.md +147 -14
  198. package/template/.aioson/locales/pt-BR/agents/deyvin.md +47 -0
  199. package/template/.aioson/locales/pt-BR/agents/neo.md +62 -1
  200. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +158 -2
  201. package/template/.aioson/locales/pt-BR/agents/pm.md +95 -1
  202. package/template/.aioson/locales/pt-BR/agents/product.md +145 -18
  203. package/template/.aioson/locales/pt-BR/agents/qa.md +16 -0
  204. package/template/.aioson/locales/pt-BR/agents/setup.md +101 -18
  205. package/template/.aioson/locales/pt-BR/agents/sheldon.md +132 -1
  206. package/template/.aioson/locales/pt-BR/agents/squad.md +14 -0
  207. package/template/.aioson/locales/pt-BR/agents/tester.md +449 -0
  208. package/template/.aioson/rules/README.md +69 -0
  209. package/template/.aioson/rules/data-format-convention.md +136 -0
  210. package/template/.aioson/rules/example-monetary-values.md +30 -0
  211. package/template/.aioson/schemas/squad-manifest.schema.json +124 -3
  212. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +2 -0
  213. package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -0
  214. package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +66 -0
  215. package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +368 -0
  216. package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -0
  217. package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -0
  218. package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -0
  219. package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +165 -0
  220. package/template/.aioson/skills/marketing/references/anti-patterns.md +254 -0
  221. package/template/.aioson/skills/marketing/references/fascinations.md +192 -0
  222. package/template/.aioson/skills/marketing/references/five-acts.md +248 -0
  223. package/template/.aioson/skills/marketing/references/market-intelligence.md +198 -0
  224. package/template/.aioson/skills/marketing/references/offer-structure.md +203 -0
  225. package/template/.aioson/skills/marketing/references/one-belief.md +149 -0
  226. package/template/.aioson/skills/marketing/references/patterns.md +218 -0
  227. package/template/.aioson/skills/marketing/references/pms-research.md +193 -0
  228. package/template/.aioson/skills/marketing/vsl-craft.md +385 -0
  229. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +1 -0
  230. package/template/.aioson/skills/process/aioson-spec-driven/references/analyst.md +30 -0
  231. package/template/.aioson/skills/process/aioson-spec-driven/references/architect.md +23 -0
  232. package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +47 -0
  233. package/template/.aioson/skills/process/aioson-spec-driven/references/deyvin.md +27 -0
  234. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +35 -0
  235. package/template/.aioson/skills/process/aioson-spec-driven/references/product.md +25 -0
  236. package/template/.aioson/skills/process/aioson-spec-driven/references/qa.md +30 -0
  237. package/template/.aioson/skills/process/aioson-spec-driven/references/sheldon.md +25 -0
  238. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +4 -1
  239. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +15 -0
  240. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +32 -0
  241. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +20 -0
  242. package/template/.aioson/skills/process/simplify/SKILL.md +173 -0
  243. package/template/.aioson/skills/static/context-budget-guide.md +46 -0
  244. package/template/.aioson/skills/static/harness-sensors.md +74 -0
  245. package/template/.aioson/skills/static/landing-page-deploy.md +192 -0
  246. package/template/.aioson/skills/static/landing-page-forge.md +730 -0
  247. package/template/.aioson/skills/static/multi-agent-patterns.md +43 -0
  248. package/template/.aioson/skills/static/react-motion-patterns.md +22 -0
  249. package/template/.aioson/skills/static/static-html-patterns/checklists.md +43 -0
  250. package/template/.aioson/skills/static/static-html-patterns/css-tokens.md +609 -0
  251. package/template/.aioson/skills/static/static-html-patterns/motion.md +193 -0
  252. package/template/.aioson/skills/static/static-html-patterns/premium.md +711 -0
  253. package/template/.aioson/skills/static/static-html-patterns/structure.md +209 -0
  254. package/template/.aioson/skills/static/static-html-patterns/utilities.md +190 -0
  255. package/template/.aioson/skills/static/static-html-patterns.md +58 -1913
  256. package/template/.aioson/skills/static/threejs-patterns.md +929 -0
  257. package/template/.aioson/skills/static/ui-ux-modern.md +1 -0
  258. package/template/.aioson/skills/static/web-research-cache.md +112 -0
  259. package/template/.aioson/tasks/implementation-plan.md +21 -1
  260. package/template/.aioson/tasks/squad-create.md +22 -0
  261. package/template/.aioson/tasks/squad-design.md +30 -0
  262. package/template/.aioson/templates/squads/digital-marketing-agency/template.json +96 -0
  263. package/template/.claude/commands/aioson/agent/design-hybrid-forge.md +5 -0
  264. package/template/.claude/commands/aioson/agent/orache.md +5 -0
  265. package/template/.claude/commands/aioson/agent/sheldon.md +5 -0
  266. package/template/.claude/commands/aioson/agent/site-forge.md +5 -0
  267. package/template/AGENTS.md +55 -3
  268. package/template/CLAUDE.md +31 -0
  269. package/template/OPENCODE.md +4 -0
  270. package/template/researchs/.gitkeep +0 -0
  271. package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
  272. package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
  273. package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
  274. package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
  275. package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
@@ -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
+ };
@@ -590,6 +590,32 @@ async function openRuntimeDb(targetDir, options = {}) {
590
590
  created_at TEXT DEFAULT (datetime('now')),
591
591
  updated_at TEXT DEFAULT (datetime('now'))
592
592
  );
593
+
594
+ CREATE TABLE IF NOT EXISTS dynamic_squad_tools (
595
+ name TEXT NOT NULL,
596
+ squad_slug TEXT NOT NULL,
597
+ description TEXT NOT NULL,
598
+ input_schema TEXT NOT NULL DEFAULT '{}',
599
+ handler_type TEXT NOT NULL DEFAULT 'shell',
600
+ handler_code TEXT,
601
+ handler_path TEXT,
602
+ registered_at TEXT NOT NULL,
603
+ registered_by TEXT,
604
+ PRIMARY KEY (name, squad_slug)
605
+ );
606
+ CREATE INDEX IF NOT EXISTS idx_dynamic_squad_tools_squad ON dynamic_squad_tools(squad_slug);
607
+
608
+ CREATE TABLE IF NOT EXISTS inter_squad_events (
609
+ id TEXT PRIMARY KEY,
610
+ from_squad TEXT NOT NULL,
611
+ event TEXT NOT NULL,
612
+ payload TEXT,
613
+ created_at TEXT NOT NULL,
614
+ consumed_by TEXT NOT NULL DEFAULT '[]',
615
+ ttl_hours INTEGER NOT NULL DEFAULT 48
616
+ );
617
+ CREATE INDEX IF NOT EXISTS idx_inter_squad_events_from ON inter_squad_events(from_squad, created_at DESC);
618
+ CREATE INDEX IF NOT EXISTS idx_inter_squad_events_event ON inter_squad_events(event, created_at DESC);
593
619
  `);
594
620
 
595
621
  ensureLegacyColumns(db);
@@ -694,6 +720,31 @@ function ensureLegacyColumns(db) {
694
720
 
695
721
  try { db.exec('ALTER TABLE worker_runs ADD COLUMN conversation_id TEXT'); } catch { /* já existe */ }
696
722
 
723
+ // Event Enrichment (Plan 61) — new columns in execution_events
724
+ const execEventColumns = db.prepare('PRAGMA table_info(execution_events)').all();
725
+ const execEventColumnNames = new Set(execEventColumns.map((col) => col.name));
726
+
727
+ if (!execEventColumnNames.has('plan_step_id')) {
728
+ db.exec('ALTER TABLE execution_events ADD COLUMN plan_step_id TEXT');
729
+ }
730
+ if (!execEventColumnNames.has('worker_status')) {
731
+ db.exec('ALTER TABLE execution_events ADD COLUMN worker_status TEXT');
732
+ }
733
+ if (!execEventColumnNames.has('verdict')) {
734
+ db.exec('ALTER TABLE execution_events ADD COLUMN verdict TEXT');
735
+ }
736
+ if (!execEventColumnNames.has('token_count')) {
737
+ db.exec('ALTER TABLE execution_events ADD COLUMN token_count INTEGER');
738
+ }
739
+ if (!execEventColumnNames.has('progress_pct')) {
740
+ db.exec('ALTER TABLE execution_events ADD COLUMN progress_pct REAL');
741
+ }
742
+
743
+ db.exec('CREATE INDEX IF NOT EXISTS idx_execution_events_agent_type ON execution_events(agent_name, event_type, created_at DESC)');
744
+ db.exec('CREATE INDEX IF NOT EXISTS idx_execution_events_verdict ON execution_events(verdict, created_at DESC)');
745
+ db.exec('CREATE INDEX IF NOT EXISTS idx_plan_phases_status ON plan_phases(plan_id, status)');
746
+ db.exec('CREATE INDEX IF NOT EXISTS idx_artifacts_run ON artifacts(run_key, created_at DESC)');
747
+
697
748
  // Dynamic Tools (Feature: Tool Registry)
698
749
  db.exec(`
699
750
  CREATE TABLE IF NOT EXISTS dynamic_tools (
@@ -767,12 +818,14 @@ function insertExecutionEvent(db, record) {
767
818
  task_key, run_key, agent_name, agent_kind, squad_slug, session_key,
768
819
  source, workflow_id, workflow_stage, parent_run_key,
769
820
  event_type, phase, status, tool_name, message, payload_json,
770
- sequence_no, parent_event_id, created_at
821
+ sequence_no, parent_event_id, created_at,
822
+ plan_step_id, worker_status, verdict, token_count, progress_pct
771
823
  ) VALUES (
772
824
  @task_key, @run_key, @agent_name, @agent_kind, @squad_slug, @session_key,
773
825
  @source, @workflow_id, @workflow_stage, @parent_run_key,
774
826
  @event_type, @phase, @status, @tool_name, @message, @payload_json,
775
- @sequence_no, @parent_event_id, @created_at
827
+ @sequence_no, @parent_event_id, @created_at,
828
+ @plan_step_id, @worker_status, @verdict, @token_count, @progress_pct
776
829
  )
777
830
  `).run(record);
778
831
  }
@@ -814,7 +867,12 @@ function appendRunEvent(db, options) {
814
867
  payload_json: payloadJson,
815
868
  sequence_no: nextExecutionSequence(db, run.run_key),
816
869
  parent_event_id: options.parentEventId || null,
817
- created_at: now
870
+ created_at: now,
871
+ plan_step_id: options.planStepId ? String(options.planStepId).trim() : null,
872
+ worker_status: options.workerStatus ? String(options.workerStatus).trim() : null,
873
+ verdict: options.verdict ? String(options.verdict).trim().toUpperCase() : null,
874
+ token_count: options.tokenCount != null ? Number(options.tokenCount) || null : null,
875
+ progress_pct: options.progressPct != null ? Number(options.progressPct) || null : null
818
876
  });
819
877
  });
820
878
 
@@ -0,0 +1,264 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Agent Teams Adapter — Plan 81, Phase 1.1
5
+ *
6
+ * Translates squad manifests into Claude Code Agent Teams configurations.
7
+ * Enables squads to execute via native Agent Teams parallelism instead of
8
+ * manual Promise.all of subprocesses.
9
+ *
10
+ * Mapping:
11
+ * executors[].slug → teammates[].name
12
+ * executors[].type → teammates[].subagent definition
13
+ * tasks[].wave → tasks[].dependencies
14
+ * tasks[].must_haves → tasks[].acceptance_criteria
15
+ * budget.max_tokens_per_task → per-teammate token limits
16
+ * intra-bus messages → shared mailbox messages
17
+ *
18
+ * Fallback: if Agent Teams is not available (Claude Code < v2.1.32),
19
+ * returns { available: false } and caller falls back to legacy engine.
20
+ */
21
+
22
+ const { execSync } = require('node:child_process');
23
+ const fs = require('node:fs/promises');
24
+ const path = require('node:path');
25
+
26
+ const SQUADS_DIR = path.join('.aioson', 'squads');
27
+
28
+ // ─── Availability detection ──────────────────────────────────────────────────
29
+
30
+ /**
31
+ * Detect if Claude Code Agent Teams is available.
32
+ * Checks for claude binary and version >= 2.1.32.
33
+ */
34
+ function detectAgentTeams() {
35
+ try {
36
+ const versionOutput = execSync('claude --version 2>/dev/null', {
37
+ encoding: 'utf8',
38
+ timeout: 5000
39
+ }).trim();
40
+
41
+ const match = versionOutput.match(/(\d+)\.(\d+)\.(\d+)/);
42
+ if (!match) return { available: false, reason: 'version_parse_error', raw: versionOutput };
43
+
44
+ const [, major, minor, patch] = match.map(Number);
45
+ const version = `${major}.${minor}.${patch}`;
46
+
47
+ // Agent Teams requires v2.1.32+
48
+ const meetsMinimum =
49
+ major > 2 ||
50
+ (major === 2 && minor > 1) ||
51
+ (major === 2 && minor === 1 && patch >= 32);
52
+
53
+ return {
54
+ available: meetsMinimum,
55
+ version,
56
+ reason: meetsMinimum ? 'ok' : 'version_too_old'
57
+ };
58
+ } catch {
59
+ return { available: false, reason: 'claude_not_found' };
60
+ }
61
+ }
62
+
63
+ // ─── Manifest to Team Config translation ─────────────────────────────────────
64
+
65
+ /**
66
+ * Build a teammate definition from a squad executor.
67
+ */
68
+ function executorToTeammate(executor, squadSlug, projectDir) {
69
+ const agentFile = executor.file
70
+ ? path.join(projectDir, executor.file)
71
+ : path.join(projectDir, SQUADS_DIR, squadSlug, 'agents', `${executor.slug}.md`);
72
+
73
+ const teammate = {
74
+ name: executor.slug,
75
+ role: executor.role || executor.title || executor.slug,
76
+ type: mapExecutorType(executor.type),
77
+ agentFile: agentFile
78
+ };
79
+
80
+ // Model tier mapping
81
+ if (executor.modelTier) {
82
+ const tierMap = {
83
+ powerful: 'opus',
84
+ balanced: 'sonnet',
85
+ fast: 'haiku',
86
+ none: null
87
+ };
88
+ teammate.model = tierMap[executor.modelTier] || 'sonnet';
89
+ }
90
+
91
+ // Skills
92
+ if (executor.skills && executor.skills.length > 0) {
93
+ teammate.skills = executor.skills;
94
+ }
95
+
96
+ return teammate;
97
+ }
98
+
99
+ /**
100
+ * Map AIOSON executor type to Agent Teams teammate type.
101
+ */
102
+ function mapExecutorType(type) {
103
+ const typeMap = {
104
+ agent: 'subagent',
105
+ worker: 'worker',
106
+ clone: 'subagent',
107
+ assistant: 'subagent',
108
+ 'human-gate': 'gate',
109
+ research: 'research',
110
+ reviewer: 'subagent',
111
+ skill: 'skill'
112
+ };
113
+ return typeMap[type] || 'subagent';
114
+ }
115
+
116
+ /**
117
+ * Convert a task decomposition plan to Agent Teams task list.
118
+ */
119
+ function planToTeamTasks(plan, executors) {
120
+ const tasks = [];
121
+
122
+ for (const task of plan.tasks) {
123
+ const teamTask = {
124
+ id: task.id,
125
+ title: task.title,
126
+ description: task.description,
127
+ assignTo: task.executor || null,
128
+ dependencies: task.dependencies || [],
129
+ acceptance_criteria: task.acceptance_criteria || [],
130
+ priority: task.priority || 0,
131
+ metadata: {}
132
+ };
133
+
134
+ // Map must_haves to structured acceptance criteria
135
+ if (task.must_haves) {
136
+ if (task.must_haves.artifacts) {
137
+ teamTask.acceptance_criteria.push(
138
+ ...task.must_haves.artifacts.map((a) => `Artifact exists: ${a}`)
139
+ );
140
+ }
141
+ if (task.must_haves.key_links) {
142
+ teamTask.acceptance_criteria.push(
143
+ ...task.must_haves.key_links.map((l) => `Wired: ${l}`)
144
+ );
145
+ }
146
+ }
147
+
148
+ // read_first_hints become context for the teammate
149
+ if (task.read_first_hints && task.read_first_hints.length > 0) {
150
+ teamTask.metadata.read_first = task.read_first_hints;
151
+ }
152
+
153
+ tasks.push(teamTask);
154
+ }
155
+
156
+ return tasks;
157
+ }
158
+
159
+ /**
160
+ * Translate a full squad manifest + plan into an Agent Teams configuration.
161
+ *
162
+ * @param {string} projectDir
163
+ * @param {object} manifest — squad.manifest.json contents
164
+ * @param {object} plan — decomposed task plan
165
+ * @param {object} [options] — { budget, enableBus }
166
+ * @returns {object} — Agent Teams config
167
+ */
168
+ function translateToTeamConfig(projectDir, manifest, plan, options = {}) {
169
+ const { budget = {} } = options;
170
+ const executors = manifest.executors || [];
171
+
172
+ // Build teammates
173
+ const teammates = executors.map((e) =>
174
+ executorToTeammate(e, manifest.slug, projectDir)
175
+ );
176
+
177
+ // Build tasks
178
+ const tasks = planToTeamTasks(plan, executors);
179
+
180
+ // Team configuration
181
+ const teamConfig = {
182
+ name: `squad-${manifest.slug}`,
183
+ description: manifest.mission || manifest.goal || `Squad: ${manifest.name}`,
184
+ teammates,
185
+ tasks,
186
+ settings: {
187
+ parallel: true,
188
+ maxConcurrent: teammates.length,
189
+ taskTimeout: budget.max_tokens_per_task ? Math.ceil(budget.max_tokens_per_task / 100) : 300,
190
+ quality: {
191
+ verifyOnComplete: true,
192
+ blockOnFail: true
193
+ }
194
+ }
195
+ };
196
+
197
+ // Budget constraints
198
+ if (budget.max_tokens_per_session) {
199
+ teamConfig.settings.tokenBudget = budget.max_tokens_per_session;
200
+ }
201
+ if (budget.max_tokens_per_task) {
202
+ teamConfig.settings.perTaskTokenLimit = budget.max_tokens_per_task;
203
+ }
204
+
205
+ // Anti-loop settings
206
+ if (manifest.anti_loop) {
207
+ teamConfig.settings.antiLoop = {
208
+ threshold: manifest.anti_loop.threshold || 8,
209
+ action: manifest.anti_loop.action || 'feedback'
210
+ };
211
+ }
212
+
213
+ return teamConfig;
214
+ }
215
+
216
+ /**
217
+ * Write Agent Teams config to a JSON file for claude --team usage.
218
+ */
219
+ async function writeTeamConfig(projectDir, squadSlug, teamConfig) {
220
+ const configDir = path.join(projectDir, '.aioson', 'squads', squadSlug, 'team-config');
221
+ await fs.mkdir(configDir, { recursive: true });
222
+
223
+ const configPath = path.join(configDir, 'team.json');
224
+ await fs.writeFile(configPath, JSON.stringify(teamConfig, null, 2), 'utf8');
225
+
226
+ return configPath;
227
+ }
228
+
229
+ /**
230
+ * Resolve the execution engine for a squad:autorun run.
231
+ * Returns 'agent-teams' if requested and available, otherwise 'legacy'.
232
+ */
233
+ function resolveEngine(requestedEngine) {
234
+ if (requestedEngine === 'legacy') return { engine: 'legacy', reason: 'explicit' };
235
+
236
+ if (requestedEngine === 'agent-teams') {
237
+ const detection = detectAgentTeams();
238
+ if (detection.available) {
239
+ return { engine: 'agent-teams', version: detection.version, reason: 'explicit' };
240
+ }
241
+ return { engine: 'legacy', reason: `agent-teams requested but ${detection.reason}`, fallback: true };
242
+ }
243
+
244
+ // Auto-detect
245
+ if (requestedEngine === 'auto') {
246
+ const detection = detectAgentTeams();
247
+ if (detection.available) {
248
+ return { engine: 'agent-teams', version: detection.version, reason: 'auto-detected' };
249
+ }
250
+ return { engine: 'legacy', reason: 'auto-fallback' };
251
+ }
252
+
253
+ return { engine: 'legacy', reason: 'default' };
254
+ }
255
+
256
+ module.exports = {
257
+ detectAgentTeams,
258
+ translateToTeamConfig,
259
+ writeTeamConfig,
260
+ resolveEngine,
261
+ executorToTeammate,
262
+ planToTeamTasks,
263
+ mapExecutorType
264
+ };