@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.
- package/CHANGELOG.md +74 -0
- package/README.md +729 -232
- package/docs/design-previews/pt.squarespace.com-homepage.html +889 -0
- package/docs/integrations/sdlc-genius-boundary.md +76 -0
- package/docs/integrations/sdlc-genius-eval-matrix.md +75 -0
- package/docs/integrations/sdlc-genius-install-checklist.md +93 -0
- package/docs/integrations/sdlc-genius-review-samples.md +86 -0
- package/docs/pt/README.md +3 -0
- package/docs/pt/agentes.md +1 -0
- package/docs/pt/comandos-cli.md +888 -2
- package/docs/pt/design-hybrid-forge.md +255 -6
- package/docs/pt/devlog-pipeline.md +270 -0
- package/docs/pt/fluxo-artefatos.md +178 -0
- package/docs/pt/hooks-session-guard.md +454 -0
- package/docs/pt/monitor-de-contexto.md +59 -5
- package/docs/pt/sdd-automation-scripts.md +557 -0
- package/docs/pt/site-forge.md +309 -0
- package/docs/pt/spec-learnings-pipeline.md +265 -0
- package/package.json +1 -1
- package/src/a2a/client.js +165 -0
- package/src/a2a/server.js +223 -0
- package/src/cli.js +235 -1
- package/src/commands/agent-audit.js +397 -0
- package/src/commands/agent-export-skill.js +229 -0
- package/src/commands/artifact-validate.js +189 -0
- package/src/commands/brief-gen.js +405 -0
- package/src/commands/brief-validate.js +65 -0
- package/src/commands/classify.js +256 -0
- package/src/commands/context-compact.js +49 -0
- package/src/commands/context-health.js +175 -0
- package/src/commands/context-monitor.js +71 -0
- package/src/commands/context-trim.js +177 -0
- package/src/commands/detect-test-runner.js +55 -0
- package/src/commands/devlog-export-brains.js +27 -0
- package/src/commands/devlog-process.js +292 -0
- package/src/commands/devlog-watch.js +131 -0
- package/src/commands/feature-close.js +165 -0
- package/src/commands/gate-check.js +228 -0
- package/src/commands/hooks-emit.js +253 -0
- package/src/commands/hooks-install.js +347 -0
- package/src/commands/learning-auto-promote.js +195 -0
- package/src/commands/learning-evolve.js +18 -9
- package/src/commands/learning-export.js +103 -0
- package/src/commands/learning-rollback.js +164 -0
- package/src/commands/live.js +25 -1
- package/src/commands/pattern-detect.js +33 -0
- package/src/commands/preflight-context.js +30 -0
- package/src/commands/preflight.js +208 -0
- package/src/commands/pulse-update.js +130 -0
- package/src/commands/runner-daemon.js +274 -0
- package/src/commands/runner-plan.js +70 -0
- package/src/commands/runner-queue-from-plan.js +166 -0
- package/src/commands/runner-queue.js +189 -0
- package/src/commands/runner-run.js +129 -0
- package/src/commands/runtime.js +47 -1
- package/src/commands/self-implement-loop.js +256 -0
- package/src/commands/session-guard.js +218 -0
- package/src/commands/sizing.js +165 -0
- package/src/commands/skill.js +65 -0
- package/src/commands/spec-checkpoint.js +177 -0
- package/src/commands/spec-status.js +79 -0
- package/src/commands/spec-sync.js +190 -0
- package/src/commands/spec-tasks.js +288 -0
- package/src/commands/squad-autorun.js +1220 -0
- package/src/commands/squad-bus.js +217 -0
- package/src/commands/squad-card.js +149 -0
- package/src/commands/squad-daemon.js +134 -0
- package/src/commands/squad-dependency-graph.js +164 -0
- package/src/commands/squad-review.js +106 -0
- package/src/commands/squad-scaffold.js +55 -0
- package/src/commands/squad-tool-register.js +157 -0
- package/src/commands/state-save.js +122 -0
- package/src/commands/update.js +2 -0
- package/src/commands/verify-gate.js +572 -0
- package/src/commands/workflow-execute.js +241 -0
- package/src/constants.js +22 -0
- package/src/install-profile.js +2 -2
- package/src/install-wizard.js +3 -2
- package/src/installer.js +6 -0
- package/src/lib/health-check.js +158 -0
- package/src/lib/hook-protocol.js +76 -0
- package/src/mcp/apps/squad-dashboard/app.js +163 -0
- package/src/mcp/apps/squad-dashboard/index.html +261 -0
- package/src/mcp/apps/squad-dashboard/mcp-manifest.json +23 -0
- package/src/mcp/resources/squad-state.js +130 -0
- package/src/preflight-engine.js +443 -0
- package/src/runner/cascade.js +97 -0
- package/src/runner/cli-launcher.js +109 -0
- package/src/runner/plan-importer.js +63 -0
- package/src/runner/queue-store.js +159 -0
- package/src/runtime-store.js +61 -3
- package/src/squad/agent-teams-adapter.js +264 -0
- package/src/squad/brief-validator.js +350 -0
- package/src/squad/bus-bridge.js +140 -0
- package/src/squad/context-compactor.js +265 -0
- package/src/squad/cross-ai-synthesizer.js +250 -0
- package/src/squad/hooks-generator.js +196 -0
- package/src/squad/inter-squad-events.js +175 -0
- package/src/squad/intra-bus.js +345 -0
- package/src/squad/learning-extractor.js +213 -0
- package/src/squad/pattern-detector.js +365 -0
- package/src/squad/preflight-context.js +296 -0
- package/src/squad/recovery-context.js +242 -71
- package/src/squad/reflection.js +365 -0
- package/src/squad/squad-scaffold.js +177 -0
- package/src/squad/state-manager.js +310 -0
- package/src/squad/task-decomposer.js +652 -0
- package/src/squad/verify-gate.js +303 -0
- package/src/updater.js +4 -5
- package/src/worker-runner.js +186 -1
- package/template/.aioson/agents/analyst.md +62 -1
- package/template/.aioson/agents/architect.md +61 -1
- package/template/.aioson/agents/copywriter.md +463 -0
- package/template/.aioson/agents/design-hybrid-forge.md +14 -0
- package/template/.aioson/agents/dev.md +271 -25
- package/template/.aioson/agents/deyvin.md +67 -8
- package/template/.aioson/agents/discovery-design-doc.md +44 -0
- package/template/.aioson/agents/genome.md +14 -0
- package/template/.aioson/agents/neo.md +83 -2
- package/template/.aioson/agents/orache.md +50 -4
- package/template/.aioson/agents/orchestrator.md +197 -1
- package/template/.aioson/agents/pm.md +35 -0
- package/template/.aioson/agents/product.md +50 -5
- package/template/.aioson/agents/profiler-enricher.md +14 -0
- package/template/.aioson/agents/profiler-forge.md +14 -0
- package/template/.aioson/agents/profiler-researcher.md +14 -0
- package/template/.aioson/agents/qa.md +273 -21
- package/template/.aioson/agents/setup.md +96 -10
- package/template/.aioson/agents/sheldon.md +131 -6
- package/template/.aioson/agents/site-forge.md +1753 -0
- package/template/.aioson/agents/squad.md +352 -0
- package/template/.aioson/agents/tester.md +53 -0
- package/template/.aioson/agents/ux-ui.md +203 -4
- package/template/.aioson/brains/README.md +128 -0
- package/template/.aioson/brains/_index.json +16 -0
- package/template/.aioson/brains/scripts/query.js +103 -0
- package/template/.aioson/brains/site-forge/visual-patterns.brain.json +205 -0
- package/template/.aioson/config.md +143 -13
- package/template/.aioson/constitution.md +33 -0
- package/template/.aioson/context/project-pulse.md +34 -0
- package/template/.aioson/docs/LAYERS.md +79 -0
- package/template/.aioson/docs/README.md +76 -0
- package/template/.aioson/docs/example-external-api-context.md +72 -0
- package/template/.aioson/genomes/copywriting.md +204 -0
- package/template/.aioson/locales/en/agents/architect.md +17 -0
- package/template/.aioson/locales/en/agents/dev.md +79 -13
- package/template/.aioson/locales/en/agents/orache.md +6 -0
- package/template/.aioson/locales/en/agents/orchestrator.md +24 -0
- package/template/.aioson/locales/en/agents/product.md +50 -0
- package/template/.aioson/locales/en/agents/sheldon.md +115 -0
- package/template/.aioson/locales/en/agents/squad.md +14 -0
- package/template/.aioson/locales/en/agents/tester.md +6 -0
- package/template/.aioson/locales/es/agents/analyst.md +2 -0
- package/template/.aioson/locales/es/agents/architect.md +19 -0
- package/template/.aioson/locales/es/agents/dev.md +64 -4
- package/template/.aioson/locales/es/agents/deyvin.md +2 -0
- package/template/.aioson/locales/es/agents/discovery-design-doc.md +2 -0
- package/template/.aioson/locales/es/agents/genome.md +2 -0
- package/template/.aioson/locales/es/agents/neo.md +2 -0
- package/template/.aioson/locales/es/agents/orache.md +2 -0
- package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/es/agents/pair.md +2 -0
- package/template/.aioson/locales/es/agents/pm.md +2 -0
- package/template/.aioson/locales/es/agents/product.md +52 -0
- package/template/.aioson/locales/es/agents/profiler-enricher.md +2 -0
- package/template/.aioson/locales/es/agents/profiler-forge.md +2 -0
- package/template/.aioson/locales/es/agents/profiler-researcher.md +2 -0
- package/template/.aioson/locales/es/agents/qa.md +2 -0
- package/template/.aioson/locales/es/agents/setup.md +2 -0
- package/template/.aioson/locales/es/agents/sheldon.md +117 -0
- package/template/.aioson/locales/es/agents/squad.md +16 -0
- package/template/.aioson/locales/es/agents/tester.md +9 -0
- package/template/.aioson/locales/es/agents/ux-ui.md +2 -0
- package/template/.aioson/locales/fr/agents/analyst.md +2 -0
- package/template/.aioson/locales/fr/agents/architect.md +19 -0
- package/template/.aioson/locales/fr/agents/dev.md +64 -4
- package/template/.aioson/locales/fr/agents/deyvin.md +2 -0
- package/template/.aioson/locales/fr/agents/discovery-design-doc.md +2 -0
- package/template/.aioson/locales/fr/agents/genome.md +2 -0
- package/template/.aioson/locales/fr/agents/neo.md +2 -0
- package/template/.aioson/locales/fr/agents/orache.md +2 -0
- package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
- package/template/.aioson/locales/fr/agents/pair.md +2 -0
- package/template/.aioson/locales/fr/agents/pm.md +2 -0
- package/template/.aioson/locales/fr/agents/product.md +52 -0
- package/template/.aioson/locales/fr/agents/profiler-enricher.md +2 -0
- package/template/.aioson/locales/fr/agents/profiler-forge.md +2 -0
- package/template/.aioson/locales/fr/agents/profiler-researcher.md +2 -0
- package/template/.aioson/locales/fr/agents/qa.md +2 -0
- package/template/.aioson/locales/fr/agents/setup.md +2 -0
- package/template/.aioson/locales/fr/agents/sheldon.md +117 -0
- package/template/.aioson/locales/fr/agents/squad.md +16 -0
- package/template/.aioson/locales/fr/agents/tester.md +9 -0
- package/template/.aioson/locales/fr/agents/ux-ui.md +2 -0
- package/template/.aioson/locales/pt-BR/agents/analyst.md +64 -3
- package/template/.aioson/locales/pt-BR/agents/architect.md +42 -0
- package/template/.aioson/locales/pt-BR/agents/dev.md +147 -14
- package/template/.aioson/locales/pt-BR/agents/deyvin.md +47 -0
- package/template/.aioson/locales/pt-BR/agents/neo.md +62 -1
- package/template/.aioson/locales/pt-BR/agents/orchestrator.md +158 -2
- package/template/.aioson/locales/pt-BR/agents/pm.md +95 -1
- package/template/.aioson/locales/pt-BR/agents/product.md +145 -18
- package/template/.aioson/locales/pt-BR/agents/qa.md +16 -0
- package/template/.aioson/locales/pt-BR/agents/setup.md +101 -18
- package/template/.aioson/locales/pt-BR/agents/sheldon.md +132 -1
- package/template/.aioson/locales/pt-BR/agents/squad.md +14 -0
- package/template/.aioson/locales/pt-BR/agents/tester.md +449 -0
- package/template/.aioson/rules/README.md +69 -0
- package/template/.aioson/rules/data-format-convention.md +136 -0
- package/template/.aioson/rules/example-monetary-values.md +30 -0
- package/template/.aioson/schemas/squad-manifest.schema.json +124 -3
- package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +2 -0
- package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -0
- package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +66 -0
- package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +368 -0
- package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -0
- package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -0
- package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -0
- package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +165 -0
- package/template/.aioson/skills/marketing/references/anti-patterns.md +254 -0
- package/template/.aioson/skills/marketing/references/fascinations.md +192 -0
- package/template/.aioson/skills/marketing/references/five-acts.md +248 -0
- package/template/.aioson/skills/marketing/references/market-intelligence.md +198 -0
- package/template/.aioson/skills/marketing/references/offer-structure.md +203 -0
- package/template/.aioson/skills/marketing/references/one-belief.md +149 -0
- package/template/.aioson/skills/marketing/references/patterns.md +218 -0
- package/template/.aioson/skills/marketing/references/pms-research.md +193 -0
- package/template/.aioson/skills/marketing/vsl-craft.md +385 -0
- package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +1 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/analyst.md +30 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/architect.md +23 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +47 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/deyvin.md +27 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +35 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/product.md +25 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/qa.md +30 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/sheldon.md +25 -0
- package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +4 -1
- package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +15 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +32 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +20 -0
- package/template/.aioson/skills/process/simplify/SKILL.md +173 -0
- package/template/.aioson/skills/static/context-budget-guide.md +46 -0
- package/template/.aioson/skills/static/harness-sensors.md +74 -0
- package/template/.aioson/skills/static/landing-page-deploy.md +192 -0
- package/template/.aioson/skills/static/landing-page-forge.md +730 -0
- package/template/.aioson/skills/static/multi-agent-patterns.md +43 -0
- package/template/.aioson/skills/static/react-motion-patterns.md +22 -0
- package/template/.aioson/skills/static/static-html-patterns/checklists.md +43 -0
- package/template/.aioson/skills/static/static-html-patterns/css-tokens.md +609 -0
- package/template/.aioson/skills/static/static-html-patterns/motion.md +193 -0
- package/template/.aioson/skills/static/static-html-patterns/premium.md +711 -0
- package/template/.aioson/skills/static/static-html-patterns/structure.md +209 -0
- package/template/.aioson/skills/static/static-html-patterns/utilities.md +190 -0
- package/template/.aioson/skills/static/static-html-patterns.md +58 -1913
- package/template/.aioson/skills/static/threejs-patterns.md +929 -0
- package/template/.aioson/skills/static/ui-ux-modern.md +1 -0
- package/template/.aioson/skills/static/web-research-cache.md +112 -0
- package/template/.aioson/tasks/implementation-plan.md +21 -1
- package/template/.aioson/tasks/squad-create.md +22 -0
- package/template/.aioson/tasks/squad-design.md +30 -0
- package/template/.aioson/templates/squads/digital-marketing-agency/template.json +96 -0
- package/template/.claude/commands/aioson/agent/design-hybrid-forge.md +5 -0
- package/template/.claude/commands/aioson/agent/orache.md +5 -0
- package/template/.claude/commands/aioson/agent/sheldon.md +5 -0
- package/template/.claude/commands/aioson/agent/site-forge.md +5 -0
- package/template/AGENTS.md +55 -3
- package/template/CLAUDE.md +31 -0
- package/template/OPENCODE.md +4 -0
- package/template/researchs/.gitkeep +0 -0
- package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
- package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
- 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
|
+
};
|
package/src/runtime-store.js
CHANGED
|
@@ -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
|
+
};
|