@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.
- package/CHANGELOG.md +49 -0
- package/README.md +729 -226
- package/docs/design-previews/aurora-command-ui-website.html +884 -0
- package/docs/design-previews/aurora-command-ui.html +682 -0
- package/docs/design-previews/bold-editorial-ui-website.html +658 -0
- package/docs/design-previews/bold-editorial-ui.html +717 -0
- package/docs/design-previews/clean-saas-ui-website.html +1202 -0
- package/docs/design-previews/clean-saas-ui.html +549 -0
- package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
- package/docs/design-previews/cognitive-core-ui.html +463 -0
- package/docs/design-previews/glassmorphism-ui-website.html +572 -0
- package/docs/design-previews/glassmorphism-ui.html +886 -0
- package/docs/design-previews/index.html +699 -0
- package/docs/design-previews/interface-design-website.html +1187 -0
- package/docs/design-previews/interface-design.html +513 -0
- package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
- package/docs/design-previews/neo-brutalist-ui.html +797 -0
- package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
- package/docs/design-previews/premium-command-center-ui.html +552 -0
- package/docs/design-previews/pt.squarespace.com-homepage.html +889 -0
- package/docs/design-previews/warm-craft-ui-website.html +684 -0
- package/docs/design-previews/warm-craft-ui.html +739 -0
- package/docs/en/cli-reference.md +20 -9
- 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 +10 -0
- package/docs/pt/agent-sharding.md +132 -0
- package/docs/pt/agentes.md +9 -2
- package/docs/pt/busca-de-contexto.md +129 -0
- package/docs/pt/cache-de-contexto.md +156 -0
- package/docs/pt/comandos-cli.md +915 -1
- package/docs/pt/design-hybrid-forge.md +356 -0
- 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/inicio-rapido.md +54 -3
- package/docs/pt/inteligencia-adaptativa.md +324 -0
- package/docs/pt/monitor-de-contexto.md +158 -0
- package/docs/pt/recuperacao-de-sessao.md +125 -0
- package/docs/pt/sandbox.md +125 -0
- package/docs/pt/sdd-automation-scripts.md +557 -0
- package/docs/pt/site-forge.md +309 -0
- package/docs/pt/skills.md +98 -6
- 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/agent-loader.js +280 -0
- package/src/cli.js +329 -1
- package/src/commands/agent-audit.js +397 -0
- package/src/commands/agent-export-skill.js +229 -0
- package/src/commands/agent-loader.js +85 -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-cache.js +90 -0
- package/src/commands/context-compact.js +49 -0
- package/src/commands/context-health.js +175 -0
- package/src/commands/context-monitor.js +163 -0
- package/src/commands/context-search.js +66 -0
- package/src/commands/context-trim.js +177 -0
- package/src/commands/design-hybrid-options.js +385 -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/health.js +214 -0
- package/src/commands/hooks-emit.js +253 -0
- package/src/commands/hooks-install.js +347 -0
- package/src/commands/init.js +54 -13
- package/src/commands/install.js +52 -13
- package/src/commands/learning-auto-promote.js +195 -0
- package/src/commands/learning-evolve.js +364 -0
- package/src/commands/learning-export.js +103 -0
- package/src/commands/learning-rollback.js +164 -0
- package/src/commands/live.js +59 -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/recovery.js +43 -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/sandbox.js +37 -0
- package/src/commands/self-implement-loop.js +256 -0
- package/src/commands/session-guard.js +218 -0
- package/src/commands/setup-context.js +22 -2
- package/src/commands/setup.js +178 -0
- package/src/commands/sizing.js +165 -0
- package/src/commands/skill.js +144 -32
- 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/tool-registry-cmd.js +232 -0
- package/src/commands/update.js +9 -0
- package/src/commands/verify-gate.js +572 -0
- package/src/commands/workflow-execute.js +241 -0
- package/src/constants.js +18 -0
- package/src/context-cache.js +159 -0
- package/src/context-search.js +326 -0
- package/src/design-variation-catalog.js +503 -0
- package/src/i18n/messages/en.js +32 -2
- package/src/i18n/messages/es.js +30 -2
- package/src/i18n/messages/fr.js +30 -2
- package/src/i18n/messages/pt-BR.js +32 -2
- package/src/install-animation.js +260 -0
- package/src/install-profile.js +143 -0
- package/src/install-wizard.js +475 -0
- package/src/installer.js +44 -10
- 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/parser.js +7 -1
- package/src/preflight-engine.js +443 -0
- package/src/recovery-context-session.js +154 -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 +158 -4
- package/src/sandbox.js +177 -0
- 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/tool-executor.js +94 -0
- package/src/updater.js +10 -3
- package/src/worker-runner.js +186 -1
- package/template/.aioson/agents/analyst.md +119 -3
- package/template/.aioson/agents/architect.md +98 -0
- package/template/.aioson/agents/design-hybrid-forge.md +141 -0
- package/template/.aioson/agents/dev.md +335 -14
- package/template/.aioson/agents/deyvin.md +117 -2
- package/template/.aioson/agents/discovery-design-doc.md +44 -0
- package/template/.aioson/agents/genome.md +14 -0
- package/template/.aioson/agents/neo.md +78 -1
- package/template/.aioson/agents/orache.md +50 -4
- package/template/.aioson/agents/orchestrator.md +197 -1
- package/template/.aioson/agents/pm.md +93 -0
- package/template/.aioson/agents/product.md +77 -4
- 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 +249 -19
- package/template/.aioson/agents/setup.md +144 -12
- package/template/.aioson/agents/sheldon.md +237 -11
- package/template/.aioson/agents/site-forge.md +1753 -0
- package/template/.aioson/agents/squad.md +162 -0
- package/template/.aioson/agents/tester.md +209 -0
- package/template/.aioson/agents/ux-ui.md +34 -1
- 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 +158 -13
- package/template/.aioson/constitution.md +33 -0
- package/template/.aioson/context/forensics/.gitkeep +0 -0
- package/template/.aioson/context/project-pulse.md +34 -0
- package/template/.aioson/context/seeds/seed-example.md +27 -0
- package/template/.aioson/context/user-profile.md +42 -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/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/setup.md +33 -1
- 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 +35 -1
- 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 +35 -1
- 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 +134 -19
- 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/aurora-command-ui/SKILL.md +243 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
- package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
- package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
- package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
- package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -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/process/aioson-spec-driven/SKILL.md +46 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/analyst.md +30 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/architect.md +23 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -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/hardening-lane.md +49 -0
- package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +101 -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/aioson-spec-driven/references/ui-language.md +75 -0
- package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +147 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +306 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +149 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +208 -0
- package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -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/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/web-research-cache.md +112 -0
- package/template/.aioson/tasks/implementation-plan.md +21 -1
- 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 +75 -1
- package/template/CLAUDE.md +31 -0
- package/template/OPENCODE.md +4 -0
- package/template/researchs/.gitkeep +0 -0
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);
|
|
@@ -693,6 +719,59 @@ function ensureLegacyColumns(db) {
|
|
|
693
719
|
}
|
|
694
720
|
|
|
695
721
|
try { db.exec('ALTER TABLE worker_runs ADD COLUMN conversation_id TEXT'); } catch { /* já existe */ }
|
|
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
|
+
|
|
748
|
+
// Dynamic Tools (Feature: Tool Registry)
|
|
749
|
+
db.exec(`
|
|
750
|
+
CREATE TABLE IF NOT EXISTS dynamic_tools (
|
|
751
|
+
name TEXT PRIMARY KEY,
|
|
752
|
+
description TEXT NOT NULL,
|
|
753
|
+
input_schema TEXT NOT NULL DEFAULT '{}',
|
|
754
|
+
handler_type TEXT NOT NULL DEFAULT 'shell',
|
|
755
|
+
handler_code TEXT,
|
|
756
|
+
handler_path TEXT,
|
|
757
|
+
squad_slug TEXT,
|
|
758
|
+
registered_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
759
|
+
registered_by TEXT
|
|
760
|
+
);
|
|
761
|
+
CREATE INDEX IF NOT EXISTS idx_dynamic_tools_squad ON dynamic_tools(squad_slug);
|
|
762
|
+
`);
|
|
763
|
+
|
|
764
|
+
// Evolution Log (Feature: Learning Evolution Pipeline)
|
|
765
|
+
db.exec(`
|
|
766
|
+
CREATE TABLE IF NOT EXISTS evolution_log (
|
|
767
|
+
id TEXT PRIMARY KEY,
|
|
768
|
+
applied_at TEXT NOT NULL,
|
|
769
|
+
deltas_count INTEGER NOT NULL DEFAULT 0,
|
|
770
|
+
squad_slug TEXT,
|
|
771
|
+
files_json TEXT,
|
|
772
|
+
source_learning_ids_json TEXT
|
|
773
|
+
);
|
|
774
|
+
`);
|
|
696
775
|
}
|
|
697
776
|
|
|
698
777
|
function insertEvent(db, record) {
|
|
@@ -739,12 +818,14 @@ function insertExecutionEvent(db, record) {
|
|
|
739
818
|
task_key, run_key, agent_name, agent_kind, squad_slug, session_key,
|
|
740
819
|
source, workflow_id, workflow_stage, parent_run_key,
|
|
741
820
|
event_type, phase, status, tool_name, message, payload_json,
|
|
742
|
-
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
|
|
743
823
|
) VALUES (
|
|
744
824
|
@task_key, @run_key, @agent_name, @agent_kind, @squad_slug, @session_key,
|
|
745
825
|
@source, @workflow_id, @workflow_stage, @parent_run_key,
|
|
746
826
|
@event_type, @phase, @status, @tool_name, @message, @payload_json,
|
|
747
|
-
@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
|
|
748
829
|
)
|
|
749
830
|
`).run(record);
|
|
750
831
|
}
|
|
@@ -786,7 +867,12 @@ function appendRunEvent(db, options) {
|
|
|
786
867
|
payload_json: payloadJson,
|
|
787
868
|
sequence_no: nextExecutionSequence(db, run.run_key),
|
|
788
869
|
parent_event_id: options.parentEventId || null,
|
|
789
|
-
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
|
|
790
876
|
});
|
|
791
877
|
});
|
|
792
878
|
|
|
@@ -2425,6 +2511,66 @@ function deleteROIConfig(db, squadSlug) {
|
|
|
2425
2511
|
return db.prepare('DELETE FROM squad_roi_config WHERE squad_slug = ?').run(squadSlug);
|
|
2426
2512
|
}
|
|
2427
2513
|
|
|
2514
|
+
// ─── Dynamic Tools CRUD ───────────────────────────────────────────────────────
|
|
2515
|
+
|
|
2516
|
+
function registerDynamicTool(db, opts) {
|
|
2517
|
+
const now = nowIso();
|
|
2518
|
+
db.prepare(`
|
|
2519
|
+
INSERT OR REPLACE INTO dynamic_tools
|
|
2520
|
+
(name, description, input_schema, handler_type, handler_code, handler_path, squad_slug, registered_at, registered_by)
|
|
2521
|
+
VALUES
|
|
2522
|
+
(@name, @description, @inputSchema, @handlerType, @handlerCode, @handlerPath, @squadSlug, @registeredAt, @registeredBy)
|
|
2523
|
+
`).run({
|
|
2524
|
+
name: String(opts.name),
|
|
2525
|
+
description: String(opts.description),
|
|
2526
|
+
inputSchema: opts.inputSchema ? JSON.stringify(opts.inputSchema) : '{}',
|
|
2527
|
+
handlerType: String(opts.handlerType || 'shell'),
|
|
2528
|
+
handlerCode: opts.handlerCode || null,
|
|
2529
|
+
handlerPath: opts.handlerPath || null,
|
|
2530
|
+
squadSlug: opts.squadSlug || null,
|
|
2531
|
+
registeredAt: now,
|
|
2532
|
+
registeredBy: opts.registeredBy || null
|
|
2533
|
+
});
|
|
2534
|
+
return opts.name;
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
function unregisterDynamicTool(db, name) {
|
|
2538
|
+
return db.prepare('DELETE FROM dynamic_tools WHERE name = ?').run(name);
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
function getDynamicTool(db, name) {
|
|
2542
|
+
return db.prepare('SELECT * FROM dynamic_tools WHERE name = ?').get(name) || null;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
function listDynamicTools(db, squadSlug = null) {
|
|
2546
|
+
if (squadSlug) {
|
|
2547
|
+
return db.prepare('SELECT * FROM dynamic_tools WHERE squad_slug = ? ORDER BY registered_at DESC').all(squadSlug);
|
|
2548
|
+
}
|
|
2549
|
+
return db.prepare('SELECT * FROM dynamic_tools ORDER BY registered_at DESC').all();
|
|
2550
|
+
}
|
|
2551
|
+
|
|
2552
|
+
// ─── Evolution Log CRUD ───────────────────────────────────────────────────────
|
|
2553
|
+
|
|
2554
|
+
function insertEvolutionLog(db, opts) {
|
|
2555
|
+
const id = `evo-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
2556
|
+
db.prepare(`
|
|
2557
|
+
INSERT INTO evolution_log (id, applied_at, deltas_count, squad_slug, files_json, source_learning_ids_json)
|
|
2558
|
+
VALUES (@id, @appliedAt, @deltasCount, @squadSlug, @filesJson, @sourceIdsJson)
|
|
2559
|
+
`).run({
|
|
2560
|
+
id,
|
|
2561
|
+
appliedAt: nowIso(),
|
|
2562
|
+
deltasCount: Number(opts.deltasCount || 0),
|
|
2563
|
+
squadSlug: opts.squadSlug || null,
|
|
2564
|
+
filesJson: JSON.stringify(opts.files || []),
|
|
2565
|
+
sourceIdsJson: JSON.stringify(opts.sourceLearningIds || [])
|
|
2566
|
+
});
|
|
2567
|
+
return id;
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
function listEvolutionLog(db, limit = 20) {
|
|
2571
|
+
return db.prepare('SELECT * FROM evolution_log ORDER BY applied_at DESC LIMIT ?').all(limit);
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2428
2574
|
module.exports = {
|
|
2429
2575
|
resolveRuntimePaths,
|
|
2430
2576
|
runtimeStoreExists,
|
|
@@ -2518,5 +2664,13 @@ module.exports = {
|
|
|
2518
2664
|
// ROI Config CRUD
|
|
2519
2665
|
upsertROIConfig,
|
|
2520
2666
|
getROIConfig,
|
|
2521
|
-
deleteROIConfig
|
|
2667
|
+
deleteROIConfig,
|
|
2668
|
+
// Dynamic Tools CRUD
|
|
2669
|
+
registerDynamicTool,
|
|
2670
|
+
unregisterDynamicTool,
|
|
2671
|
+
getDynamicTool,
|
|
2672
|
+
listDynamicTools,
|
|
2673
|
+
// Evolution Log CRUD
|
|
2674
|
+
insertEvolutionLog,
|
|
2675
|
+
listEvolutionLog
|
|
2522
2676
|
};
|
package/src/sandbox.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('node:child_process');
|
|
4
|
+
|
|
5
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
6
|
+
const MAX_OUTPUT_BYTES = 5 * 1024; // 5KB before summarization
|
|
7
|
+
|
|
8
|
+
// Credential redaction patterns — covers the most common secret formats
|
|
9
|
+
const REDACTION_PATTERNS = [
|
|
10
|
+
// GitHub tokens (classic and fine-grained)
|
|
11
|
+
{ pattern: /ghp_[A-Za-z0-9]{36}/g, replacement: 'ghp_[REDACTED]' },
|
|
12
|
+
{ pattern: /github_pat_[A-Za-z0-9_]{82}/g, replacement: 'github_pat_[REDACTED]' },
|
|
13
|
+
// AWS access keys
|
|
14
|
+
{ pattern: /AKIA[0-9A-Z]{16}/g, replacement: 'AKIA[REDACTED]' },
|
|
15
|
+
// Google OAuth tokens
|
|
16
|
+
{ pattern: /ya29\.[A-Za-z0-9_\-]{50,}/g, replacement: 'ya29.[REDACTED]' },
|
|
17
|
+
// Generic Bearer tokens in headers
|
|
18
|
+
{ pattern: /Bearer\s+[A-Za-z0-9\-._~+\/]+=*/gi, replacement: 'Bearer [REDACTED]' },
|
|
19
|
+
// Password in URL (e.g. postgres://user:password@host)
|
|
20
|
+
{ pattern: /:[^/:@\s]{4,}@[a-z0-9.\-]+(?::\d+)?/gi, replacement: ':[REDACTED]@host' },
|
|
21
|
+
// Generic password= key=value pairs
|
|
22
|
+
{ pattern: /password\s*=\s*["']?[^\s"'&;,]{4,}["']?/gi, replacement: 'password=[REDACTED]' },
|
|
23
|
+
{ pattern: /passwd\s*=\s*["']?[^\s"'&;,]{4,}["']?/gi, replacement: 'passwd=[REDACTED]' },
|
|
24
|
+
// secret= key=value pairs
|
|
25
|
+
{ pattern: /secret\s*=\s*["']?[^\s"'&;,]{4,}["']?/gi, replacement: 'secret=[REDACTED]' },
|
|
26
|
+
// api_key= or apikey= patterns
|
|
27
|
+
{ pattern: /api[_-]?key\s*=\s*["']?[^\s"'&;,]{4,}["']?/gi, replacement: 'api_key=[REDACTED]' },
|
|
28
|
+
// Private key blocks
|
|
29
|
+
{ pattern: /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/g, replacement: '-----BEGIN PRIVATE KEY [REDACTED] END PRIVATE KEY-----' },
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Redact known credential patterns from a string.
|
|
34
|
+
* @param {string} text
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
function redactCredentials(text) {
|
|
38
|
+
if (!text) return text;
|
|
39
|
+
let result = text;
|
|
40
|
+
for (const { pattern, replacement } of REDACTION_PATTERNS) {
|
|
41
|
+
result = result.replace(pattern, replacement);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Summarize long output to stay within size budget.
|
|
48
|
+
* @param {string} output
|
|
49
|
+
* @param {string} intent — optional context about what was executed
|
|
50
|
+
* @param {number} maxSize — max bytes to return
|
|
51
|
+
* @returns {string}
|
|
52
|
+
*/
|
|
53
|
+
function summarizeOutput(output, intent = '', maxSize = MAX_OUTPUT_BYTES) {
|
|
54
|
+
if (!output || output.length <= maxSize) return output;
|
|
55
|
+
|
|
56
|
+
const half = Math.floor(maxSize / 2);
|
|
57
|
+
const head = output.slice(0, half);
|
|
58
|
+
const tail = output.slice(-half);
|
|
59
|
+
const omitted = output.length - maxSize;
|
|
60
|
+
const intentNote = intent ? ` (${intent})` : '';
|
|
61
|
+
|
|
62
|
+
return `${head}\n\n[... ${omitted} bytes omitted${intentNote} ...]\n\n${tail}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Execute a shell command in a sandboxed subprocess with timeout and redaction.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} command — shell command to run
|
|
69
|
+
* @param {object} opts — { cwd?, timeout?, env?, maxOutput?, intent?, shell? }
|
|
70
|
+
* @returns {{ ok: boolean, stdout: string, stderr: string, exitCode: number|null, timedOut: boolean }}
|
|
71
|
+
*/
|
|
72
|
+
async function executeInSandbox(command, opts = {}) {
|
|
73
|
+
const timeout = opts.timeout || DEFAULT_TIMEOUT_MS;
|
|
74
|
+
const cwd = opts.cwd || process.cwd();
|
|
75
|
+
const maxOutput = opts.maxOutput || MAX_OUTPUT_BYTES;
|
|
76
|
+
const intent = opts.intent || command.slice(0, 60);
|
|
77
|
+
const shell = opts.shell !== false; // default true
|
|
78
|
+
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
const controller = new AbortController();
|
|
81
|
+
let timedOut = false;
|
|
82
|
+
let killed = false;
|
|
83
|
+
|
|
84
|
+
const timer = setTimeout(() => {
|
|
85
|
+
timedOut = true;
|
|
86
|
+
controller.abort();
|
|
87
|
+
}, timeout);
|
|
88
|
+
|
|
89
|
+
const stdoutChunks = [];
|
|
90
|
+
const stderrChunks = [];
|
|
91
|
+
let stdoutSize = 0;
|
|
92
|
+
let stderrSize = 0;
|
|
93
|
+
|
|
94
|
+
const baseOpts = {
|
|
95
|
+
cwd,
|
|
96
|
+
env: { ...process.env, ...(opts.env || {}) },
|
|
97
|
+
signal: controller.signal
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
let child;
|
|
101
|
+
try {
|
|
102
|
+
if (shell) {
|
|
103
|
+
// Use Node's built-in shell wrapping
|
|
104
|
+
child = spawn(command, [], { ...baseOpts, shell: true });
|
|
105
|
+
} else {
|
|
106
|
+
const parts = command.split(/\s+/);
|
|
107
|
+
child = spawn(parts[0], parts.slice(1), { ...baseOpts, shell: false });
|
|
108
|
+
}
|
|
109
|
+
} catch (err) {
|
|
110
|
+
clearTimeout(timer);
|
|
111
|
+
resolve({ ok: false, stdout: '', stderr: err.message, exitCode: null, timedOut: false, error: err.message });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
child.stdout.on('data', (chunk) => {
|
|
116
|
+
if (stdoutSize < maxOutput * 2) {
|
|
117
|
+
stdoutChunks.push(chunk);
|
|
118
|
+
stdoutSize += chunk.length;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
child.stderr.on('data', (chunk) => {
|
|
123
|
+
if (stderrSize < maxOutput * 2) {
|
|
124
|
+
stderrChunks.push(chunk);
|
|
125
|
+
stderrSize += chunk.length;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
child.on('close', (code, signal) => {
|
|
130
|
+
if (killed) return;
|
|
131
|
+
clearTimeout(timer);
|
|
132
|
+
|
|
133
|
+
const rawStdout = Buffer.concat(stdoutChunks).toString('utf8');
|
|
134
|
+
const rawStderr = Buffer.concat(stderrChunks).toString('utf8');
|
|
135
|
+
|
|
136
|
+
const stdout = redactCredentials(summarizeOutput(rawStdout, intent, maxOutput));
|
|
137
|
+
const stderr = redactCredentials(summarizeOutput(rawStderr, intent, maxOutput));
|
|
138
|
+
|
|
139
|
+
resolve({
|
|
140
|
+
ok: !timedOut && code === 0,
|
|
141
|
+
stdout,
|
|
142
|
+
stderr,
|
|
143
|
+
exitCode: code,
|
|
144
|
+
timedOut,
|
|
145
|
+
signal: signal || null
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
child.on('error', (err) => {
|
|
150
|
+
if (killed) return;
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
|
|
153
|
+
if (err.code === 'ABORT_ERR' || timedOut) {
|
|
154
|
+
resolve({
|
|
155
|
+
ok: false,
|
|
156
|
+
stdout: '',
|
|
157
|
+
stderr: `Command timed out after ${timeout}ms`,
|
|
158
|
+
exitCode: null,
|
|
159
|
+
timedOut: true,
|
|
160
|
+
signal: null
|
|
161
|
+
});
|
|
162
|
+
} else {
|
|
163
|
+
resolve({
|
|
164
|
+
ok: false,
|
|
165
|
+
stdout: '',
|
|
166
|
+
stderr: err.message,
|
|
167
|
+
exitCode: null,
|
|
168
|
+
timedOut: false,
|
|
169
|
+
error: err.message
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
killed = true;
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = { executeInSandbox, redactCredentials, summarizeOutput };
|
|
@@ -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
|
+
};
|