macro-agent 0.1.0 → 0.1.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/.claude/settings.local.json +3 -1
- package/.sudocode/issues.jsonl +28 -0
- package/.sudocode/specs.jsonl +8 -0
- package/CLAUDE.md +25 -17
- package/README.md +11 -29
- package/dist/acp/macro-agent.d.ts +15 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +131 -35
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/types.d.ts +32 -1
- package/dist/acp/types.d.ts.map +1 -1
- package/dist/acp/types.js.map +1 -1
- package/dist/agent/agent-manager.d.ts +65 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +544 -200
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +8 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/server.d.ts +8 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +136 -8
- package/dist/api/server.js.map +1 -1
- package/dist/api/types.d.ts +1 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token.d.ts +41 -0
- package/dist/auth/token.d.ts.map +1 -0
- package/dist/auth/token.js +73 -0
- package/dist/auth/token.js.map +1 -0
- package/dist/cli/acp.d.ts +2 -23
- package/dist/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +197 -61
- package/dist/cli/acp.js.map +1 -1
- package/dist/cli/index.js +152 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.d.ts +6 -0
- package/dist/cli/mcp.d.ts.map +1 -1
- package/dist/cli/mcp.js +279 -173
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli/parse-args.d.ts +20 -0
- package/dist/cli/parse-args.d.ts.map +1 -0
- package/dist/cli/parse-args.js +43 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/stable-instance-id.d.ts +8 -0
- package/dist/cli/stable-instance-id.d.ts.map +1 -0
- package/dist/cli/stable-instance-id.js +14 -0
- package/dist/cli/stable-instance-id.js.map +1 -0
- package/dist/config/project-config.d.ts +85 -7
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +133 -20
- package/dist/config/project-config.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/handlers/index.d.ts +7 -3
- package/dist/lifecycle/handlers/index.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.js +25 -8
- package/dist/lifecycle/handlers/index.js.map +1 -1
- package/dist/lifecycle/types.d.ts +2 -0
- package/dist/lifecycle/types.d.ts.map +1 -1
- package/dist/lifecycle/types.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts +17 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +384 -23
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/adapter/connection-manager.d.ts.map +1 -1
- package/dist/map/adapter/connection-manager.js +3 -0
- package/dist/map/adapter/connection-manager.js.map +1 -1
- package/dist/map/adapter/event-log.d.ts +87 -0
- package/dist/map/adapter/event-log.d.ts.map +1 -0
- package/dist/map/adapter/event-log.js +122 -0
- package/dist/map/adapter/event-log.js.map +1 -0
- package/dist/map/adapter/event-translator.js +6 -6
- package/dist/map/adapter/event-translator.js.map +1 -1
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +13 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +61 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
- package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
- package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
- package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
- package/dist/map/adapter/extensions/rename.d.ts +29 -0
- package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
- package/dist/map/adapter/extensions/rename.js +49 -0
- package/dist/map/adapter/extensions/rename.js.map +1 -0
- package/dist/map/adapter/extensions/streams.d.ts +95 -0
- package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
- package/dist/map/adapter/extensions/streams.js +515 -0
- package/dist/map/adapter/extensions/streams.js.map +1 -0
- package/dist/map/adapter/extensions/task.d.ts.map +1 -1
- package/dist/map/adapter/extensions/task.js +10 -0
- package/dist/map/adapter/extensions/task.js.map +1 -1
- package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
- package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
- package/dist/map/adapter/extensions/update-metadata.js +67 -0
- package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
- package/dist/map/adapter/index.d.ts +2 -1
- package/dist/map/adapter/index.d.ts.map +1 -1
- package/dist/map/adapter/index.js +10 -2
- package/dist/map/adapter/index.js.map +1 -1
- package/dist/map/adapter/interface.d.ts +2 -0
- package/dist/map/adapter/interface.d.ts.map +1 -1
- package/dist/map/adapter/map-adapter.d.ts +3 -0
- package/dist/map/adapter/map-adapter.d.ts.map +1 -1
- package/dist/map/adapter/map-adapter.js +258 -35
- package/dist/map/adapter/map-adapter.js.map +1 -1
- package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
- package/dist/map/adapter/subscription-manager.js +5 -1
- package/dist/map/adapter/subscription-manager.js.map +1 -1
- package/dist/map/adapter/types.d.ts +3 -1
- package/dist/map/adapter/types.d.ts.map +1 -1
- package/dist/mcp/map-client.d.ts +39 -0
- package/dist/mcp/map-client.d.ts.map +1 -0
- package/dist/mcp/map-client.js +129 -0
- package/dist/mcp/map-client.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +16 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +125 -88
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tools/done.d.ts.map +1 -1
- package/dist/mcp/tools/done.js +18 -0
- package/dist/mcp/tools/done.js.map +1 -1
- package/dist/mcp/types.d.ts +9 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/metrics/metrics.js +1 -1
- package/dist/metrics/metrics.js.map +1 -1
- package/dist/roles/builtin/coordinator.d.ts.map +1 -1
- package/dist/roles/builtin/coordinator.js +2 -1
- package/dist/roles/builtin/coordinator.js.map +1 -1
- package/dist/roles/builtin/integrator.d.ts.map +1 -1
- package/dist/roles/builtin/integrator.js +2 -1
- package/dist/roles/builtin/integrator.js.map +1 -1
- package/dist/roles/builtin/worker.d.ts.map +1 -1
- package/dist/roles/builtin/worker.js +3 -1
- package/dist/roles/builtin/worker.js.map +1 -1
- package/dist/roles/capabilities.d.ts +9 -1
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +27 -7
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/config-loader.d.ts +6 -6
- package/dist/roles/config-loader.d.ts.map +1 -1
- package/dist/roles/config-loader.js +8 -7
- package/dist/roles/config-loader.js.map +1 -1
- package/dist/roles/registry.d.ts +2 -2
- package/dist/roles/registry.js +2 -2
- package/dist/roles/types.d.ts +3 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/server/combined-server.d.ts +28 -1
- package/dist/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +111 -8
- package/dist/server/combined-server.js.map +1 -1
- package/dist/store/event-store.d.ts +2 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +80 -24
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/instance.d.ts +1 -1
- package/dist/store/instance.d.ts.map +1 -1
- package/dist/store/instance.js +2 -2
- package/dist/store/instance.js.map +1 -1
- package/dist/store/types/agents.d.ts +23 -0
- package/dist/store/types/agents.d.ts.map +1 -1
- package/dist/store/types/events.d.ts +1 -1
- package/dist/store/types/events.d.ts.map +1 -1
- package/dist/task/backend/index.d.ts +47 -29
- package/dist/task/backend/index.d.ts.map +1 -1
- package/dist/task/backend/index.js +109 -71
- package/dist/task/backend/index.js.map +1 -1
- package/dist/task/backend/memory.d.ts +1 -0
- package/dist/task/backend/memory.d.ts.map +1 -1
- package/dist/task/backend/memory.js +3 -0
- package/dist/task/backend/memory.js.map +1 -1
- package/dist/task/backend/opentasks/backend.d.ts +140 -0
- package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
- package/dist/task/backend/opentasks/backend.js +1023 -0
- package/dist/task/backend/opentasks/backend.js.map +1 -0
- package/dist/task/backend/opentasks/client.d.ts +337 -0
- package/dist/task/backend/opentasks/client.d.ts.map +1 -0
- package/dist/task/backend/opentasks/client.js +225 -0
- package/dist/task/backend/opentasks/client.js.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.js +195 -0
- package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
- package/dist/task/backend/opentasks/index.d.ts +21 -0
- package/dist/task/backend/opentasks/index.d.ts.map +1 -0
- package/dist/task/backend/opentasks/index.js +21 -0
- package/dist/task/backend/opentasks/index.js.map +1 -0
- package/dist/task/backend/opentasks/mapping.d.ts +48 -0
- package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
- package/dist/task/backend/opentasks/mapping.js +77 -0
- package/dist/task/backend/opentasks/mapping.js.map +1 -0
- package/dist/task/backend/types.d.ts +33 -53
- package/dist/task/backend/types.d.ts.map +1 -1
- package/dist/task/backend/types.js +7 -11
- package/dist/task/backend/types.js.map +1 -1
- package/dist/task/backend/unified-tool-provider.d.ts +57 -0
- package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
- package/dist/task/backend/unified-tool-provider.js +623 -0
- package/dist/task/backend/unified-tool-provider.js.map +1 -0
- package/dist/teams/index.d.ts +3 -1
- package/dist/teams/index.d.ts.map +1 -1
- package/dist/teams/index.js +2 -0
- package/dist/teams/index.js.map +1 -1
- package/dist/teams/seed-defaults.d.ts +20 -0
- package/dist/teams/seed-defaults.d.ts.map +1 -0
- package/dist/teams/seed-defaults.js +71 -0
- package/dist/teams/seed-defaults.js.map +1 -0
- package/dist/teams/team-loader.d.ts +7 -3
- package/dist/teams/team-loader.d.ts.map +1 -1
- package/dist/teams/team-loader.js +156 -164
- package/dist/teams/team-loader.js.map +1 -1
- package/dist/teams/team-manager.d.ts +112 -0
- package/dist/teams/team-manager.d.ts.map +1 -0
- package/dist/teams/team-manager.js +305 -0
- package/dist/teams/team-manager.js.map +1 -0
- package/dist/teams/team-runtime.d.ts +125 -19
- package/dist/teams/team-runtime.d.ts.map +1 -1
- package/dist/teams/team-runtime.js +529 -119
- package/dist/teams/team-runtime.js.map +1 -1
- package/dist/teams/types.d.ts +41 -151
- package/dist/teams/types.d.ts.map +1 -1
- package/dist/teams/types.js +2 -3
- package/dist/teams/types.js.map +1 -1
- package/docs/architecture.md +7 -6
- package/docs/configuration.md +26 -62
- package/docs/implementation-details.md +5 -5
- package/docs/implementation-summary.md +17 -17
- package/docs/plan-self-driving-support.md +4 -4
- package/docs/spec-self-driving-support.md +10 -10
- package/docs/team-templates.md +2 -2
- package/docs/teams.md +76 -3
- package/docs/troubleshooting.md +10 -11
- package/package.json +7 -4
- package/references/minimem/.claude/settings.json +7 -0
- package/references/minimem/.sudocode/issues.jsonl +18 -0
- package/references/minimem/.sudocode/specs.jsonl +1 -0
- package/references/minimem/CLAUDE.md +310 -0
- package/references/minimem/README.md +562 -0
- package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
- package/references/minimem/claude-plugin/.mcp.json +7 -0
- package/references/minimem/claude-plugin/README.md +158 -0
- package/references/minimem/claude-plugin/commands/recall.md +47 -0
- package/references/minimem/claude-plugin/commands/remember.md +41 -0
- package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
- package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
- package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
- package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
- package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
- package/references/minimem/media/banner.png +0 -0
- package/references/minimem/package-lock.json +5373 -0
- package/references/minimem/package.json +72 -0
- package/references/minimem/scripts/postbuild.js +35 -0
- package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
- package/references/minimem/src/__tests__/errors.test.ts +265 -0
- package/references/minimem/src/__tests__/helpers.ts +199 -0
- package/references/minimem/src/__tests__/internal.test.ts +407 -0
- package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
- package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
- package/references/minimem/src/__tests__/session.test.ts +190 -0
- package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
- package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
- package/references/minimem/src/cli/commands/append.ts +76 -0
- package/references/minimem/src/cli/commands/config.ts +262 -0
- package/references/minimem/src/cli/commands/conflicts.ts +413 -0
- package/references/minimem/src/cli/commands/daemon.ts +169 -0
- package/references/minimem/src/cli/commands/index.ts +12 -0
- package/references/minimem/src/cli/commands/init.ts +88 -0
- package/references/minimem/src/cli/commands/mcp.ts +177 -0
- package/references/minimem/src/cli/commands/push-pull.ts +213 -0
- package/references/minimem/src/cli/commands/search.ts +158 -0
- package/references/minimem/src/cli/commands/status.ts +84 -0
- package/references/minimem/src/cli/commands/sync-init.ts +290 -0
- package/references/minimem/src/cli/commands/sync.ts +70 -0
- package/references/minimem/src/cli/commands/upsert.ts +197 -0
- package/references/minimem/src/cli/config.ts +584 -0
- package/references/minimem/src/cli/index.ts +264 -0
- package/references/minimem/src/cli/shared.ts +161 -0
- package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
- package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
- package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
- package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
- package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
- package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
- package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
- package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
- package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
- package/references/minimem/src/cli/sync/central.ts +292 -0
- package/references/minimem/src/cli/sync/conflicts.ts +204 -0
- package/references/minimem/src/cli/sync/daemon.ts +407 -0
- package/references/minimem/src/cli/sync/detection.ts +138 -0
- package/references/minimem/src/cli/sync/index.ts +107 -0
- package/references/minimem/src/cli/sync/operations.ts +373 -0
- package/references/minimem/src/cli/sync/registry.ts +279 -0
- package/references/minimem/src/cli/sync/state.ts +355 -0
- package/references/minimem/src/cli/sync/validation.ts +206 -0
- package/references/minimem/src/cli/sync/watcher.ts +234 -0
- package/references/minimem/src/cli/version.ts +34 -0
- package/references/minimem/src/core/index.ts +9 -0
- package/references/minimem/src/core/indexer.ts +628 -0
- package/references/minimem/src/core/searcher.ts +221 -0
- package/references/minimem/src/db/schema.ts +183 -0
- package/references/minimem/src/db/sqlite-vec.ts +24 -0
- package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
- package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
- package/references/minimem/src/embeddings/batch-openai.ts +409 -0
- package/references/minimem/src/embeddings/embeddings.ts +434 -0
- package/references/minimem/src/index.ts +109 -0
- package/references/minimem/src/internal.ts +299 -0
- package/references/minimem/src/minimem.ts +1276 -0
- package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
- package/references/minimem/src/search/graph.ts +234 -0
- package/references/minimem/src/search/hybrid.ts +151 -0
- package/references/minimem/src/search/search.ts +256 -0
- package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
- package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
- package/references/minimem/src/server/mcp.ts +326 -0
- package/references/minimem/src/server/tools.ts +720 -0
- package/references/minimem/src/session.ts +460 -0
- package/references/minimem/tsconfig.json +19 -0
- package/references/minimem/tsup.config.ts +26 -0
- package/references/minimem/vitest.config.ts +24 -0
- package/references/openteams/.claude/settings.json +6 -0
- package/references/openteams/README.md +1 -0
- package/references/openteams/SKILL.md +341 -0
- package/references/openteams/design.md +411 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
- package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
- package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
- package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
- package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
- package/references/openteams/examples/bmad-method/team.yaml +161 -0
- package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
- package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
- package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
- package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
- package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
- package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
- package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
- package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
- package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
- package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
- package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
- package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
- package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
- package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
- package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
- package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
- package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
- package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
- package/references/openteams/examples/get-shit-done/team.yaml +154 -0
- package/references/openteams/package-lock.json +2181 -0
- package/references/openteams/package.json +48 -0
- package/references/openteams/schema/role.schema.json +125 -0
- package/references/openteams/schema/team.schema.json +284 -0
- package/references/openteams/src/cli/agent.ts +104 -0
- package/references/openteams/src/cli/cli.test.ts +381 -0
- package/references/openteams/src/cli/generate.ts +220 -0
- package/references/openteams/src/cli/message.ts +241 -0
- package/references/openteams/src/cli/task.ts +154 -0
- package/references/openteams/src/cli/team.ts +104 -0
- package/references/openteams/src/cli/template.ts +207 -0
- package/references/openteams/src/cli.ts +45 -0
- package/references/openteams/src/db/database.test.ts +185 -0
- package/references/openteams/src/db/database.ts +240 -0
- package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
- package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
- package/references/openteams/src/generators/package-generator.test.ts +129 -0
- package/references/openteams/src/generators/package-generator.ts +102 -0
- package/references/openteams/src/generators/skill-generator.test.ts +246 -0
- package/references/openteams/src/generators/skill-generator.ts +374 -0
- package/references/openteams/src/index.ts +104 -0
- package/references/openteams/src/services/agent-service.test.ts +158 -0
- package/references/openteams/src/services/agent-service.ts +84 -0
- package/references/openteams/src/services/communication-service.test.ts +455 -0
- package/references/openteams/src/services/communication-service.ts +371 -0
- package/references/openteams/src/services/message-service.test.ts +342 -0
- package/references/openteams/src/services/message-service.ts +203 -0
- package/references/openteams/src/services/task-service.test.ts +434 -0
- package/references/openteams/src/services/task-service.ts +239 -0
- package/references/openteams/src/services/team-service.test.ts +181 -0
- package/references/openteams/src/services/team-service.ts +139 -0
- package/references/openteams/src/services/template-service.test.ts +306 -0
- package/references/openteams/src/services/template-service.ts +182 -0
- package/references/openteams/src/spawner/acp-factory.ts +96 -0
- package/references/openteams/src/spawner/interface.ts +31 -0
- package/references/openteams/src/spawner/mock.test.ts +93 -0
- package/references/openteams/src/spawner/mock.ts +59 -0
- package/references/openteams/src/template/loader.test.ts +1319 -0
- package/references/openteams/src/template/loader.ts +698 -0
- package/references/openteams/src/template/types.ts +200 -0
- package/references/openteams/src/types.ts +205 -0
- package/references/openteams/tsconfig.json +18 -0
- package/references/openteams/vitest.config.ts +9 -0
- package/references/skill-tree/.claude/settings.json +6 -0
- package/references/skill-tree/.sudocode/issues.jsonl +11 -0
- package/references/skill-tree/.sudocode/specs.jsonl +1 -0
- package/references/skill-tree/CLAUDE.md +150 -0
- package/references/skill-tree/README.md +324 -0
- package/references/skill-tree/docs/GAPS_v1.md +221 -0
- package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
- package/references/skill-tree/docs/TODOS.md +91 -0
- package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
- package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
- package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
- package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
- package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
- package/references/skill-tree/docs/scraper/README.md +170 -0
- package/references/skill-tree/examples/basic-usage.ts +190 -0
- package/references/skill-tree/package-lock.json +1509 -0
- package/references/skill-tree/package.json +66 -0
- package/references/skill-tree/scraper/README.md +123 -0
- package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
- package/references/skill-tree/scraper/docs/PLAN.md +336 -0
- package/references/skill-tree/scraper/drizzle.config.ts +10 -0
- package/references/skill-tree/scraper/package-lock.json +6329 -0
- package/references/skill-tree/scraper/package.json +68 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
- package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
- package/references/skill-tree/scraper/tsup.config.ts +14 -0
- package/references/skill-tree/scraper/vitest.config.ts +17 -0
- package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
- package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
- package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
- package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
- package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
- package/references/skill-tree/test/run-all.ts +106 -0
- package/references/skill-tree/test/utils.ts +128 -0
- package/references/skill-tree/vitest.config.ts +16 -0
- package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
- package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
- package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
- package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
- package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
- package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
- package/src/acp/__tests__/integration.test.ts +56 -31
- package/src/acp/__tests__/macro-agent.test.ts +16 -7
- package/src/acp/macro-agent.ts +170 -36
- package/src/acp/types.ts +46 -1
- package/src/agent/__tests__/agent-manager.test.ts +228 -2
- package/src/agent/agent-manager.ts +809 -285
- package/src/agent/types.ts +12 -1
- package/src/api/__tests__/server.test.ts +203 -4
- package/src/api/server.ts +169 -10
- package/src/api/types.ts +3 -1
- package/src/auth/__tests__/token.test.ts +100 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/token.ts +82 -0
- package/src/cli/__tests__/acp.test.ts +1 -1
- package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
- package/src/cli/acp.ts +197 -72
- package/src/cli/index.ts +125 -15
- package/src/cli/mcp.ts +315 -197
- package/src/cli/parse-args.ts +54 -0
- package/src/cli/stable-instance-id.ts +14 -0
- package/src/config/project-config.ts +214 -27
- package/src/index.ts +3 -0
- package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
- package/src/lifecycle/__tests__/handlers.test.ts +53 -0
- package/src/lifecycle/handlers/index.ts +25 -8
- package/src/lifecycle/types.ts +3 -0
- package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
- package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
- package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
- package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
- package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
- package/src/map/adapter/__tests__/event-log.test.ts +527 -0
- package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
- package/src/map/adapter/__tests__/extensions.test.ts +408 -0
- package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
- package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
- package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
- package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
- package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
- package/src/map/adapter/acp-over-map.ts +678 -66
- package/src/map/adapter/connection-manager.ts +3 -0
- package/src/map/adapter/event-log.ts +208 -0
- package/src/map/adapter/event-translator.ts +6 -6
- package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
- package/src/map/adapter/extensions/index.ts +96 -0
- package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
- package/src/map/adapter/extensions/streams.ts +839 -0
- package/src/map/adapter/extensions/task.ts +11 -0
- package/src/map/adapter/extensions/update-metadata.ts +126 -0
- package/src/map/adapter/index.ts +33 -0
- package/src/map/adapter/interface.ts +2 -0
- package/src/map/adapter/map-adapter.ts +312 -47
- package/src/map/adapter/subscription-manager.ts +5 -1
- package/src/map/adapter/types.ts +10 -1
- package/src/mcp/__tests__/map-client.test.ts +386 -0
- package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
- package/src/mcp/__tests__/mcp-server.test.ts +100 -1
- package/src/mcp/map-client.ts +177 -0
- package/src/mcp/mcp-server.ts +205 -103
- package/src/mcp/tools/done.ts +19 -0
- package/src/mcp/types.ts +6 -1
- package/src/metrics/metrics.ts +1 -1
- package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
- package/src/roles/__tests__/config-loader.test.ts +7 -7
- package/src/roles/builtin/coordinator.ts +2 -0
- package/src/roles/builtin/integrator.ts +2 -0
- package/src/roles/builtin/worker.ts +3 -0
- package/src/roles/capabilities.ts +28 -7
- package/src/roles/config-loader.ts +8 -7
- package/src/roles/registry.ts +2 -2
- package/src/roles/types.ts +7 -0
- package/src/server/__tests__/combined-server.test.ts +94 -21
- package/src/server/combined-server.ts +203 -33
- package/src/steering/__tests__/steering-integration.test.ts +1 -1
- package/src/store/__tests__/event-store-oob.test.ts +109 -0
- package/src/store/__tests__/event-store.test.ts +196 -1
- package/src/store/__tests__/instance.test.ts +3 -3
- package/src/store/event-store.ts +92 -23
- package/src/store/instance.ts +2 -2
- package/src/store/types/agents.ts +20 -0
- package/src/store/types/events.ts +1 -1
- package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
- package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
- package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
- package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
- package/src/task/backend/index.ts +156 -106
- package/src/task/backend/memory.ts +4 -0
- package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
- package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
- package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
- package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
- package/src/task/backend/opentasks/backend.ts +1323 -0
- package/src/task/backend/opentasks/client.ts +652 -0
- package/src/task/backend/opentasks/daemon-manager.ts +256 -0
- package/src/task/backend/opentasks/index.ts +69 -0
- package/src/task/backend/opentasks/mapping.ts +94 -0
- package/src/task/backend/types.ts +42 -66
- package/src/task/backend/unified-tool-provider.ts +779 -0
- package/src/teams/CLAUDE.md +180 -0
- package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
- package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
- package/src/teams/__tests__/team-manager.test.ts +814 -0
- package/src/teams/__tests__/team-system.test.ts +1291 -8
- package/src/teams/index.ts +21 -3
- package/src/teams/seed-defaults.ts +79 -0
- package/src/teams/team-loader.ts +202 -236
- package/src/teams/team-manager.ts +387 -0
- package/src/teams/team-runtime.ts +592 -121
- package/src/teams/types.ts +99 -200
- package/test_fixtures/README.md +2 -3
- package/test_fixtures/fixtures/index.ts +0 -3
- package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
- package/test_fixtures/fixtures/repos/index.ts +1 -3
- package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
- package/test_fixtures/fixtures/repos/types.ts +0 -11
- package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
- package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
- package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
- package/vitest.config.ts +1 -1
- package/vitest.e2e.config.ts +1 -1
- package/vitest.setup.ts +1 -30
- package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
- package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
- package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
- package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
- package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
- package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
- package/.macro-agent/teams/self-driving/team.yaml +0 -103
- package/.macro-agent/teams/structured/prompts/developer.md +0 -26
- package/.macro-agent/teams/structured/prompts/lead.md +0 -25
- package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
- package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
- package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
- package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
- package/.macro-agent/teams/structured/team.yaml +0 -89
- package/docs/sudocode-integration.md +0 -383
- package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
- package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
- package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
- package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
- package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
- package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
- package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
- package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
- package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
- package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
- package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
- package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
- package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
- package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
- package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
- package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
- package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
- package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
- package/src/task/backend/sudocode/backend.ts +0 -1237
- package/src/task/backend/sudocode/client.ts +0 -515
- package/src/task/backend/sudocode/index.ts +0 -120
- package/src/task/backend/sudocode/mapping.ts +0 -93
- package/src/task/backend/sudocode/server-client.ts +0 -522
- package/src/task/backend/sudocode/standalone-client.ts +0 -623
- package/src/task/backend/sudocode/sync-policy.ts +0 -387
- package/src/task/backend/sudocode/tools.ts +0 -896
- package/src/task/backend/tool-provider.ts +0 -506
- package/test_fixtures/fixtures/sudocode/index.ts +0 -29
- package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
- package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Team Runtime
|
|
3
3
|
*
|
|
4
|
-
* Wires a loaded
|
|
4
|
+
* Wires a loaded team template into the running system: registers roles,
|
|
5
5
|
* sets up integration strategy, configures communication topology,
|
|
6
6
|
* and manages the team lifecycle.
|
|
7
7
|
*
|
|
@@ -11,15 +11,22 @@
|
|
|
11
11
|
import type { EventStore } from "../store/event-store.js";
|
|
12
12
|
import type { MessageRouter } from "../router/message-router.js";
|
|
13
13
|
import type { AgentManager, SpawnInterceptor } from "../agent/agent-manager.js";
|
|
14
|
+
import type {
|
|
15
|
+
SignalFilter,
|
|
16
|
+
EmissionValidator,
|
|
17
|
+
EmissionValidatorResult,
|
|
18
|
+
} from "../router/message-router.js";
|
|
14
19
|
import type { RoleRegistry } from "../roles/types.js";
|
|
15
20
|
import type { SpawnAgentOptions } from "../agent/types.js";
|
|
16
21
|
import type { AgentId } from "../store/types/index.js";
|
|
17
22
|
import type {
|
|
18
23
|
TeamManifest,
|
|
24
|
+
MacroResolvedTemplate,
|
|
19
25
|
McpServerEntry,
|
|
20
26
|
PeerConnection,
|
|
21
27
|
} from "./types.js";
|
|
22
28
|
import type { IntegrationStrategy } from "../workspace/strategies/types.js";
|
|
29
|
+
import { WORKSPACE_CAPABILITIES } from "../roles/capabilities.js";
|
|
23
30
|
|
|
24
31
|
// =============================================================================
|
|
25
32
|
// Types
|
|
@@ -29,6 +36,10 @@ export interface TeamServices {
|
|
|
29
36
|
agentManager: AgentManager;
|
|
30
37
|
messageRouter: MessageRouter;
|
|
31
38
|
eventStore: EventStore;
|
|
39
|
+
/** Optional workspace manager for merge queue wiring */
|
|
40
|
+
workspaceManager?: import("../workspace/types.js").WorkspaceManager;
|
|
41
|
+
/** Optional task backend for auto-scaling queue depth checks */
|
|
42
|
+
taskBackend?: import("../task/backend/types.js").TaskBackend;
|
|
32
43
|
}
|
|
33
44
|
|
|
34
45
|
export interface TeamBootstrapResult {
|
|
@@ -36,6 +47,45 @@ export interface TeamBootstrapResult {
|
|
|
36
47
|
companionIds: string[];
|
|
37
48
|
}
|
|
38
49
|
|
|
50
|
+
// =============================================================================
|
|
51
|
+
// Conversion: TeamManifest → MacroResolvedTemplate
|
|
52
|
+
// =============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Convert a legacy TeamManifest (with _ prefixed fields) to MacroResolvedTemplate.
|
|
56
|
+
* Used for backward compatibility when TeamRuntime receives a TeamManifest.
|
|
57
|
+
*/
|
|
58
|
+
function manifestToResolved(manifest: TeamManifest): MacroResolvedTemplate {
|
|
59
|
+
return {
|
|
60
|
+
template: {
|
|
61
|
+
manifest: {
|
|
62
|
+
name: manifest.name,
|
|
63
|
+
description: manifest.description,
|
|
64
|
+
version: manifest.version,
|
|
65
|
+
roles: manifest.roles,
|
|
66
|
+
topology: manifest.topology,
|
|
67
|
+
communication: manifest.communication,
|
|
68
|
+
},
|
|
69
|
+
roles: new Map(), // Not used — macro-agent uses resolvedRoles
|
|
70
|
+
prompts: new Map(), // Prompts are in _loadedPrompts
|
|
71
|
+
mcpServers: manifest._mcpServers,
|
|
72
|
+
sourcePath: "",
|
|
73
|
+
},
|
|
74
|
+
resolvedRoles: manifest._resolvedRoles,
|
|
75
|
+
macroAgent: manifest.macro_agent,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check if input is a MacroResolvedTemplate (has `template` field)
|
|
81
|
+
* vs a legacy TeamManifest (has `_resolvedRoles` field).
|
|
82
|
+
*/
|
|
83
|
+
function isMacroResolvedTemplate(
|
|
84
|
+
input: TeamManifest | MacroResolvedTemplate
|
|
85
|
+
): input is MacroResolvedTemplate {
|
|
86
|
+
return "template" in input && "resolvedRoles" in input;
|
|
87
|
+
}
|
|
88
|
+
|
|
39
89
|
// =============================================================================
|
|
40
90
|
// TeamRuntime
|
|
41
91
|
// =============================================================================
|
|
@@ -46,6 +96,18 @@ export class TeamRuntime {
|
|
|
46
96
|
private roleRegistry: RoleRegistry;
|
|
47
97
|
private lifecycleUnsubscribe?: () => void;
|
|
48
98
|
private integrationStrategy?: IntegrationStrategy;
|
|
99
|
+
private scalingTimer?: ReturnType<typeof setInterval>;
|
|
100
|
+
private lastScaleUpTime = 0;
|
|
101
|
+
private teamStreamId?: string;
|
|
102
|
+
private mergeQueueUnsub?: () => void;
|
|
103
|
+
private mergeRequestPollTimer?: ReturnType<typeof setInterval>;
|
|
104
|
+
private lastMergeRequestSeen = 0;
|
|
105
|
+
|
|
106
|
+
/** The resolved template (canonical internal representation) */
|
|
107
|
+
private readonly resolved: MacroResolvedTemplate;
|
|
108
|
+
|
|
109
|
+
/** Legacy loaded prompts map (path → content) for backward compat */
|
|
110
|
+
private readonly loadedPrompts: Map<string, string>;
|
|
49
111
|
|
|
50
112
|
/** Role name → spawned agent ID mapping (populated during bootstrap) */
|
|
51
113
|
private roleAgentMap = new Map<string, AgentId>();
|
|
@@ -59,16 +121,43 @@ export class TeamRuntime {
|
|
|
59
121
|
/** Reverse mapping: agent ID → role name (for signal filter lookups) */
|
|
60
122
|
private agentRoleMap = new Map<AgentId, string>();
|
|
61
123
|
|
|
124
|
+
/** Pre-computed per-role allowed signals from channel subscriptions */
|
|
125
|
+
private roleAllowedSignals = new Map<string, Set<string> | "all">();
|
|
126
|
+
|
|
62
127
|
/** Lifecycle unsubscribe for deferred peer wiring */
|
|
63
128
|
private peerWiringUnsubscribe?: () => void;
|
|
64
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Create a TeamRuntime.
|
|
132
|
+
*
|
|
133
|
+
* Accepts either a MacroResolvedTemplate (new) or a TeamManifest (legacy).
|
|
134
|
+
* Internally always uses MacroResolvedTemplate.
|
|
135
|
+
*/
|
|
65
136
|
constructor(
|
|
66
|
-
|
|
137
|
+
input: TeamManifest | MacroResolvedTemplate,
|
|
67
138
|
private readonly services: TeamServices
|
|
68
139
|
) {
|
|
140
|
+
this.resolved = isMacroResolvedTemplate(input)
|
|
141
|
+
? input
|
|
142
|
+
: manifestToResolved(input);
|
|
143
|
+
|
|
144
|
+
// Extract loaded prompts from legacy manifest if available
|
|
145
|
+
this.loadedPrompts = !isMacroResolvedTemplate(input)
|
|
146
|
+
? input._loadedPrompts
|
|
147
|
+
: new Map();
|
|
148
|
+
|
|
69
149
|
this.roleRegistry = services.agentManager.getRoleRegistry();
|
|
70
150
|
}
|
|
71
151
|
|
|
152
|
+
// Convenience accessors
|
|
153
|
+
private get manifest() {
|
|
154
|
+
return this.resolved.template.manifest;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private get communication() {
|
|
158
|
+
return (this.manifest.communication ?? {}) as NonNullable<typeof this.manifest.communication>;
|
|
159
|
+
}
|
|
160
|
+
|
|
72
161
|
// ─────────────────────────────────────────────────────────────
|
|
73
162
|
// Initialization
|
|
74
163
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -78,25 +167,41 @@ export class TeamRuntime {
|
|
|
78
167
|
*
|
|
79
168
|
* 1. Register team roles into RoleRegistry
|
|
80
169
|
* 2. Store team_config event in EventStore (for MCP subprocess discovery)
|
|
81
|
-
* 3.
|
|
170
|
+
* 3. Instantiate integration strategy
|
|
171
|
+
*
|
|
172
|
+
* Note: Does NOT install spawn interceptor, signal filter, or emission
|
|
173
|
+
* validator on services. Call installOnServices() for standalone use,
|
|
174
|
+
* or let TeamManager handle composite installation.
|
|
82
175
|
*/
|
|
83
|
-
async initialize(): Promise<void> {
|
|
84
|
-
const {
|
|
176
|
+
async initialize(options?: { teamInstanceId?: string }): Promise<void> {
|
|
177
|
+
const { eventStore } = this.services;
|
|
85
178
|
|
|
86
179
|
// 1. Register team roles into RoleRegistry (custom layer, highest priority)
|
|
87
|
-
for (const [, resolved] of this.
|
|
88
|
-
|
|
180
|
+
for (const [, resolved] of this.resolved.resolvedRoles) {
|
|
181
|
+
const rd = resolved.roleDefinition;
|
|
182
|
+
const existing = this.roleRegistry.getRole(rd.name);
|
|
183
|
+
if (existing) {
|
|
184
|
+
const existingCaps = [...existing.capabilities].sort();
|
|
185
|
+
const newCaps = [...rd.capabilities].sort();
|
|
186
|
+
if (existingCaps.length !== newCaps.length || existingCaps.some((c, i) => c !== newCaps[i])) {
|
|
187
|
+
console.warn(
|
|
188
|
+
`[TeamRuntime] Role '${rd.name}' conflict: team '${this.manifest.name}' re-registers with different capabilities. ` +
|
|
189
|
+
`Existing: [${existingCaps.join(", ")}], New: [${newCaps.join(", ")}]`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
this.roleRegistry.registerRole(rd);
|
|
89
194
|
}
|
|
90
195
|
|
|
91
196
|
// 2. Store team config in EventStore for cross-process access (RD2)
|
|
92
|
-
const taskMode = this.
|
|
93
|
-
const strategyName = this.
|
|
94
|
-
const strategyConfig = this.
|
|
95
|
-
const enforcement = this.
|
|
197
|
+
const taskMode = this.resolved.macroAgent.task_assignment?.mode ?? "push";
|
|
198
|
+
const strategyName = this.resolved.macroAgent.integration?.strategy ?? "queue";
|
|
199
|
+
const strategyConfig = this.resolved.macroAgent.integration?.config ?? {};
|
|
200
|
+
const enforcement = this.communication.enforcement ?? "permissive";
|
|
96
201
|
|
|
97
202
|
// Serialize resolved roles for MCP subprocess capability checks
|
|
98
203
|
const serializedRoles: Record<string, { name: string; capabilities: string[]; tools?: object; lifecycle?: object; description?: string }> = {};
|
|
99
|
-
for (const [name, resolved] of this.
|
|
204
|
+
for (const [name, resolved] of this.resolved.resolvedRoles) {
|
|
100
205
|
const rd = resolved.roleDefinition;
|
|
101
206
|
serializedRoles[name] = {
|
|
102
207
|
name: rd.name,
|
|
@@ -115,32 +220,40 @@ export class TeamRuntime {
|
|
|
115
220
|
summary: `Team '${this.manifest.name}' initialized`,
|
|
116
221
|
team_config: {
|
|
117
222
|
teamName: this.manifest.name,
|
|
223
|
+
...(options?.teamInstanceId && { team_instance: options.teamInstanceId }),
|
|
118
224
|
strategy: strategyName,
|
|
119
225
|
strategyConfig,
|
|
120
226
|
taskMode,
|
|
121
227
|
enforcement,
|
|
122
228
|
roles: serializedRoles,
|
|
123
|
-
peerRoutes: this.
|
|
124
|
-
emissions: this.
|
|
229
|
+
peerRoutes: this.communication.routing?.peers ?? [],
|
|
230
|
+
emissions: this.communication.emissions ?? {},
|
|
125
231
|
},
|
|
126
232
|
},
|
|
127
233
|
});
|
|
128
234
|
|
|
129
235
|
await eventStore.persist();
|
|
130
236
|
|
|
131
|
-
//
|
|
237
|
+
// 3. Instantiate integration strategy and call lifecycle hook
|
|
132
238
|
try {
|
|
133
239
|
const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
|
|
134
240
|
this.integrationStrategy = defaultStrategyRegistry.get(strategyName, strategyConfig as Record<string, unknown>);
|
|
135
241
|
if (this.integrationStrategy.initialize) {
|
|
136
242
|
await this.integrationStrategy.initialize();
|
|
137
243
|
}
|
|
244
|
+
|
|
245
|
+
// Wire merge queue to queue strategy if workspace manager is available
|
|
246
|
+
if (
|
|
247
|
+
this.services.workspaceManager &&
|
|
248
|
+
strategyName === "queue" &&
|
|
249
|
+
"setMergeQueue" in this.integrationStrategy
|
|
250
|
+
) {
|
|
251
|
+
const mergeQueue = this.services.workspaceManager.getMergeQueue();
|
|
252
|
+
(this.integrationStrategy as { setMergeQueue(q: typeof mergeQueue): void }).setMergeQueue(mergeQueue);
|
|
253
|
+
}
|
|
138
254
|
} catch {
|
|
139
255
|
// Strategy instantiation is best-effort — queue strategy needs merge queue set later
|
|
140
256
|
}
|
|
141
|
-
|
|
142
|
-
// 3. Register spawn interceptor
|
|
143
|
-
agentManager.setSpawnInterceptor(this.createSpawnInterceptor());
|
|
144
257
|
}
|
|
145
258
|
|
|
146
259
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -149,9 +262,13 @@ export class TeamRuntime {
|
|
|
149
262
|
|
|
150
263
|
/**
|
|
151
264
|
* Spawn root and companion agents per the team topology.
|
|
265
|
+
*
|
|
266
|
+
* Populates internal state (agentRoleMap, peerSignalFilters) used by
|
|
267
|
+
* createSignalFilter() and createEmissionValidator(). Call installOnServices()
|
|
268
|
+
* after bootstrap for standalone use, or let TeamManager handle installation.
|
|
152
269
|
*/
|
|
153
270
|
async bootstrap(): Promise<TeamBootstrapResult> {
|
|
154
|
-
const { agentManager
|
|
271
|
+
const { agentManager } = this.services;
|
|
155
272
|
const { topology } = this.manifest;
|
|
156
273
|
|
|
157
274
|
// 1. Spawn root agent
|
|
@@ -170,6 +287,10 @@ export class TeamRuntime {
|
|
|
170
287
|
});
|
|
171
288
|
this.rootAgentId = root.id;
|
|
172
289
|
|
|
290
|
+
// 1b. Set up workspace integration BEFORE companions spawn,
|
|
291
|
+
// so the spawn interceptor has teamStreamId for workspace injection
|
|
292
|
+
this.setupWorkspaceIntegration(root.id as AgentId);
|
|
293
|
+
|
|
173
294
|
// 2. Spawn companions (peers, not children)
|
|
174
295
|
const companionIds: string[] = [];
|
|
175
296
|
for (const companion of topology.companions ?? []) {
|
|
@@ -197,15 +318,15 @@ export class TeamRuntime {
|
|
|
197
318
|
}
|
|
198
319
|
this.wirePeerRoutes();
|
|
199
320
|
|
|
200
|
-
// 4.
|
|
201
|
-
this.
|
|
202
|
-
|
|
203
|
-
// 5. Install emission validator on message router
|
|
204
|
-
this.installEmissionValidator();
|
|
321
|
+
// 4. Pre-compute role allowed signals (used by createSignalFilter)
|
|
322
|
+
this.computeRoleAllowedSignals();
|
|
205
323
|
|
|
206
|
-
//
|
|
324
|
+
// 5. Set up continuation monitoring for daemon agents (P4.2)
|
|
207
325
|
this.monitorContinuations();
|
|
208
326
|
|
|
327
|
+
// 6. Set up auto-scaling monitoring
|
|
328
|
+
this.monitorScaling();
|
|
329
|
+
|
|
209
330
|
return {
|
|
210
331
|
rootId: root.id,
|
|
211
332
|
companionIds,
|
|
@@ -217,10 +338,13 @@ export class TeamRuntime {
|
|
|
217
338
|
// ─────────────────────────────────────────────────────────────
|
|
218
339
|
|
|
219
340
|
/**
|
|
220
|
-
* Tear down team:
|
|
341
|
+
* Tear down team: stop continuation monitoring, clean up strategy.
|
|
342
|
+
*
|
|
343
|
+
* Note: Does NOT clear spawn interceptor or filters on services.
|
|
344
|
+
* The caller (TeamManager or standalone code) is responsible for
|
|
345
|
+
* removing the interceptor/filters from shared services.
|
|
221
346
|
*/
|
|
222
347
|
async teardown(): Promise<void> {
|
|
223
|
-
this.services.agentManager.setSpawnInterceptor(null);
|
|
224
348
|
if (this.lifecycleUnsubscribe) {
|
|
225
349
|
this.lifecycleUnsubscribe();
|
|
226
350
|
this.lifecycleUnsubscribe = undefined;
|
|
@@ -229,6 +353,18 @@ export class TeamRuntime {
|
|
|
229
353
|
this.peerWiringUnsubscribe();
|
|
230
354
|
this.peerWiringUnsubscribe = undefined;
|
|
231
355
|
}
|
|
356
|
+
if (this.scalingTimer) {
|
|
357
|
+
clearInterval(this.scalingTimer);
|
|
358
|
+
this.scalingTimer = undefined;
|
|
359
|
+
}
|
|
360
|
+
if (this.mergeQueueUnsub) {
|
|
361
|
+
this.mergeQueueUnsub();
|
|
362
|
+
this.mergeQueueUnsub = undefined;
|
|
363
|
+
}
|
|
364
|
+
if (this.mergeRequestPollTimer) {
|
|
365
|
+
clearInterval(this.mergeRequestPollTimer);
|
|
366
|
+
this.mergeRequestPollTimer = undefined;
|
|
367
|
+
}
|
|
232
368
|
// Call strategy lifecycle close hook
|
|
233
369
|
if (this.integrationStrategy?.close) {
|
|
234
370
|
try {
|
|
@@ -245,17 +381,31 @@ export class TeamRuntime {
|
|
|
245
381
|
|
|
246
382
|
/** Get task assignment mode */
|
|
247
383
|
getTaskMode(): "push" | "pull" {
|
|
248
|
-
return this.
|
|
384
|
+
return this.resolved.macroAgent.task_assignment?.mode ?? "push";
|
|
249
385
|
}
|
|
250
386
|
|
|
251
387
|
/** Get integration strategy name */
|
|
252
388
|
getStrategyName(): string {
|
|
253
|
-
return this.
|
|
389
|
+
return this.resolved.macroAgent.integration?.strategy ?? "queue";
|
|
254
390
|
}
|
|
255
391
|
|
|
256
392
|
/** Get the active manifest (for API) */
|
|
257
393
|
getManifest(): TeamManifest {
|
|
258
|
-
|
|
394
|
+
// Build a backward-compatible TeamManifest from the resolved template
|
|
395
|
+
return {
|
|
396
|
+
...this.manifest,
|
|
397
|
+
description: this.manifest.description ?? "",
|
|
398
|
+
communication: this.communication,
|
|
399
|
+
macro_agent: this.resolved.macroAgent,
|
|
400
|
+
_resolvedRoles: this.resolved.resolvedRoles,
|
|
401
|
+
_loadedPrompts: this.loadedPrompts,
|
|
402
|
+
_mcpServers: this.resolved.template.mcpServers,
|
|
403
|
+
} as TeamManifest;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/** Get the resolved template */
|
|
407
|
+
getResolvedTemplate(): MacroResolvedTemplate {
|
|
408
|
+
return this.resolved;
|
|
259
409
|
}
|
|
260
410
|
|
|
261
411
|
/** Get root agent ID (after bootstrap) */
|
|
@@ -273,11 +423,32 @@ export class TeamRuntime {
|
|
|
273
423
|
return this.integrationStrategy;
|
|
274
424
|
}
|
|
275
425
|
|
|
426
|
+
/** Get team-wide integration stream ID (after bootstrap) */
|
|
427
|
+
getTeamStreamId(): string | undefined {
|
|
428
|
+
return this.teamStreamId;
|
|
429
|
+
}
|
|
430
|
+
|
|
276
431
|
/** Get signal filters for peer connections (for use by signal filtering - i-3o8g) */
|
|
277
432
|
getPeerSignalFilters(): ReadonlyMap<string, string[]> {
|
|
278
433
|
return this.peerSignalFilters;
|
|
279
434
|
}
|
|
280
435
|
|
|
436
|
+
/** Get the agent → role mapping (for TeamManager agent-team lookups) */
|
|
437
|
+
getAgentRoleMap(): ReadonlyMap<AgentId, string> {
|
|
438
|
+
return this.agentRoleMap;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/** Register an agent's role mapping (for TeamManager to track dynamically spawned agents) */
|
|
442
|
+
registerAgent(agentId: AgentId, roleName: string): void {
|
|
443
|
+
this.agentRoleMap.set(agentId, roleName);
|
|
444
|
+
this.roleAgentMap.set(roleName, agentId);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/** Check if this team owns a given agent */
|
|
448
|
+
hasAgent(agentId: string): boolean {
|
|
449
|
+
return this.agentRoleMap.has(agentId as AgentId);
|
|
450
|
+
}
|
|
451
|
+
|
|
281
452
|
// ─────────────────────────────────────────────────────────────
|
|
282
453
|
// Continuation Monitoring (P4.2)
|
|
283
454
|
// ─────────────────────────────────────────────────────────────
|
|
@@ -289,7 +460,7 @@ export class TeamRuntime {
|
|
|
289
460
|
* lifecycle config enables continuations, automatically spawn a continuation.
|
|
290
461
|
*/
|
|
291
462
|
private monitorContinuations(): void {
|
|
292
|
-
const lifecycleConfig = this.
|
|
463
|
+
const lifecycleConfig = this.resolved.macroAgent.lifecycle;
|
|
293
464
|
if (!lifecycleConfig?.continuations?.enabled) return;
|
|
294
465
|
|
|
295
466
|
const { agentManager } = this.services;
|
|
@@ -329,19 +500,252 @@ export class TeamRuntime {
|
|
|
329
500
|
});
|
|
330
501
|
}
|
|
331
502
|
|
|
503
|
+
// ─────────────────────────────────────────────────────────────
|
|
504
|
+
// Auto-Scaling
|
|
505
|
+
// ─────────────────────────────────────────────────────────────
|
|
506
|
+
|
|
507
|
+
/** Minimum interval between scale-up actions (ms) */
|
|
508
|
+
private static readonly SCALE_COOLDOWN_MS = 10_000;
|
|
509
|
+
|
|
510
|
+
/** Default scaling check interval (ms) */
|
|
511
|
+
private static readonly SCALE_CHECK_INTERVAL_MS = 5_000;
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Monitor task queue depth and auto-scale workers.
|
|
515
|
+
*
|
|
516
|
+
* Follows the same lifecycle pattern as monitorContinuations().
|
|
517
|
+
* Only active when `scaling.scale_on === "task_queue_depth"` and
|
|
518
|
+
* a task backend is available.
|
|
519
|
+
*/
|
|
520
|
+
private monitorScaling(): void {
|
|
521
|
+
const scalingConfig = this.resolved.macroAgent.lifecycle?.scaling;
|
|
522
|
+
if (!scalingConfig || scalingConfig.scale_on !== "task_queue_depth") return;
|
|
523
|
+
|
|
524
|
+
const { taskBackend } = this.services;
|
|
525
|
+
if (!taskBackend?.listClaimable) return; // Need claimable task counting
|
|
526
|
+
|
|
527
|
+
const maxWorkers = scalingConfig.max_workers ?? Infinity;
|
|
528
|
+
const minWorkers = scalingConfig.min_workers ?? 0;
|
|
529
|
+
|
|
530
|
+
// Determine which role names are worker-derived (for counting active workers)
|
|
531
|
+
const workerRoleNames = new Set<string>();
|
|
532
|
+
for (const [name, resolved] of this.resolved.resolvedRoles) {
|
|
533
|
+
if (resolved.baseRole === "worker") {
|
|
534
|
+
workerRoleNames.add(name);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
if (workerRoleNames.size === 0) return; // No worker roles to scale
|
|
538
|
+
|
|
539
|
+
// Pick the first worker role for spawning (most common pattern: single worker role)
|
|
540
|
+
const spawnRole = [...workerRoleNames][0];
|
|
541
|
+
|
|
542
|
+
this.scalingTimer = setInterval(async () => {
|
|
543
|
+
try {
|
|
544
|
+
// Count claimable tasks
|
|
545
|
+
const claimable = await taskBackend.listClaimable!();
|
|
546
|
+
const pendingCount = claimable.length;
|
|
547
|
+
|
|
548
|
+
// Count active workers in this team
|
|
549
|
+
const allAgents = this.services.agentManager.list({ state: "running" });
|
|
550
|
+
let activeWorkers = 0;
|
|
551
|
+
for (const agent of allAgents) {
|
|
552
|
+
if (agent.role && workerRoleNames.has(agent.role) && this.agentRoleMap.has(agent.id as AgentId)) {
|
|
553
|
+
activeWorkers++;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Scale up: more pending tasks than active workers, under max cap
|
|
558
|
+
if (pendingCount > activeWorkers && activeWorkers < maxWorkers) {
|
|
559
|
+
const now = Date.now();
|
|
560
|
+
if (now - this.lastScaleUpTime < TeamRuntime.SCALE_COOLDOWN_MS) {
|
|
561
|
+
return; // Cooldown not elapsed
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (!this.rootAgentId) return; // No root to spawn from
|
|
565
|
+
|
|
566
|
+
try {
|
|
567
|
+
await this.services.agentManager.spawn({
|
|
568
|
+
task: `[${this.manifest.name}] auto-scaled ${spawnRole}`,
|
|
569
|
+
role: spawnRole,
|
|
570
|
+
parent: this.rootAgentId,
|
|
571
|
+
});
|
|
572
|
+
this.lastScaleUpTime = now;
|
|
573
|
+
|
|
574
|
+
// Emit scaling event for observability
|
|
575
|
+
this.services.eventStore.emit({
|
|
576
|
+
type: "status",
|
|
577
|
+
source: { agent_id: "system" },
|
|
578
|
+
payload: {
|
|
579
|
+
status_type: "scaling",
|
|
580
|
+
summary: `Auto-scaled: spawned ${spawnRole} (pending=${pendingCount}, active=${activeWorkers}, max=${maxWorkers})`,
|
|
581
|
+
},
|
|
582
|
+
});
|
|
583
|
+
} catch {
|
|
584
|
+
// Spawn failed — will retry on next tick
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Scale down is handled by idle_drain: workers self-terminate after idle_timeout_s
|
|
589
|
+
// No active termination needed from the scaling monitor
|
|
590
|
+
} catch {
|
|
591
|
+
// Best-effort — don't crash the scaling loop
|
|
592
|
+
}
|
|
593
|
+
}, TeamRuntime.SCALE_CHECK_INTERVAL_MS);
|
|
594
|
+
|
|
595
|
+
// Ensure timer doesn't prevent process exit
|
|
596
|
+
if (this.scalingTimer.unref) {
|
|
597
|
+
this.scalingTimer.unref();
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// ─────────────────────────────────────────────────────────────
|
|
602
|
+
// Workspace Integration
|
|
603
|
+
// ─────────────────────────────────────────────────────────────
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Create the team-wide integration stream and subscribe to merge queue events.
|
|
607
|
+
*
|
|
608
|
+
* When a worker submits to the merge queue, the integrator agent is
|
|
609
|
+
* automatically prompted to process it.
|
|
610
|
+
*/
|
|
611
|
+
private setupWorkspaceIntegration(rootAgentId: AgentId): void {
|
|
612
|
+
const { workspaceManager } = this.services;
|
|
613
|
+
if (!workspaceManager || !this.integrationStrategy) return;
|
|
614
|
+
|
|
615
|
+
// Create integration stream owned by root agent
|
|
616
|
+
try {
|
|
617
|
+
this.teamStreamId = workspaceManager.createIntegrationStream(
|
|
618
|
+
rootAgentId,
|
|
619
|
+
{ name: this.manifest.name, forkFrom: "main" }
|
|
620
|
+
);
|
|
621
|
+
} catch {
|
|
622
|
+
// Workspace isolation unavailable (e.g., not a git repo)
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// Subscribe to merge queue events — wake integrator on mr:submitted
|
|
627
|
+
try {
|
|
628
|
+
const mergeQueue = workspaceManager.getMergeQueue();
|
|
629
|
+
if (mergeQueue?.onEvent) {
|
|
630
|
+
this.mergeQueueUnsub = mergeQueue.onEvent((event) => {
|
|
631
|
+
if (event.type !== "mr:submitted") return;
|
|
632
|
+
|
|
633
|
+
// Find agent with workspace.integrate capability in this team
|
|
634
|
+
for (const [agentId, roleName] of this.agentRoleMap) {
|
|
635
|
+
const resolved = this.resolved.resolvedRoles.get(roleName);
|
|
636
|
+
const caps = resolved?.capabilities ?? [];
|
|
637
|
+
if (caps.includes(WORKSPACE_CAPABILITIES.INTEGRATE)) {
|
|
638
|
+
try {
|
|
639
|
+
this.services.agentManager.prompt(
|
|
640
|
+
agentId,
|
|
641
|
+
`Merge request ${(event as { data?: Record<string, unknown> }).data?.mrId} submitted ` +
|
|
642
|
+
`by worker ${(event as { data?: Record<string, unknown> }).data?.workerAgentId} ` +
|
|
643
|
+
`for branch ${(event as { data?: Record<string, unknown> }).data?.workerBranch}. ` +
|
|
644
|
+
`Process the merge queue.`
|
|
645
|
+
);
|
|
646
|
+
} catch {
|
|
647
|
+
// Best-effort wake
|
|
648
|
+
}
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
} catch {
|
|
655
|
+
// Merge queue not available — workspace isolation without merge queue
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Poll EventStore for MERGE_REQUEST signals from worker subprocesses.
|
|
659
|
+
// Workers in MCP subprocess emit to shared SQLite; main process must reload to see them.
|
|
660
|
+
this.startMergeRequestPolling();
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Poll EventStore for MERGE_REQUEST signals emitted by worker subprocesses.
|
|
665
|
+
*
|
|
666
|
+
* Workers call done() in their MCP subprocess, which emits MERGE_REQUEST to
|
|
667
|
+
* the shared EventStore. This polling picks up those signals and submits to
|
|
668
|
+
* the merge queue on the main server.
|
|
669
|
+
*/
|
|
670
|
+
private startMergeRequestPolling(): void {
|
|
671
|
+
const { workspaceManager, eventStore } = this.services;
|
|
672
|
+
if (!workspaceManager || !this.teamStreamId) return;
|
|
673
|
+
|
|
674
|
+
const mergeQueue = workspaceManager.getMergeQueue();
|
|
675
|
+
if (!mergeQueue) return;
|
|
676
|
+
|
|
677
|
+
this.mergeRequestPollTimer = setInterval(async () => {
|
|
678
|
+
try {
|
|
679
|
+
// Reload to see events written by subprocesses
|
|
680
|
+
if (eventStore.reload) {
|
|
681
|
+
await eventStore.reload();
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
const events = eventStore.query({ type: "status", limit: 100 });
|
|
685
|
+
for (const event of events) {
|
|
686
|
+
// Skip already-processed events
|
|
687
|
+
if (event.timestamp <= this.lastMergeRequestSeen) continue;
|
|
688
|
+
|
|
689
|
+
const details = event.payload?.details as Record<string, unknown> | undefined;
|
|
690
|
+
if (details?.signal !== "MERGE_REQUEST") continue;
|
|
691
|
+
|
|
692
|
+
// Check this agent belongs to our team
|
|
693
|
+
const sourceAgentId = event.source?.agent_id;
|
|
694
|
+
if (!sourceAgentId) continue;
|
|
695
|
+
|
|
696
|
+
// Check if agent is a team member OR a child of a team member
|
|
697
|
+
const isTeamMember = this.agentRoleMap.has(sourceAgentId as AgentId);
|
|
698
|
+
const parentAgent = eventStore.getAgent(sourceAgentId);
|
|
699
|
+
const isChildOfTeamMember = parentAgent?.parent
|
|
700
|
+
? this.agentRoleMap.has(parentAgent.parent as AgentId)
|
|
701
|
+
: false;
|
|
702
|
+
|
|
703
|
+
if (!isTeamMember && !isChildOfTeamMember) continue;
|
|
704
|
+
|
|
705
|
+
this.lastMergeRequestSeen = event.timestamp;
|
|
706
|
+
|
|
707
|
+
// Extract merge request details
|
|
708
|
+
const sourceBranch = details.sourceBranch as string | undefined;
|
|
709
|
+
const taskId = details.taskId as string | undefined;
|
|
710
|
+
const workerId = details.workerId as string | undefined;
|
|
711
|
+
|
|
712
|
+
if (!sourceBranch || !workerId) continue;
|
|
713
|
+
|
|
714
|
+
// Submit to merge queue
|
|
715
|
+
try {
|
|
716
|
+
mergeQueue.submit({
|
|
717
|
+
streamId: this.teamStreamId!,
|
|
718
|
+
taskId: taskId ?? `task-${workerId}`,
|
|
719
|
+
workerBranch: sourceBranch,
|
|
720
|
+
workerAgentId: workerId,
|
|
721
|
+
});
|
|
722
|
+
} catch {
|
|
723
|
+
// Already submitted or other error — best-effort
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
} catch {
|
|
727
|
+
// Best-effort polling
|
|
728
|
+
}
|
|
729
|
+
}, 2000);
|
|
730
|
+
|
|
731
|
+
if (this.mergeRequestPollTimer.unref) {
|
|
732
|
+
this.mergeRequestPollTimer.unref();
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
332
736
|
// ─────────────────────────────────────────────────────────────
|
|
333
737
|
// Spawn Interceptor
|
|
334
738
|
// ─────────────────────────────────────────────────────────────
|
|
335
739
|
|
|
336
740
|
/**
|
|
337
|
-
* Create the spawn interceptor that injects team context into spawn options.
|
|
741
|
+
* Internal: Create the spawn interceptor that injects team context into spawn options.
|
|
338
742
|
*/
|
|
339
|
-
private
|
|
743
|
+
private _createSpawnInterceptor(): SpawnInterceptor {
|
|
340
744
|
return (options: SpawnAgentOptions): SpawnAgentOptions => {
|
|
341
745
|
const roleName = options.role;
|
|
342
746
|
if (!roleName) return options;
|
|
343
747
|
|
|
344
|
-
const resolved = this.
|
|
748
|
+
const resolved = this.resolved.resolvedRoles.get(roleName);
|
|
345
749
|
if (!resolved) return options; // Unknown role — pass through
|
|
346
750
|
|
|
347
751
|
// Compute topics from communication topology
|
|
@@ -362,9 +766,34 @@ export class TeamRuntime {
|
|
|
362
766
|
if (strategyName) {
|
|
363
767
|
teamEnv.MACRO_INTEGRATION_STRATEGY = strategyName;
|
|
364
768
|
}
|
|
769
|
+
// Task backend config is propagated by AgentManager.buildMacroAgentMcp()
|
|
770
|
+
// from its taskBackend/openTasksSocketPath config options.
|
|
771
|
+
|
|
772
|
+
// Inject workspace fields based on capabilities (never overwrite explicit values)
|
|
773
|
+
const capabilities = resolved.capabilities;
|
|
774
|
+
let streamId = options.streamId;
|
|
775
|
+
let streamConfig = options.streamConfig;
|
|
776
|
+
let dataplaneTaskId = options.dataplaneTaskId;
|
|
777
|
+
|
|
778
|
+
if (this.teamStreamId && capabilities) {
|
|
779
|
+
if (capabilities.includes(WORKSPACE_CAPABILITIES.WORKTREE)) {
|
|
780
|
+
streamId = streamId ?? this.teamStreamId;
|
|
781
|
+
// Pull-mode workers use agentId as workspace identifier (one worktree per lifetime)
|
|
782
|
+
dataplaneTaskId = dataplaneTaskId ?? `worker-${Date.now()}`;
|
|
783
|
+
} else if (capabilities.includes(WORKSPACE_CAPABILITIES.INTEGRATE)) {
|
|
784
|
+
streamId = streamId ?? this.teamStreamId;
|
|
785
|
+
}
|
|
786
|
+
// workspace.stream: stream creation is managed by TeamRuntime.setupWorkspaceIntegration(),
|
|
787
|
+
// not auto-injected. Coordinators that need sub-streams pass explicit streamConfig.
|
|
788
|
+
}
|
|
365
789
|
|
|
366
790
|
return {
|
|
367
791
|
...options,
|
|
792
|
+
// Workspace fields
|
|
793
|
+
streamId,
|
|
794
|
+
streamConfig,
|
|
795
|
+
dataplaneTaskId,
|
|
796
|
+
capabilities: capabilities ?? options.capabilities,
|
|
368
797
|
// Merge topics
|
|
369
798
|
topics: [
|
|
370
799
|
...(options.topics ?? []),
|
|
@@ -404,7 +833,7 @@ export class TeamRuntime {
|
|
|
404
833
|
*/
|
|
405
834
|
private getTopicsForRole(roleName: string): string[] {
|
|
406
835
|
const topics: string[] = [];
|
|
407
|
-
const subs = this.
|
|
836
|
+
const subs = this.communication.subscriptions?.[roleName] ?? [];
|
|
408
837
|
|
|
409
838
|
for (const sub of subs) {
|
|
410
839
|
// Channel name becomes the topic name
|
|
@@ -420,16 +849,16 @@ export class TeamRuntime {
|
|
|
420
849
|
* Get MCP servers configured for a role.
|
|
421
850
|
*/
|
|
422
851
|
private getMcpServersForRole(roleName: string): McpServerEntry[] {
|
|
423
|
-
return this.
|
|
852
|
+
return this.resolved.template.mcpServers.get(roleName) ?? [];
|
|
424
853
|
}
|
|
425
854
|
|
|
426
855
|
/**
|
|
427
856
|
* Get the loaded prompt content for a role.
|
|
428
857
|
*/
|
|
429
858
|
private getPromptForRole(roleName: string): string | undefined {
|
|
430
|
-
const resolved = this.
|
|
859
|
+
const resolved = this.resolved.resolvedRoles.get(roleName);
|
|
431
860
|
if (!resolved?.prompt) return undefined;
|
|
432
|
-
return this.
|
|
861
|
+
return this.loadedPrompts.get(resolved.prompt);
|
|
433
862
|
}
|
|
434
863
|
|
|
435
864
|
/**
|
|
@@ -440,7 +869,7 @@ export class TeamRuntime {
|
|
|
440
869
|
): string | undefined {
|
|
441
870
|
// Prefer topology-level prompt reference
|
|
442
871
|
if (node.prompt) {
|
|
443
|
-
return this.
|
|
872
|
+
return this.loadedPrompts.get(node.prompt);
|
|
444
873
|
}
|
|
445
874
|
// Fall back to role-level prompt
|
|
446
875
|
return this.getPromptForRole(node.role);
|
|
@@ -454,7 +883,7 @@ export class TeamRuntime {
|
|
|
454
883
|
const taskMode = this.getTaskMode();
|
|
455
884
|
|
|
456
885
|
if (taskMode === "pull") {
|
|
457
|
-
const pullConfig = this.
|
|
886
|
+
const pullConfig = this.resolved.macroAgent.task_assignment?.pull;
|
|
458
887
|
const idleTimeout = pullConfig?.idle_timeout_s ?? 300;
|
|
459
888
|
|
|
460
889
|
patterns.push(`## Task Claiming
|
|
@@ -488,114 +917,156 @@ Focus on correctness — your changes go live immediately.`);
|
|
|
488
917
|
}
|
|
489
918
|
|
|
490
919
|
// ─────────────────────────────────────────────────────────────
|
|
491
|
-
//
|
|
920
|
+
// Exposed Interceptor / Filter / Validator Factories
|
|
492
921
|
// ─────────────────────────────────────────────────────────────
|
|
493
922
|
|
|
494
923
|
/**
|
|
495
|
-
*
|
|
924
|
+
* Create the spawn interceptor for this team.
|
|
925
|
+
*
|
|
926
|
+
* Returns a function that injects team context (topics, MCP servers,
|
|
927
|
+
* env vars, prompt, interaction patterns) into spawn options.
|
|
928
|
+
* The caller (TeamManager or installOnServices) is responsible for
|
|
929
|
+
* installing it on AgentManager.
|
|
930
|
+
*/
|
|
931
|
+
createSpawnInterceptor(): SpawnInterceptor {
|
|
932
|
+
return this._createSpawnInterceptor();
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Create the signal filter for this team.
|
|
496
937
|
*
|
|
497
938
|
* Combines two filter sources:
|
|
498
|
-
* 1. Channel subscription filters (per-role, per-topic)
|
|
499
|
-
* 2. Peer connection filters (per-agent-pair)
|
|
939
|
+
* 1. Channel subscription filters (per-role, per-topic)
|
|
940
|
+
* 2. Peer connection filters (per-agent-pair)
|
|
500
941
|
*
|
|
501
|
-
*
|
|
942
|
+
* Must be called after bootstrap() so that agentRoleMap and
|
|
943
|
+
* peerSignalFilters are populated. Returns null if no filtering needed.
|
|
502
944
|
*/
|
|
503
|
-
|
|
504
|
-
|
|
945
|
+
createSignalFilter(): SignalFilter | null {
|
|
946
|
+
return (from: AgentId, to: AgentId, signal: string | undefined): boolean => {
|
|
947
|
+
// Untagged status events always pass through
|
|
948
|
+
if (!signal) return true;
|
|
949
|
+
|
|
950
|
+
// Check peer connection filter (directional: from→to)
|
|
951
|
+
const peerFilter = this.peerSignalFilters.get(`${from}→${to}`);
|
|
952
|
+
if (peerFilter) {
|
|
953
|
+
return peerFilter.includes(signal);
|
|
954
|
+
}
|
|
505
955
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
956
|
+
// Check channel subscription filter for recipient's role
|
|
957
|
+
const recipientRole = this.agentRoleMap.get(to);
|
|
958
|
+
if (recipientRole) {
|
|
959
|
+
const allowed = this.roleAllowedSignals.get(recipientRole);
|
|
960
|
+
if (allowed && allowed !== "all") {
|
|
961
|
+
return allowed.has(signal);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
510
964
|
|
|
511
|
-
|
|
512
|
-
|
|
965
|
+
// No filter configured — allow delivery
|
|
966
|
+
return true;
|
|
967
|
+
};
|
|
968
|
+
}
|
|
513
969
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
970
|
+
/**
|
|
971
|
+
* Create the emission validator for this team.
|
|
972
|
+
*
|
|
973
|
+
* Checks whether an agent's emitted signal is in its role's allowed
|
|
974
|
+
* emissions list. Behavior depends on enforcement mode.
|
|
975
|
+
* Returns null if no emissions config exists.
|
|
976
|
+
*/
|
|
977
|
+
createEmissionValidator(): EmissionValidator | null {
|
|
978
|
+
const emissions = this.communication.emissions;
|
|
979
|
+
const enforcement = this.communication.enforcement ?? "permissive";
|
|
980
|
+
|
|
981
|
+
// No emissions config — nothing to enforce
|
|
982
|
+
if (!emissions || Object.keys(emissions).length === 0) return null;
|
|
983
|
+
|
|
984
|
+
return (agentId: AgentId, signal: string | undefined): EmissionValidatorResult => {
|
|
985
|
+
// Untagged status events are always allowed
|
|
986
|
+
if (!signal) return { action: "allow" };
|
|
987
|
+
|
|
988
|
+
const role = this.agentRoleMap.get(agentId);
|
|
989
|
+
if (!role) return { action: "allow" };
|
|
990
|
+
|
|
991
|
+
const allowedSignals = emissions[role];
|
|
992
|
+
if (!allowedSignals) return { action: "allow" };
|
|
993
|
+
|
|
994
|
+
if (allowedSignals.includes(signal)) {
|
|
995
|
+
return { action: "allow" };
|
|
523
996
|
}
|
|
524
997
|
|
|
525
|
-
|
|
526
|
-
|
|
998
|
+
// Signal not in allowed list — enforce
|
|
999
|
+
const message = `Agent '${agentId}' (role: ${role}) emitted disallowed signal '${signal}'. Allowed: [${allowedSignals.join(", ")}]`;
|
|
1000
|
+
|
|
1001
|
+
switch (enforcement) {
|
|
1002
|
+
case "strict":
|
|
1003
|
+
return { action: "reject", message };
|
|
1004
|
+
case "audit":
|
|
1005
|
+
return { action: "audit", message };
|
|
1006
|
+
case "permissive":
|
|
1007
|
+
default:
|
|
1008
|
+
return { action: "warn", message };
|
|
1009
|
+
}
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
527
1012
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
1013
|
+
/**
|
|
1014
|
+
* Convenience method: install interceptor, signal filter, and emission
|
|
1015
|
+
* validator directly on the shared services.
|
|
1016
|
+
*
|
|
1017
|
+
* Use this for standalone operation (without TeamManager).
|
|
1018
|
+
* TeamManager uses the individual create* methods for composite dispatch.
|
|
1019
|
+
*/
|
|
1020
|
+
installOnServices(): void {
|
|
1021
|
+
const { agentManager, messageRouter } = this.services;
|
|
532
1022
|
|
|
533
|
-
|
|
534
|
-
const peerFilter = this.peerSignalFilters.get(`${from}→${to}`);
|
|
535
|
-
if (peerFilter) {
|
|
536
|
-
return peerFilter.includes(signal);
|
|
537
|
-
}
|
|
1023
|
+
agentManager.setSpawnInterceptor(this.createSpawnInterceptor());
|
|
538
1024
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
if (allowed && allowed !== "all") {
|
|
544
|
-
return allowed.has(signal);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
1025
|
+
const signalFilter = this.createSignalFilter();
|
|
1026
|
+
if (signalFilter && messageRouter.setSignalFilter) {
|
|
1027
|
+
messageRouter.setSignalFilter(signalFilter);
|
|
1028
|
+
}
|
|
547
1029
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
1030
|
+
const emissionValidator = this.createEmissionValidator();
|
|
1031
|
+
if (emissionValidator && messageRouter.setEmissionValidator) {
|
|
1032
|
+
messageRouter.setEmissionValidator(emissionValidator);
|
|
551
1033
|
}
|
|
552
1034
|
}
|
|
553
1035
|
|
|
1036
|
+
/**
|
|
1037
|
+
* Convenience method: uninstall interceptor and filters from services.
|
|
1038
|
+
* Use on teardown for standalone operation.
|
|
1039
|
+
*/
|
|
1040
|
+
uninstallFromServices(): void {
|
|
1041
|
+
this.services.agentManager.setSpawnInterceptor(null);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
554
1044
|
// ─────────────────────────────────────────────────────────────
|
|
555
|
-
//
|
|
1045
|
+
// Internal: Pre-compute role allowed signals
|
|
556
1046
|
// ─────────────────────────────────────────────────────────────
|
|
557
1047
|
|
|
558
1048
|
/**
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
* Behavior depends on enforcement mode: strict (reject), permissive (warn), audit (record).
|
|
1049
|
+
* Pre-compute per-role allowed signals from channel subscriptions.
|
|
1050
|
+
* Called during bootstrap() so createSignalFilter() can use the result.
|
|
562
1051
|
*/
|
|
563
|
-
private
|
|
564
|
-
|
|
565
|
-
const emissions = this.manifest.communication.emissions;
|
|
566
|
-
const enforcement = this.manifest.communication.enforcement ?? "permissive";
|
|
567
|
-
|
|
568
|
-
// No emissions config — nothing to enforce
|
|
569
|
-
if (!emissions || Object.keys(emissions).length === 0) return;
|
|
1052
|
+
private computeRoleAllowedSignals(): void {
|
|
1053
|
+
this.roleAllowedSignals.clear();
|
|
570
1054
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
// Untagged status events are always allowed
|
|
574
|
-
if (!signal) return { action: "allow" };
|
|
575
|
-
|
|
576
|
-
const role = this.agentRoleMap.get(agentId);
|
|
577
|
-
if (!role) return { action: "allow" };
|
|
578
|
-
|
|
579
|
-
const allowedSignals = emissions[role];
|
|
580
|
-
if (!allowedSignals) return { action: "allow" };
|
|
1055
|
+
for (const [roleName, subs] of Object.entries(this.communication.subscriptions ?? {})) {
|
|
1056
|
+
let allowed: Set<string> | "all" = new Set<string>();
|
|
581
1057
|
|
|
582
|
-
|
|
583
|
-
|
|
1058
|
+
for (const sub of subs) {
|
|
1059
|
+
if (!sub.signals || sub.signals.length === 0) {
|
|
1060
|
+
// No filter on this subscription — role receives all signals
|
|
1061
|
+
allowed = "all";
|
|
1062
|
+
break;
|
|
584
1063
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
const message = `Agent '${agentId}' (role: ${role}) emitted disallowed signal '${signal}'. Allowed: [${allowedSignals.join(", ")}]`;
|
|
588
|
-
|
|
589
|
-
switch (enforcement) {
|
|
590
|
-
case "strict":
|
|
591
|
-
return { action: "reject", message };
|
|
592
|
-
case "audit":
|
|
593
|
-
return { action: "audit", message };
|
|
594
|
-
case "permissive":
|
|
595
|
-
default:
|
|
596
|
-
return { action: "warn", message };
|
|
1064
|
+
for (const sig of sub.signals) {
|
|
1065
|
+
(allowed as Set<string>).add(sig);
|
|
597
1066
|
}
|
|
598
|
-
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
this.roleAllowedSignals.set(roleName, allowed);
|
|
599
1070
|
}
|
|
600
1071
|
}
|
|
601
1072
|
|
|
@@ -608,7 +1079,7 @@ Focus on correctness — your changes go live immediately.`);
|
|
|
608
1079
|
* Falls back to legacy bidirectional subtree subs when no peers config exists.
|
|
609
1080
|
*/
|
|
610
1081
|
private wirePeerRoutes(): void {
|
|
611
|
-
const peers = this.
|
|
1082
|
+
const peers = this.communication.routing?.peers;
|
|
612
1083
|
|
|
613
1084
|
if (!peers || peers.length === 0) {
|
|
614
1085
|
// Fallback: hardcoded mutual subtree subscriptions (backwards compat)
|