@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
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# Spec & Learnings Pipeline
|
|
2
|
+
|
|
3
|
+
> Sincroniza specs Markdown com o SQLite e exporta learnings para memória procedural do projeto.
|
|
4
|
+
|
|
5
|
+
O AIOSON mantém duas representações do estado de desenvolvimento: os arquivos `spec-{slug}.md` em `.aioson/context/` (editados pelos agentes) e o banco SQLite `aios.sqlite` (lido pelo dashboard). Este pipeline conecta os dois automaticamente.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Visão geral do fluxo
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
@dev escreve spec-checkout.md
|
|
13
|
+
└─ ## Session Learnings: [process] commit por step
|
|
14
|
+
└─ frontmatter: phase_gates: {plan: approved}
|
|
15
|
+
└─ last_checkpoint: "Criando migration cart_items — step 3 de 5"
|
|
16
|
+
|
|
17
|
+
aioson spec:sync .
|
|
18
|
+
└─ project_learnings ← learnings upserted (frequency++)
|
|
19
|
+
└─ plan_phases ← phase_gates mapeadas para status
|
|
20
|
+
|
|
21
|
+
aioson spec:status .
|
|
22
|
+
└─ tabela de features com fase, agente, checkpoint
|
|
23
|
+
|
|
24
|
+
aioson learning:export . --min-frequency=2
|
|
25
|
+
└─ .aioson/brains/process-commit-por-step.md ← node Zettelkasten
|
|
26
|
+
|
|
27
|
+
aioson learning:evolve .
|
|
28
|
+
└─ genome ← learnings com frequency ≥ 5 promovidos
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## `aioson spec:sync`
|
|
34
|
+
|
|
35
|
+
Sincroniza learnings e phase gates de todos os specs para o SQLite.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
aioson spec:sync [path] [opções]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Opções:**
|
|
42
|
+
|
|
43
|
+
| Opção | Descrição |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `--json` | Retorna JSON com contagem de learnings e fases sincronizadas |
|
|
46
|
+
| `--verbose` | Mostra detalhes de cada arquivo processado |
|
|
47
|
+
|
|
48
|
+
**Exemplo:**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
aioson spec:sync .
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Saída:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Spec Sync — meu-projeto
|
|
58
|
+
──────────────────────────────────────────────────
|
|
59
|
+
spec-checkout.md
|
|
60
|
+
Learnings synced: 3
|
|
61
|
+
Plan phases updated: 1
|
|
62
|
+
last_checkpoint: "Criando migration cart_items"
|
|
63
|
+
spec.md
|
|
64
|
+
Learnings synced: 2
|
|
65
|
+
──────────────────────────────────────────────────
|
|
66
|
+
Summary: 5 learnings synced, 1 plan phases updated
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Formato dos learnings no spec:**
|
|
70
|
+
|
|
71
|
+
```markdown
|
|
72
|
+
## Session Learnings
|
|
73
|
+
- [process] Fazer commit após cada step atômico, não só no final
|
|
74
|
+
- [domain] cart_items deve ter UNIQUE(cart_id, product_id)
|
|
75
|
+
- [quality] Rodar testes com --filter isola o módulo rapidamente
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Prefixos aceitos: `[process]`, `[domain]`, `[quality]`, `[preference]`.
|
|
79
|
+
Linhas sem prefixo são classificadas automaticamente como `[process]`.
|
|
80
|
+
|
|
81
|
+
**Idempotência:** rodar `spec:sync` duas vezes no mesmo spec não duplica learnings. Se o título já existe em `project_learnings`, o campo `frequency` é incrementado (`frequency++`).
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## `aioson spec:status`
|
|
86
|
+
|
|
87
|
+
Exibe o estado atual de todas as features com dados do SQLite.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
aioson spec:status [path] [opções]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Opções:**
|
|
94
|
+
|
|
95
|
+
| Opção | Descrição |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `--json` | Retorna JSON com array de features e contagem de learnings |
|
|
98
|
+
|
|
99
|
+
**Exemplo:**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
aioson spec:status .
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Saída:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
Project Status — meu-projeto
|
|
109
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
110
|
+
Feature Phase Status Last Agent Checkpoint
|
|
111
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
112
|
+
checkout 2/5 in_progress dev Criando migration...
|
|
113
|
+
auth 5/5 done qa QA sign-off 2026-03-28
|
|
114
|
+
onboarding 0/5 not_started — —
|
|
115
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
116
|
+
Active learnings: 12 | Promotable (freq≥3): 4
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## `aioson spec:checkpoint`
|
|
122
|
+
|
|
123
|
+
Registra manualmente o `last_checkpoint` de um spec no SQLite. Útil quando a sessão caiu sem `agent:done`.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
aioson spec:checkpoint [path] --feature=<slug> [--agent=<agent>]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Opções:**
|
|
130
|
+
|
|
131
|
+
| Opção | Descrição |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `--feature=<slug>` | Feature cujo spec será lido (obrigatório) |
|
|
134
|
+
| `--agent=<name>` | Agente da run ativa (padrão: `dev`) |
|
|
135
|
+
| `--json` | Retorna JSON com run_key e checkpoint registrado |
|
|
136
|
+
|
|
137
|
+
**Exemplo:**
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Sessão do @dev em checkout caiu sem agent:done
|
|
141
|
+
aioson spec:checkpoint . --feature=checkout
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Saída:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
Reading spec-checkout.md...
|
|
148
|
+
last_checkpoint: "Criando migration cart_items — step 3 of 5"
|
|
149
|
+
phase_gates: {"plan":"approved","requirements":"approved","design":"pending"}
|
|
150
|
+
|
|
151
|
+
Checkpoint registered:
|
|
152
|
+
run_key: dev-1711234567890
|
|
153
|
+
summary: "Criando migration cart_items — step 3 of 5"
|
|
154
|
+
status: in_progress (checkpoint only — use agent:done to close)
|
|
155
|
+
|
|
156
|
+
Next: continue with /dev — start from last_checkpoint
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
O comando procura a run mais recente do agente no SQLite e registra um evento `plan_checkpoint` nela. O run permanece `in_progress` — use `agent:done` para fechá-la quando terminar.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## `aioson learning:export`
|
|
164
|
+
|
|
165
|
+
Exporta `project_learnings` do SQLite para `.aioson/brains/` como nodes no formato Zettelkasten.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
aioson learning:export [path] [--min-frequency=N] [--json]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Opções:**
|
|
172
|
+
|
|
173
|
+
| Opção | Descrição |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `--min-frequency=N` | Exporta apenas learnings com `frequency >= N` (padrão: 1) |
|
|
176
|
+
| `--json` | Retorna JSON com lista de nodes exportados |
|
|
177
|
+
|
|
178
|
+
**Exemplos:**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Exportar todos os learnings ativos
|
|
182
|
+
aioson learning:export .
|
|
183
|
+
|
|
184
|
+
# Apenas learnings reforçados em 2+ sessões
|
|
185
|
+
aioson learning:export . --min-frequency=2
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Saída:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
Learning Export — min-frequency: 2
|
|
192
|
+
──────────────────────────────────────────────────
|
|
193
|
+
process-commit-por-step.md ✓ (frequency: 4)
|
|
194
|
+
domain-cart-uniqueness.md ✓ (frequency: 3)
|
|
195
|
+
process-test-isolation.md ✓ (frequency: 2)
|
|
196
|
+
──────────────────────────────────────────────────
|
|
197
|
+
3 nodes written to .aioson/brains/
|
|
198
|
+
2 learning(s) with frequency ≥ 5 — run: aioson learning:evolve to promote to genome
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Formato do node exportado** (`.aioson/brains/process-commit-por-step.md`):
|
|
202
|
+
|
|
203
|
+
```markdown
|
|
204
|
+
---
|
|
205
|
+
id: process-commit-por-step
|
|
206
|
+
type: process
|
|
207
|
+
title: Fazer commit após cada step atômico, não só no final
|
|
208
|
+
frequency: 4
|
|
209
|
+
last_reinforced: 2026-04-01
|
|
210
|
+
source_feature: checkout
|
|
211
|
+
promoted_to: null
|
|
212
|
+
created_at: 2026-03-15
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
# Fazer commit após cada step atômico
|
|
216
|
+
|
|
217
|
+
**Evidence:** Detected in 4 session(s).
|
|
218
|
+
|
|
219
|
+
## Applications
|
|
220
|
+
- Review and apply this learning in future sessions of type: process
|
|
221
|
+
|
|
222
|
+
## Links
|
|
223
|
+
<!-- Add cross-references here -->
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Fluxo recomendado após cada sessão do @dev
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# 1. Sincronizar spec com o SQLite
|
|
232
|
+
aioson spec:sync .
|
|
233
|
+
|
|
234
|
+
# 2. Ver estado atual das features
|
|
235
|
+
aioson spec:status .
|
|
236
|
+
|
|
237
|
+
# 3. Quando learnings se acumularem (≥ 2 sessões), exportar para brains
|
|
238
|
+
aioson learning:export . --min-frequency=2
|
|
239
|
+
|
|
240
|
+
# 4. Quando um learning atingir frequency ≥ 5, promover para genome
|
|
241
|
+
aioson learning:evolve .
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Integração com o spec.md
|
|
247
|
+
|
|
248
|
+
O `spec:sync` procura esses elementos em cada `spec-{slug}.md`:
|
|
249
|
+
|
|
250
|
+
| Elemento | Onde fica | O que faz |
|
|
251
|
+
|---|---|---|
|
|
252
|
+
| `## Session Learnings` | Corpo do arquivo | Cria/atualiza `project_learnings` |
|
|
253
|
+
| `phase_gates` | Frontmatter YAML | Atualiza `plan_phases.status` |
|
|
254
|
+
| `last_checkpoint` | Frontmatter ou seção | Exibido em `spec:status` |
|
|
255
|
+
|
|
256
|
+
**Exemplo de frontmatter de spec:**
|
|
257
|
+
|
|
258
|
+
```markdown
|
|
259
|
+
---
|
|
260
|
+
feature: checkout
|
|
261
|
+
status: in_progress
|
|
262
|
+
phase_gates: {"plan": "approved", "requirements": "approved", "design": "pending"}
|
|
263
|
+
last_checkpoint: "Criando migration cart_items — step 3 de 5"
|
|
264
|
+
---
|
|
265
|
+
```
|
package/package.json
CHANGED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A2A Client — Plan 81, Phase 3.2
|
|
5
|
+
*
|
|
6
|
+
* HTTP client for sending tasks/events to A2A-compatible agents
|
|
7
|
+
* (including other AIOSON squads in different projects).
|
|
8
|
+
*
|
|
9
|
+
* Implements Google A2A v1.0 JSON-RPC 2.0 protocol.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const http = require('node:http');
|
|
13
|
+
const https = require('node:https');
|
|
14
|
+
const { randomUUID } = require('node:crypto');
|
|
15
|
+
|
|
16
|
+
const DEFAULT_TIMEOUT = 30000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Send a JSON-RPC 2.0 request to an A2A endpoint.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} url — A2A endpoint URL
|
|
22
|
+
* @param {string} method — JSON-RPC method
|
|
23
|
+
* @param {object} params — Method parameters
|
|
24
|
+
* @param {object} [options] — { timeout }
|
|
25
|
+
* @returns {Promise<object>} — JSON-RPC response
|
|
26
|
+
*/
|
|
27
|
+
function rpcRequest(url, method, params, options = {}) {
|
|
28
|
+
const { timeout = DEFAULT_TIMEOUT } = options;
|
|
29
|
+
const requestId = randomUUID();
|
|
30
|
+
|
|
31
|
+
const body = JSON.stringify({
|
|
32
|
+
jsonrpc: '2.0',
|
|
33
|
+
id: requestId,
|
|
34
|
+
method,
|
|
35
|
+
params
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const parsedUrl = new URL(url);
|
|
40
|
+
const transport = parsedUrl.protocol === 'https:' ? https : http;
|
|
41
|
+
|
|
42
|
+
const req = transport.request({
|
|
43
|
+
hostname: parsedUrl.hostname,
|
|
44
|
+
port: parsedUrl.port,
|
|
45
|
+
path: parsedUrl.pathname,
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
'Content-Length': Buffer.byteLength(body)
|
|
50
|
+
},
|
|
51
|
+
timeout
|
|
52
|
+
}, (res) => {
|
|
53
|
+
let data = '';
|
|
54
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
55
|
+
res.on('end', () => {
|
|
56
|
+
try {
|
|
57
|
+
resolve(JSON.parse(data));
|
|
58
|
+
} catch {
|
|
59
|
+
resolve({ error: { code: -32700, message: 'Parse error', data } });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
req.on('error', (err) => {
|
|
65
|
+
resolve({ error: { code: -32000, message: err.message } });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
req.on('timeout', () => {
|
|
69
|
+
req.destroy();
|
|
70
|
+
resolve({ error: { code: -32000, message: `Request timed out after ${timeout}ms` } });
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
req.write(body);
|
|
74
|
+
req.end();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Discover an A2A agent by fetching its Agent Card.
|
|
80
|
+
*
|
|
81
|
+
* @param {string} baseUrl — Agent's base URL
|
|
82
|
+
* @returns {Promise<object|null>} — Agent Card or null
|
|
83
|
+
*/
|
|
84
|
+
async function discoverAgent(baseUrl) {
|
|
85
|
+
const cardUrl = `${baseUrl.replace(/\/$/, '')}/.well-known/agent.json`;
|
|
86
|
+
|
|
87
|
+
return new Promise((resolve) => {
|
|
88
|
+
const parsedUrl = new URL(cardUrl);
|
|
89
|
+
const transport = parsedUrl.protocol === 'https:' ? https : http;
|
|
90
|
+
|
|
91
|
+
const req = transport.get(cardUrl, { timeout: 10000 }, (res) => {
|
|
92
|
+
let data = '';
|
|
93
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
94
|
+
res.on('end', () => {
|
|
95
|
+
try {
|
|
96
|
+
resolve(JSON.parse(data));
|
|
97
|
+
} catch {
|
|
98
|
+
resolve(null);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
req.on('error', () => resolve(null));
|
|
104
|
+
req.on('timeout', () => { req.destroy(); resolve(null); });
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Send a task to an A2A agent.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} agentUrl — Agent's A2A endpoint URL
|
|
112
|
+
* @param {object} task — { id, title, description, input }
|
|
113
|
+
* @returns {Promise<object>} — { ok, taskId, result, error }
|
|
114
|
+
*/
|
|
115
|
+
async function sendTask(agentUrl, task) {
|
|
116
|
+
const taskId = task.id || randomUUID();
|
|
117
|
+
|
|
118
|
+
const response = await rpcRequest(agentUrl, 'tasks/send', {
|
|
119
|
+
id: taskId,
|
|
120
|
+
message: {
|
|
121
|
+
role: 'user',
|
|
122
|
+
parts: [
|
|
123
|
+
{ type: 'text', text: task.description || task.title }
|
|
124
|
+
]
|
|
125
|
+
},
|
|
126
|
+
metadata: {
|
|
127
|
+
title: task.title,
|
|
128
|
+
input: task.input || null
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (response.error) {
|
|
133
|
+
return { ok: false, taskId, error: response.error.message };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { ok: true, taskId, result: response.result };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Publish an event to an A2A peer.
|
|
141
|
+
*
|
|
142
|
+
* @param {string} peerUrl — Peer's A2A endpoint URL
|
|
143
|
+
* @param {object} event — { fromSquad, event, payload }
|
|
144
|
+
* @returns {Promise<object>}
|
|
145
|
+
*/
|
|
146
|
+
async function publishEvent(peerUrl, event) {
|
|
147
|
+
const response = await rpcRequest(peerUrl, 'events/publish', {
|
|
148
|
+
source: event.fromSquad,
|
|
149
|
+
type: event.event,
|
|
150
|
+
data: event.payload || {}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
if (response.error) {
|
|
154
|
+
return { ok: false, error: response.error.message };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return { ok: true, id: response.result?.id };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = {
|
|
161
|
+
rpcRequest,
|
|
162
|
+
discoverAgent,
|
|
163
|
+
sendTask,
|
|
164
|
+
publishEvent
|
|
165
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A2A Server — Plan 81, Phase 3.2
|
|
5
|
+
*
|
|
6
|
+
* Micro HTTP server that exposes squad capabilities via A2A protocol.
|
|
7
|
+
* Receives tasks from external A2A agents and routes them to local squads.
|
|
8
|
+
*
|
|
9
|
+
* Endpoints:
|
|
10
|
+
* POST /a2a/{squad-slug} — JSON-RPC 2.0 task handler
|
|
11
|
+
* GET /.well-known/agent.json — Agent Card discovery
|
|
12
|
+
* GET /a2a/{squad-slug}/status — Squad status
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const http = require('node:http');
|
|
16
|
+
const fs = require('node:fs/promises');
|
|
17
|
+
const path = require('node:path');
|
|
18
|
+
const { randomUUID } = require('node:crypto');
|
|
19
|
+
|
|
20
|
+
const SQUADS_DIR = path.join('.aioson', 'squads');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Create an A2A server for a project.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} projectDir
|
|
26
|
+
* @param {object} [options] — { port, host }
|
|
27
|
+
* @returns {{ server, start, stop }}
|
|
28
|
+
*/
|
|
29
|
+
function createA2AServer(projectDir, options = {}) {
|
|
30
|
+
const { port = 3847, host = '127.0.0.1' } = options;
|
|
31
|
+
const pendingTasks = new Map();
|
|
32
|
+
|
|
33
|
+
const server = http.createServer(async (req, res) => {
|
|
34
|
+
const url = new URL(req.url, `http://${host}:${port}`);
|
|
35
|
+
|
|
36
|
+
// CORS headers
|
|
37
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
38
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
39
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
|
40
|
+
|
|
41
|
+
if (req.method === 'OPTIONS') {
|
|
42
|
+
res.writeHead(200);
|
|
43
|
+
res.end();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Agent Card discovery
|
|
48
|
+
if (req.method === 'GET' && url.pathname === '/.well-known/agent.json') {
|
|
49
|
+
return handleAgentCardDiscovery(projectDir, res);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Squad status
|
|
53
|
+
const statusMatch = url.pathname.match(/^\/a2a\/([a-z0-9-]+)\/status$/);
|
|
54
|
+
if (req.method === 'GET' && statusMatch) {
|
|
55
|
+
return handleSquadStatus(projectDir, statusMatch[1], res);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A2A JSON-RPC endpoint
|
|
59
|
+
const a2aMatch = url.pathname.match(/^\/a2a\/([a-z0-9-]+)$/);
|
|
60
|
+
if (req.method === 'POST' && a2aMatch) {
|
|
61
|
+
return handleJsonRpc(projectDir, a2aMatch[1], req, res, pendingTasks);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
65
|
+
res.end(JSON.stringify({ error: 'Not Found' }));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
server,
|
|
70
|
+
start() {
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
server.listen(port, host, () => resolve({ port, host }));
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
stop() {
|
|
76
|
+
return new Promise((resolve) => {
|
|
77
|
+
server.close(() => resolve());
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
pendingTasks
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// ─── Handlers ────────────────────────────────────────────────────────────────
|
|
85
|
+
|
|
86
|
+
async function handleAgentCardDiscovery(projectDir, res) {
|
|
87
|
+
// Return a composite card for all squads
|
|
88
|
+
const squadsDir = path.join(projectDir, SQUADS_DIR);
|
|
89
|
+
const cards = [];
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const entries = await fs.readdir(squadsDir, { withFileTypes: true });
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
if (!entry.isDirectory()) continue;
|
|
95
|
+
const manifestPath = path.join(squadsDir, entry.name, 'squad.manifest.json');
|
|
96
|
+
try {
|
|
97
|
+
const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
|
|
98
|
+
cards.push({
|
|
99
|
+
slug: entry.name,
|
|
100
|
+
name: manifest.name || entry.name,
|
|
101
|
+
description: manifest.mission || manifest.goal || ''
|
|
102
|
+
});
|
|
103
|
+
} catch { /* no valid manifest */ }
|
|
104
|
+
}
|
|
105
|
+
} catch { /* no squads dir */ }
|
|
106
|
+
|
|
107
|
+
const compositeCard = {
|
|
108
|
+
name: 'AIOSON Project',
|
|
109
|
+
description: `AIOSON project with ${cards.length} squad(s)`,
|
|
110
|
+
version: '1.0.0',
|
|
111
|
+
squads: cards,
|
|
112
|
+
capabilities: {
|
|
113
|
+
streaming: false,
|
|
114
|
+
pushNotifications: false
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
119
|
+
res.end(JSON.stringify(compositeCard, null, 2));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function handleSquadStatus(projectDir, squadSlug, res) {
|
|
123
|
+
const statePath = path.join(projectDir, SQUADS_DIR, squadSlug, 'STATE.md');
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
const content = await fs.readFile(statePath, 'utf8');
|
|
127
|
+
res.writeHead(200, { 'Content-Type': 'text/markdown' });
|
|
128
|
+
res.end(content);
|
|
129
|
+
} catch {
|
|
130
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
131
|
+
res.end(JSON.stringify({ error: `Squad "${squadSlug}" not found` }));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function handleJsonRpc(projectDir, squadSlug, req, res, pendingTasks) {
|
|
136
|
+
let body = '';
|
|
137
|
+
for await (const chunk of req) body += chunk;
|
|
138
|
+
|
|
139
|
+
let rpc;
|
|
140
|
+
try {
|
|
141
|
+
rpc = JSON.parse(body);
|
|
142
|
+
} catch {
|
|
143
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
144
|
+
res.end(JSON.stringify({
|
|
145
|
+
jsonrpc: '2.0',
|
|
146
|
+
error: { code: -32700, message: 'Parse error' },
|
|
147
|
+
id: null
|
|
148
|
+
}));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const { method, params, id } = rpc;
|
|
153
|
+
|
|
154
|
+
if (method === 'tasks/send') {
|
|
155
|
+
const taskId = params?.id || randomUUID();
|
|
156
|
+
pendingTasks.set(taskId, {
|
|
157
|
+
id: taskId,
|
|
158
|
+
squadSlug,
|
|
159
|
+
params,
|
|
160
|
+
status: 'pending',
|
|
161
|
+
createdAt: new Date().toISOString()
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
165
|
+
res.end(JSON.stringify({
|
|
166
|
+
jsonrpc: '2.0',
|
|
167
|
+
result: {
|
|
168
|
+
id: taskId,
|
|
169
|
+
status: { state: 'submitted' },
|
|
170
|
+
message: `Task queued for squad "${squadSlug}"`
|
|
171
|
+
},
|
|
172
|
+
id
|
|
173
|
+
}));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (method === 'tasks/get') {
|
|
178
|
+
const task = pendingTasks.get(params?.id);
|
|
179
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
180
|
+
res.end(JSON.stringify({
|
|
181
|
+
jsonrpc: '2.0',
|
|
182
|
+
result: task || { error: 'Task not found' },
|
|
183
|
+
id
|
|
184
|
+
}));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (method === 'events/publish') {
|
|
189
|
+
// Route to local inter-squad-events
|
|
190
|
+
try {
|
|
191
|
+
const { publish } = require('../squad/inter-squad-events');
|
|
192
|
+
const eventId = await publish(projectDir, {
|
|
193
|
+
fromSquad: params?.source || 'a2a-external',
|
|
194
|
+
event: params?.type || 'a2a.event',
|
|
195
|
+
payload: params?.data
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
199
|
+
res.end(JSON.stringify({
|
|
200
|
+
jsonrpc: '2.0',
|
|
201
|
+
result: { id: eventId, status: 'published' },
|
|
202
|
+
id
|
|
203
|
+
}));
|
|
204
|
+
} catch (err) {
|
|
205
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
206
|
+
res.end(JSON.stringify({
|
|
207
|
+
jsonrpc: '2.0',
|
|
208
|
+
error: { code: -32603, message: err.message },
|
|
209
|
+
id
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
216
|
+
res.end(JSON.stringify({
|
|
217
|
+
jsonrpc: '2.0',
|
|
218
|
+
error: { code: -32601, message: `Method not found: ${method}` },
|
|
219
|
+
id
|
|
220
|
+
}));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = { createA2AServer };
|