macro-agent 0.1.1 → 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/.sudocode/issues.jsonl +28 -0
- package/.sudocode/specs.jsonl +4 -0
- package/CLAUDE.md +9 -3
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +111 -48
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/server.d.ts +5 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +100 -3
- 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/cli/acp.d.ts.map +1 -1
- package/dist/cli/acp.js +71 -1
- package/dist/cli/acp.js.map +1 -1
- package/dist/cli/index.js +5 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.js +27 -8
- package/dist/cli/mcp.js.map +1 -1
- package/dist/config/project-config.d.ts +13 -2
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +12 -2
- 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/extensions/index.d.ts +4 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +27 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- 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/index.d.ts +1 -1
- package/dist/map/adapter/index.d.ts.map +1 -1
- package/dist/map/adapter/index.js +3 -1
- package/dist/map/adapter/index.js.map +1 -1
- package/dist/map/adapter/types.d.ts +1 -1
- package/dist/map/adapter/types.d.ts.map +1 -1
- package/dist/mcp/mcp-server.d.ts +2 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +12 -3
- 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/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 +6 -0
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +10 -0
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/config-loader.d.ts +1 -1
- package/dist/roles/config-loader.d.ts.map +1 -1
- package/dist/roles/config-loader.js +3 -2
- package/dist/roles/config-loader.js.map +1 -1
- package/dist/roles/types.d.ts +3 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/server/combined-server.d.ts +8 -1
- package/dist/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +6 -2
- package/dist/server/combined-server.js.map +1 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +12 -5
- 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 +5 -0
- package/dist/store/types/agents.d.ts.map +1 -1
- package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -1
- package/dist/task/backend/opentasks/daemon-manager.js +1 -1
- package/dist/task/backend/opentasks/daemon-manager.js.map +1 -1
- 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 +6 -2
- package/dist/teams/team-loader.d.ts.map +1 -1
- package/dist/teams/team-loader.js +154 -162
- 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 +527 -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/teams.md +73 -0
- package/package.json +2 -1
- 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/agent/agent-manager.ts +143 -72
- package/src/agent/types.ts +9 -0
- package/src/api/__tests__/server.test.ts +203 -4
- package/src/api/server.ts +130 -5
- package/src/api/types.ts +3 -1
- package/src/cli/acp.ts +68 -1
- package/src/cli/index.ts +5 -1
- package/src/cli/mcp.ts +27 -13
- package/src/config/project-config.ts +27 -3
- package/src/index.ts +3 -0
- 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__/stream-extensions.test.ts +494 -0
- package/src/map/adapter/extensions/index.ts +36 -0
- package/src/map/adapter/extensions/streams.ts +839 -0
- package/src/map/adapter/index.ts +5 -0
- package/src/map/adapter/types.ts +8 -1
- package/src/mcp/mcp-server.ts +14 -3
- package/src/mcp/tools/done.ts +19 -0
- 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 +11 -0
- package/src/roles/config-loader.ts +3 -2
- package/src/roles/types.ts +7 -0
- package/src/server/combined-server.ts +15 -1
- package/src/store/__tests__/event-store-oob.test.ts +109 -0
- package/src/store/event-store.ts +13 -3
- package/src/store/instance.ts +2 -2
- package/src/store/types/agents.ts +5 -0
- package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
- package/src/task/backend/opentasks/daemon-manager.ts +4 -1
- package/src/teams/CLAUDE.md +180 -0
- 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 +200 -234
- package/src/teams/team-manager.ts +387 -0
- package/src/teams/team-runtime.ts +590 -121
- package/src/teams/types.ts +99 -200
package/src/api/server.ts
CHANGED
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
} from "../steering/index.js";
|
|
58
58
|
import type { AgentId } from "../store/types/index.js";
|
|
59
59
|
import { secureCompare } from "../auth/token.js";
|
|
60
|
+
import type { TeamManager } from "../teams/team-manager.js";
|
|
60
61
|
|
|
61
62
|
// ─────────────────────────────────────────────────────────────────
|
|
62
63
|
// Server Configuration
|
|
@@ -88,6 +89,8 @@ export interface APIServices {
|
|
|
88
89
|
mailService?: import("../mail/mail-service.js").MailService;
|
|
89
90
|
/** Optional conversation map for agent-to-conversation tracking */
|
|
90
91
|
conversationMap?: import("../mail/conversation-map.js").ConversationMap;
|
|
92
|
+
/** Optional team manager for dynamic team management */
|
|
93
|
+
teamManager?: TeamManager;
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -347,6 +350,113 @@ function registerConversationRoutes(
|
|
|
347
350
|
});
|
|
348
351
|
}
|
|
349
352
|
|
|
353
|
+
// ─────────────────────────────────────────────────────────────────
|
|
354
|
+
// Shared Team Routes Helper
|
|
355
|
+
// ─────────────────────────────────────────────────────────────────
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Register team management REST endpoints on an Express app.
|
|
359
|
+
* Shared between standalone and shared API modes.
|
|
360
|
+
*
|
|
361
|
+
* Endpoints:
|
|
362
|
+
* POST /api/teams — Start a team instance
|
|
363
|
+
* GET /api/teams — List running team instances
|
|
364
|
+
* GET /api/teams/:id — Get team instance details
|
|
365
|
+
* DELETE /api/teams/:id — Teardown a team instance
|
|
366
|
+
*/
|
|
367
|
+
function registerTeamRoutes(
|
|
368
|
+
app: Express,
|
|
369
|
+
teamManager: TeamManager | undefined,
|
|
370
|
+
defaultCwd: string,
|
|
371
|
+
sendError: (res: Response, status: number, code: string, message: string) => void,
|
|
372
|
+
broadcast?: (channel: string, message: WSMessage) => void,
|
|
373
|
+
): void {
|
|
374
|
+
if (!teamManager) return;
|
|
375
|
+
|
|
376
|
+
// POST /api/teams — Start a team instance
|
|
377
|
+
app.post("/api/teams", async (req: Request, res: Response) => {
|
|
378
|
+
const { template, overrides } = req.body ?? {};
|
|
379
|
+
if (!template || typeof template !== "string") {
|
|
380
|
+
return sendError(res, 400, "INVALID_REQUEST", "Missing required field: template");
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const instance = await teamManager.startTeam(template, defaultCwd, overrides);
|
|
385
|
+
const result = {
|
|
386
|
+
id: instance.id,
|
|
387
|
+
templateName: instance.templateName,
|
|
388
|
+
rootAgentId: instance.result.rootId,
|
|
389
|
+
companionAgentIds: instance.result.companionIds,
|
|
390
|
+
taskMode: instance.runtime.getTaskMode(),
|
|
391
|
+
strategy: instance.runtime.getStrategyName(),
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
if (broadcast) {
|
|
395
|
+
broadcast("teams", { type: "team_started", data: result });
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
res.status(201).json(result);
|
|
399
|
+
} catch (err) {
|
|
400
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
401
|
+
return sendError(res, 500, "TEAM_START_FAILED", message);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// GET /api/teams — List running team instances
|
|
406
|
+
app.get("/api/teams", (_req: Request, res: Response) => {
|
|
407
|
+
const instances = teamManager.getInstances();
|
|
408
|
+
res.json(instances.map((inst) => ({
|
|
409
|
+
id: inst.id,
|
|
410
|
+
templateName: inst.templateName,
|
|
411
|
+
rootAgentId: inst.result.rootId,
|
|
412
|
+
companionAgentIds: inst.result.companionIds,
|
|
413
|
+
taskMode: inst.runtime.getTaskMode(),
|
|
414
|
+
strategy: inst.runtime.getStrategyName(),
|
|
415
|
+
})));
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// GET /api/teams/:id — Get team instance details
|
|
419
|
+
app.get("/api/teams/:id", (req: Request, res: Response) => {
|
|
420
|
+
const instance = teamManager.getInstance(req.params.id);
|
|
421
|
+
if (!instance) {
|
|
422
|
+
return sendError(res, 404, "TEAM_NOT_FOUND", `No team instance '${req.params.id}'`);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const manifest = instance.runtime.getManifest();
|
|
426
|
+
res.json({
|
|
427
|
+
id: instance.id,
|
|
428
|
+
templateName: instance.templateName,
|
|
429
|
+
rootAgentId: instance.result.rootId,
|
|
430
|
+
companionAgentIds: instance.result.companionIds,
|
|
431
|
+
taskMode: instance.runtime.getTaskMode(),
|
|
432
|
+
strategy: instance.runtime.getStrategyName(),
|
|
433
|
+
roles: manifest.roles,
|
|
434
|
+
communication: manifest.communication,
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// DELETE /api/teams/:id — Teardown a team instance
|
|
439
|
+
app.delete("/api/teams/:id", async (req: Request, res: Response) => {
|
|
440
|
+
const instance = teamManager.getInstance(req.params.id);
|
|
441
|
+
if (!instance) {
|
|
442
|
+
return sendError(res, 404, "TEAM_NOT_FOUND", `No team instance '${req.params.id}'`);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
try {
|
|
446
|
+
await teamManager.stopTeam(req.params.id);
|
|
447
|
+
|
|
448
|
+
if (broadcast) {
|
|
449
|
+
broadcast("teams", { type: "team_stopped", data: { id: req.params.id } });
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
res.json({ success: true });
|
|
453
|
+
} catch (err) {
|
|
454
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
455
|
+
return sendError(res, 500, "TEAM_STOP_FAILED", message);
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
350
460
|
// ─────────────────────────────────────────────────────────────────
|
|
351
461
|
// Create API Server
|
|
352
462
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -568,8 +678,11 @@ export function createAPIServer(
|
|
|
568
678
|
res.json(status);
|
|
569
679
|
});
|
|
570
680
|
|
|
571
|
-
// GET /api/team - Get active team info
|
|
681
|
+
// GET /api/team - Get active team info (DEPRECATED: use GET /api/teams)
|
|
572
682
|
app.get("/api/team", (_req: Request, res: Response) => {
|
|
683
|
+
res.set("Deprecation", "true");
|
|
684
|
+
res.set("Link", '</api/teams>; rel="successor-version"');
|
|
685
|
+
|
|
573
686
|
// Check for team config in EventStore
|
|
574
687
|
const statusEvents = eventStore.query({ type: "status", limit: 50 });
|
|
575
688
|
const teamConfigEvent = statusEvents.find(
|
|
@@ -591,6 +704,9 @@ export function createAPIServer(
|
|
|
591
704
|
});
|
|
592
705
|
});
|
|
593
706
|
|
|
707
|
+
// Register dynamic team management routes
|
|
708
|
+
registerTeamRoutes(app, services.teamManager, process.cwd(), sendError, broadcastToChannel);
|
|
709
|
+
|
|
594
710
|
// ─────────────────────────────────────────────────────────────────
|
|
595
711
|
// Metrics Endpoints (Phase 5)
|
|
596
712
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -1175,7 +1291,7 @@ export function createAPIServer(
|
|
|
1175
1291
|
const gracePeriod = options?.force ? 0 : shutdownGracePeriodMs;
|
|
1176
1292
|
|
|
1177
1293
|
// 1. Stop accepting new connections
|
|
1178
|
-
server.close();
|
|
1294
|
+
await new Promise<void>((resolve) => server.close(() => resolve()));
|
|
1179
1295
|
|
|
1180
1296
|
// 2. Wait grace period for in-flight work
|
|
1181
1297
|
if (gracePeriod > 0) {
|
|
@@ -1259,10 +1375,10 @@ export function createAPIServer(
|
|
|
1259
1375
|
* @returns Express app
|
|
1260
1376
|
*/
|
|
1261
1377
|
export function createAPIApp(
|
|
1262
|
-
services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager" | "messageRouter"> & Pick<Partial<APIServices>, "mailService" | "conversationMap">,
|
|
1263
|
-
config: { cors?: boolean; serverToken?: string } = {}
|
|
1378
|
+
services: Pick<APIServices, "eventStore" | "agentManager" | "taskManager" | "messageRouter"> & Pick<Partial<APIServices>, "mailService" | "conversationMap" | "teamManager">,
|
|
1379
|
+
config: { cors?: boolean; serverToken?: string; defaultCwd?: string } = {}
|
|
1264
1380
|
): Express {
|
|
1265
|
-
const { cors = true, serverToken } = config;
|
|
1381
|
+
const { cors = true, serverToken, defaultCwd } = config;
|
|
1266
1382
|
const { agentManager, taskManager, messageRouter } = services;
|
|
1267
1383
|
|
|
1268
1384
|
// Create shared state
|
|
@@ -1823,6 +1939,15 @@ export function createAPIApp(
|
|
|
1823
1939
|
// Register conversation API routes (if mail service available)
|
|
1824
1940
|
registerConversationRoutes(app, services, sendError);
|
|
1825
1941
|
|
|
1942
|
+
// Register dynamic team management routes
|
|
1943
|
+
registerTeamRoutes(
|
|
1944
|
+
app,
|
|
1945
|
+
services.teamManager,
|
|
1946
|
+
defaultCwd ?? process.cwd(),
|
|
1947
|
+
sendError,
|
|
1948
|
+
state.broadcast,
|
|
1949
|
+
);
|
|
1950
|
+
|
|
1826
1951
|
return app;
|
|
1827
1952
|
}
|
|
1828
1953
|
|
package/src/api/types.ts
CHANGED
package/src/cli/acp.ts
CHANGED
|
@@ -48,6 +48,7 @@ import { createAgentManager } from "../agent/agent-manager.js";
|
|
|
48
48
|
import { createTaskManager } from "../task/task-manager.js";
|
|
49
49
|
import { createMessageRouter } from "../router/message-router.js";
|
|
50
50
|
import { MacroAgent } from "../acp/macro-agent.js";
|
|
51
|
+
import { TeamManager } from "../teams/team-manager.js";
|
|
51
52
|
import {
|
|
52
53
|
createCombinedServer,
|
|
53
54
|
type CombinedServer,
|
|
@@ -237,6 +238,24 @@ async function main() {
|
|
|
237
238
|
agentTokenManager = new AgentTokenManager();
|
|
238
239
|
}
|
|
239
240
|
|
|
241
|
+
// Create WorkspaceManager for workspace isolation (optional — requires git repo)
|
|
242
|
+
let workspaceManager: import("../workspace/types.js").WorkspaceManager | undefined;
|
|
243
|
+
try {
|
|
244
|
+
const { createWorkspaceManager } = await import("../workspace/workspace-manager.js");
|
|
245
|
+
const poolSize = parseInt(process.env.MACRO_WORKSPACE_POOL_SIZE ?? "10", 10);
|
|
246
|
+
workspaceManager = createWorkspaceManager({
|
|
247
|
+
enabled: true,
|
|
248
|
+
repoPath: defaultCwd,
|
|
249
|
+
pool: {
|
|
250
|
+
enabled: poolSize > 0,
|
|
251
|
+
maxSize: poolSize,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
console.error(`[acp] WorkspaceManager created (pool: ${poolSize})`);
|
|
255
|
+
} catch (err) {
|
|
256
|
+
console.error(`[acp] WorkspaceManager not available: ${err instanceof Error ? err.message : err}`);
|
|
257
|
+
}
|
|
258
|
+
|
|
240
259
|
// Now create the agentManager with the real router
|
|
241
260
|
agentManager = createAgentManager(eventStore, messageRouter, {
|
|
242
261
|
serverUrl,
|
|
@@ -244,6 +263,7 @@ async function main() {
|
|
|
244
263
|
agentTokenManager: serverUrl ? agentTokenManager : undefined,
|
|
245
264
|
taskBackend: mergedConfig.task?.backend,
|
|
246
265
|
openTasksSocketPath: mergedConfig.task?.opentasks?.socket_path,
|
|
266
|
+
workspaceManager,
|
|
247
267
|
});
|
|
248
268
|
const taskManager = createTaskManager(eventStore);
|
|
249
269
|
|
|
@@ -304,6 +324,49 @@ async function main() {
|
|
|
304
324
|
}
|
|
305
325
|
}
|
|
306
326
|
|
|
327
|
+
// Create TeamManager for dynamic team loading (server mode only)
|
|
328
|
+
const teamManager = new TeamManager({ agentManager, messageRouter, eventStore, workspaceManager, taskBackend });
|
|
329
|
+
teamManager.install(); // Composite interceptor/filter/validator
|
|
330
|
+
|
|
331
|
+
// Seed default team templates if they don't exist yet
|
|
332
|
+
try {
|
|
333
|
+
const { seedDefaultTemplates } = await import("../teams/seed-defaults.js");
|
|
334
|
+
const seeded = await seedDefaultTemplates(defaultCwd);
|
|
335
|
+
if (seeded.length > 0) {
|
|
336
|
+
console.error(`[acp] Seeded default team templates: ${seeded.join(", ")}`);
|
|
337
|
+
}
|
|
338
|
+
} catch (err) {
|
|
339
|
+
console.error(`[acp] Failed to seed default templates: ${err}`);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Auto-start teams from config
|
|
343
|
+
if (!options.acp) {
|
|
344
|
+
// Default team (backward compat)
|
|
345
|
+
if (mergedConfig.team) {
|
|
346
|
+
try {
|
|
347
|
+
const instance = await teamManager.startTeam(mergedConfig.team, defaultCwd);
|
|
348
|
+
console.error(`[acp] Team '${mergedConfig.team}' started (${instance.id}): root=${instance.result.rootId}, companions=[${instance.result.companionIds.join(", ")}]`);
|
|
349
|
+
} catch (err) {
|
|
350
|
+
console.error(`[acp] Failed to start team '${mergedConfig.team}': ${err}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Additional teams with autoStart (skip if already started as default team)
|
|
355
|
+
if (mergedConfig.teams) {
|
|
356
|
+
for (const [name, entry] of Object.entries(mergedConfig.teams)) {
|
|
357
|
+
if (!entry.autoStart) continue;
|
|
358
|
+
const template = entry.template ?? name;
|
|
359
|
+
if (template === mergedConfig.team) continue; // Already started above
|
|
360
|
+
try {
|
|
361
|
+
const instance = await teamManager.startTeam(template, defaultCwd);
|
|
362
|
+
console.error(`[acp] Team '${template}' started (${instance.id}): root=${instance.result.rootId}, companions=[${instance.result.companionIds.join(", ")}]`);
|
|
363
|
+
} catch (err) {
|
|
364
|
+
console.error(`[acp] Failed to start team '${template}': ${err}`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
307
370
|
// Create ActivityWatcher for event-driven agent waking
|
|
308
371
|
const sessionProvider = createSessionProviderFromAgentManager(agentManager);
|
|
309
372
|
const wakeHandler = createWakeHandler(sessionProvider, agentManager);
|
|
@@ -401,6 +464,10 @@ async function main() {
|
|
|
401
464
|
}
|
|
402
465
|
}
|
|
403
466
|
|
|
467
|
+
try { await teamManager.teardownAll(); } catch (err) {
|
|
468
|
+
console.error(`[cleanup] TeamManager teardown failed: ${err}`);
|
|
469
|
+
}
|
|
470
|
+
|
|
404
471
|
try { await agentManager.close(); } catch (err) {
|
|
405
472
|
console.error(`[cleanup] AgentManager close failed: ${err}`);
|
|
406
473
|
}
|
|
@@ -456,7 +523,7 @@ async function main() {
|
|
|
456
523
|
const port = options.port ?? mergedConfig.port ?? 3001;
|
|
457
524
|
|
|
458
525
|
combinedServer = createCombinedServer(
|
|
459
|
-
{ eventStore, agentManager, taskManager, messageRouter, activityWatcher, taskBackend, taskToolProvider, taskToolContext, agentTokenManager, getConnectedProjects },
|
|
526
|
+
{ eventStore, agentManager, taskManager, messageRouter, activityWatcher, taskBackend, taskToolProvider, taskToolContext, agentTokenManager, getConnectedProjects, teamManager, workspaceManager },
|
|
460
527
|
{ port, host, defaultCwd, serverToken, noAuth }
|
|
461
528
|
);
|
|
462
529
|
|
package/src/cli/index.ts
CHANGED
|
@@ -170,6 +170,9 @@ program
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// Determine team name: CLI flag > merged config
|
|
173
|
+
if (options.team) {
|
|
174
|
+
console.warn(chalk.yellow("[DEPRECATED] --team flag on multiagent-cli start is deprecated. Use 'multiagent' with .multiagent/config.json instead."));
|
|
175
|
+
}
|
|
173
176
|
const teamName = options.team ?? mergedConfig.team;
|
|
174
177
|
|
|
175
178
|
// Load and initialize team if specified
|
|
@@ -715,7 +718,8 @@ program
|
|
|
715
718
|
const path = await import("path");
|
|
716
719
|
const os = await import("os");
|
|
717
720
|
|
|
718
|
-
const
|
|
721
|
+
const baseDir = process.env.MACRO_AGENT_HOME || path.join(os.homedir(), ".multiagent");
|
|
722
|
+
const storagePath = path.join(baseDir, "store.json");
|
|
719
723
|
|
|
720
724
|
if (fs.existsSync(storagePath)) {
|
|
721
725
|
fs.unlinkSync(storagePath);
|
package/src/cli/mcp.ts
CHANGED
|
@@ -253,12 +253,18 @@ async function startLegacy() {
|
|
|
253
253
|
}
|
|
254
254
|
});
|
|
255
255
|
|
|
256
|
-
// Read team config from EventStore
|
|
256
|
+
// Read team config from EventStore (scoped by MACRO_TEAM_NAME for multi-team)
|
|
257
257
|
let teamTaskMode: string | undefined;
|
|
258
|
+
const myTeamName = process.env.MACRO_TEAM_NAME;
|
|
258
259
|
const teamEvents = eventStore.query({ type: "status", limit: 50 });
|
|
259
|
-
const teamConfigEvent = teamEvents.find(
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
const teamConfigEvent = teamEvents.find((e) => {
|
|
261
|
+
const tc = e.payload?.team_config as Record<string, unknown> | undefined;
|
|
262
|
+
if (!tc) return false;
|
|
263
|
+
// If agent has a team name, find that specific team's config
|
|
264
|
+
if (myTeamName) return tc.teamName === myTeamName;
|
|
265
|
+
// Fallback: first team_config found (backward compat)
|
|
266
|
+
return true;
|
|
267
|
+
});
|
|
262
268
|
if (teamConfigEvent?.payload?.team_config) {
|
|
263
269
|
const tc = teamConfigEvent.payload.team_config as Record<string, unknown>;
|
|
264
270
|
teamTaskMode = tc.taskMode as string | undefined;
|
|
@@ -282,15 +288,23 @@ async function startLegacy() {
|
|
|
282
288
|
|
|
283
289
|
const strategyName = tc.strategy as string | undefined;
|
|
284
290
|
if (strategyName) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
291
|
+
// Queue strategy requires merge queue which is only available in the main process.
|
|
292
|
+
// Skip it so the worker handler falls through to MERGE_REQUEST signal emission,
|
|
293
|
+
// which the main server's TeamRuntime polls for and submits to the real merge queue.
|
|
294
|
+
if (strategyName === "queue") {
|
|
295
|
+
debugLog(`[MCP] Skipping queue strategy in subprocess (no merge queue available). ` +
|
|
296
|
+
`Worker done() will emit MERGE_REQUEST signal for main process to handle.`);
|
|
297
|
+
} else {
|
|
298
|
+
try {
|
|
299
|
+
const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
|
|
300
|
+
integrationStrategy = defaultStrategyRegistry.get(
|
|
301
|
+
strategyName,
|
|
302
|
+
tc.strategyConfig as Record<string, unknown> | undefined
|
|
303
|
+
);
|
|
304
|
+
debugLog(`[MCP] Instantiated '${strategyName}' integration strategy`);
|
|
305
|
+
} catch (err) {
|
|
306
|
+
debugLog(`[MCP] Failed to instantiate strategy '${strategyName}': ${err}`);
|
|
307
|
+
}
|
|
294
308
|
}
|
|
295
309
|
}
|
|
296
310
|
}
|
|
@@ -17,6 +17,16 @@ import * as path from "path";
|
|
|
17
17
|
// Types
|
|
18
18
|
// =============================================================================
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Entry in the `teams` config for declaring additional team templates.
|
|
22
|
+
*/
|
|
23
|
+
export interface TeamConfigEntry {
|
|
24
|
+
/** Template name (defaults to the key) */
|
|
25
|
+
template?: string;
|
|
26
|
+
/** Auto-start on server boot (default: false) */
|
|
27
|
+
autoStart?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
/**
|
|
21
31
|
* Typed configuration schema for multiagent.
|
|
22
32
|
*
|
|
@@ -24,9 +34,12 @@ import * as path from "path";
|
|
|
24
34
|
* Environment variables override file-based config.
|
|
25
35
|
*/
|
|
26
36
|
export interface MultiagentConfig {
|
|
27
|
-
/**
|
|
37
|
+
/** Default team template name to load on startup */
|
|
28
38
|
team?: string;
|
|
29
39
|
|
|
40
|
+
/** Additional teams available for dynamic or auto-start loading */
|
|
41
|
+
teams?: Record<string, TeamConfigEntry>;
|
|
42
|
+
|
|
30
43
|
/** Server port (default: 3001) */
|
|
31
44
|
port?: number;
|
|
32
45
|
|
|
@@ -134,10 +147,11 @@ export function getProjectConfigPath(projectPath?: string): string {
|
|
|
134
147
|
/**
|
|
135
148
|
* Get the global config file path.
|
|
136
149
|
*
|
|
137
|
-
* @returns Absolute path to ~/.multiagent/config.json
|
|
150
|
+
* @returns Absolute path to ~/.multiagent/config.json (or MACRO_AGENT_HOME/config.json)
|
|
138
151
|
*/
|
|
139
152
|
export function getGlobalConfigPath(): string {
|
|
140
|
-
|
|
153
|
+
const globalDir = process.env.MACRO_AGENT_HOME || path.join(os.homedir(), CONFIG_DIR);
|
|
154
|
+
return path.join(globalDir, CONFIG_FILE);
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
// =============================================================================
|
|
@@ -249,6 +263,16 @@ export function loadMergedConfig(projectPath?: string): MultiagentConfig {
|
|
|
249
263
|
merged.auth = { ...(merged.auth ?? {}), disabled: true };
|
|
250
264
|
}
|
|
251
265
|
|
|
266
|
+
// MACRO_TEAMS: comma-separated template names to auto-start
|
|
267
|
+
if (process.env.MACRO_TEAMS) {
|
|
268
|
+
const names = process.env.MACRO_TEAMS.split(",").map(s => s.trim()).filter(Boolean);
|
|
269
|
+
const teams: Record<string, TeamConfigEntry> = { ...(merged.teams ?? {}) };
|
|
270
|
+
for (const name of names) {
|
|
271
|
+
teams[name] = { ...teams[name], autoStart: true };
|
|
272
|
+
}
|
|
273
|
+
merged.teams = teams;
|
|
274
|
+
}
|
|
275
|
+
|
|
252
276
|
return merged;
|
|
253
277
|
}
|
|
254
278
|
|
package/src/index.ts
CHANGED
|
@@ -1752,6 +1752,37 @@ describe("handlers", () => {
|
|
|
1752
1752
|
|
|
1753
1753
|
expect(handler).toBeDefined();
|
|
1754
1754
|
});
|
|
1755
|
+
|
|
1756
|
+
it("should return worker handler for team role with workspace.worktree capability", () => {
|
|
1757
|
+
const deps = createMockDeps();
|
|
1758
|
+
const registry = createHandlerRegistry(deps as any);
|
|
1759
|
+
|
|
1760
|
+
// "developer" extends "worker" — gets workspace.worktree capability
|
|
1761
|
+
const handler = getHandler("developer", registry, deps as any, ["workspace.worktree"]);
|
|
1762
|
+
|
|
1763
|
+
// Should be the worker handler, not generic
|
|
1764
|
+
expect(handler).toBe(registry.get("worker"));
|
|
1765
|
+
});
|
|
1766
|
+
|
|
1767
|
+
it("should return integrator handler for team role with workspace.integrate capability", () => {
|
|
1768
|
+
const deps = createMockDeps();
|
|
1769
|
+
const registry = createHandlerRegistry(deps as any);
|
|
1770
|
+
|
|
1771
|
+
const handler = getHandler("merger", registry, deps as any, ["workspace.integrate"]);
|
|
1772
|
+
|
|
1773
|
+
expect(handler).toBe(registry.get("integrator"));
|
|
1774
|
+
});
|
|
1775
|
+
|
|
1776
|
+
it("should return generic handler when capabilities have no workspace match", () => {
|
|
1777
|
+
const deps = createMockDeps();
|
|
1778
|
+
const registry = createHandlerRegistry(deps as any);
|
|
1779
|
+
|
|
1780
|
+
const handler = getHandler("watcher", registry, deps as any, ["msg.send", "file.read"]);
|
|
1781
|
+
|
|
1782
|
+
// No workspace capability → falls through to generic
|
|
1783
|
+
expect(handler).not.toBe(registry.get("worker"));
|
|
1784
|
+
expect(handler).not.toBe(registry.get("integrator"));
|
|
1785
|
+
});
|
|
1755
1786
|
});
|
|
1756
1787
|
|
|
1757
1788
|
describe("dispatchDone", () => {
|
|
@@ -1795,6 +1826,28 @@ describe("handlers", () => {
|
|
|
1795
1826
|
expect(result.signalsEmitted).toContain("STATUS");
|
|
1796
1827
|
});
|
|
1797
1828
|
|
|
1829
|
+
it("should dispatch team role with workspace.worktree to worker handler", async () => {
|
|
1830
|
+
const deps = createMockDeps();
|
|
1831
|
+
const context: LifecycleContext = {
|
|
1832
|
+
agentId: "developer-1",
|
|
1833
|
+
role: "developer",
|
|
1834
|
+
capabilities: ["workspace.worktree", "lifecycle.done", "file.read"],
|
|
1835
|
+
};
|
|
1836
|
+
const args: DoneArgs = { status: "completed" };
|
|
1837
|
+
const cleanupStatus: CleanupStatus = { ready: true };
|
|
1838
|
+
|
|
1839
|
+
const result = await dispatchDone(
|
|
1840
|
+
context,
|
|
1841
|
+
args,
|
|
1842
|
+
cleanupStatus,
|
|
1843
|
+
deps as any,
|
|
1844
|
+
);
|
|
1845
|
+
|
|
1846
|
+
// Should have gone through the worker handler path
|
|
1847
|
+
expect(result.shouldTerminate).toBe(true);
|
|
1848
|
+
expect(result.signalsEmitted).toContain("WORKER_DONE");
|
|
1849
|
+
});
|
|
1850
|
+
|
|
1798
1851
|
it("should use custom registry when provided", async () => {
|
|
1799
1852
|
const deps = createMockDeps();
|
|
1800
1853
|
const customHandler = vi.fn().mockResolvedValue({
|
|
@@ -111,29 +111,46 @@ export function createHandlerRegistry(
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
* Get the handler for a given role
|
|
114
|
+
* Get the handler for a given role.
|
|
115
115
|
*
|
|
116
|
-
*
|
|
116
|
+
* Resolution order:
|
|
117
|
+
* 1. Exact role name match (e.g., "worker", "integrator")
|
|
118
|
+
* 2. Dot-prefix match (e.g., "worker.resolver" → "worker")
|
|
119
|
+
* 3. Capability-based match (e.g., "developer" with workspace.worktree → worker handler)
|
|
120
|
+
* 4. Generic fallback handler
|
|
117
121
|
*/
|
|
118
122
|
export function getHandler(
|
|
119
123
|
role: string,
|
|
120
124
|
registry: DoneHandlerRegistry,
|
|
121
|
-
deps: AllHandlerDeps
|
|
125
|
+
deps: AllHandlerDeps,
|
|
126
|
+
capabilities?: string[],
|
|
122
127
|
): DoneHandler {
|
|
123
|
-
//
|
|
128
|
+
// 1. Exact match
|
|
124
129
|
const handler = registry.get(role);
|
|
125
130
|
if (handler) {
|
|
126
131
|
return handler;
|
|
127
132
|
}
|
|
128
133
|
|
|
129
|
-
//
|
|
134
|
+
// 2. Dot-prefix match (e.g., "worker.resolver" → "worker")
|
|
130
135
|
const baseRole = role.split(".")[0];
|
|
131
136
|
const baseHandler = registry.get(baseRole);
|
|
132
137
|
if (baseHandler) {
|
|
133
138
|
return baseHandler;
|
|
134
139
|
}
|
|
135
140
|
|
|
136
|
-
//
|
|
141
|
+
// 3. Capability-based match (for team-defined roles like "developer" extending "worker")
|
|
142
|
+
if (capabilities) {
|
|
143
|
+
if (capabilities.includes("workspace.worktree")) {
|
|
144
|
+
const workerHandler = registry.get("worker");
|
|
145
|
+
if (workerHandler) return workerHandler;
|
|
146
|
+
}
|
|
147
|
+
if (capabilities.includes("workspace.integrate")) {
|
|
148
|
+
const integratorHandler = registry.get("integrator");
|
|
149
|
+
if (integratorHandler) return integratorHandler;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 4. Generic fallback
|
|
137
154
|
const genericDeps: GenericHandlerDeps = {
|
|
138
155
|
messageRouter: deps.messageRouter,
|
|
139
156
|
};
|
|
@@ -158,8 +175,8 @@ export async function dispatchDone(
|
|
|
158
175
|
// Use provided registry or create default
|
|
159
176
|
const handlers = registry ?? createHandlerRegistry(deps);
|
|
160
177
|
|
|
161
|
-
// Get the handler for this role
|
|
162
|
-
const handler = getHandler(context.role, handlers, deps);
|
|
178
|
+
// Get the handler for this role (pass capabilities for team role resolution)
|
|
179
|
+
const handler = getHandler(context.role, handlers, deps, context.capabilities);
|
|
163
180
|
|
|
164
181
|
// Execute the handler
|
|
165
182
|
return handler(context, args, cleanupStatus);
|
package/src/lifecycle/types.ts
CHANGED
|
@@ -117,6 +117,9 @@ export interface LifecycleContext {
|
|
|
117
117
|
|
|
118
118
|
/** Merge request ID (for resolver workers to track which MR they're resolving) */
|
|
119
119
|
mrId?: string;
|
|
120
|
+
|
|
121
|
+
/** Resolved capabilities for the agent's role (for capability-based handler dispatch) */
|
|
122
|
+
capabilities?: string[];
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
/**
|