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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* - MessageRouter for subscription setup
|
|
8
8
|
*/
|
|
9
9
|
import { nanoid } from "nanoid";
|
|
10
|
+
import { uniqueNamesGenerator, adjectives, animals, } from "unique-names-generator";
|
|
10
11
|
import { AgentFactory, } from "acp-factory";
|
|
11
12
|
import { AgentManagerError } from "./types.js";
|
|
12
13
|
import { AGENT_CAPABILITIES } from "../roles/capabilities.js";
|
|
@@ -45,7 +46,9 @@ function getSpawnCapability(childRole) {
|
|
|
45
46
|
// AgentManager Implementation
|
|
46
47
|
// ─────────────────────────────────────────────────────────────────
|
|
47
48
|
export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
48
|
-
const { defaultPermissionMode = "auto-approve", defaultAgentType = "claude-code", defaultCwd = process.cwd(), workspaceManager, roleRegistry = new DefaultRoleRegistry(), healthCheckService, mailService: initialMailService, conversationMap: initialConversationMap, } = config;
|
|
49
|
+
const { defaultPermissionMode = "auto-approve", defaultAgentType = "claude-code", defaultCwd = process.cwd(), workspaceManager, roleRegistry = new DefaultRoleRegistry(), healthCheckService, mailService: initialMailService, conversationMap: initialConversationMap, serverUrl, serverToken, agentTokenManager, taskBackend: configTaskBackend, openTasksSocketPath: initialOpenTasksSocketPath, } = config;
|
|
50
|
+
// Mutable OpenTasks socket path (support late binding via setOpenTasksSocketPath)
|
|
51
|
+
let configOpenTasksSocketPath = initialOpenTasksSocketPath;
|
|
49
52
|
// Mutable mail services (support late binding via setMailServices)
|
|
50
53
|
let mailService = initialMailService;
|
|
51
54
|
let conversationMap = initialConversationMap;
|
|
@@ -57,17 +60,76 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
57
60
|
const agentWorkspaces = new Map();
|
|
58
61
|
// Lifecycle event listeners
|
|
59
62
|
const lifecycleListeners = new Set();
|
|
63
|
+
// Shutdown guard — prevents spawns during close()
|
|
64
|
+
let isShuttingDown = false;
|
|
65
|
+
// ─────────────────────────────────────────────────────────────────
|
|
66
|
+
// MCP Server Config
|
|
67
|
+
// ─────────────────────────────────────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Build the macro-agent MCP server config for a Claude Code agent session.
|
|
70
|
+
* Used by spawn(), resume(), and forkAgent() to ensure every agent gets
|
|
71
|
+
* access to the macro-agent coordination tools.
|
|
72
|
+
*/
|
|
73
|
+
function buildMacroAgentMcp(opts) {
|
|
74
|
+
// Common env vars for both thin-client and legacy modes
|
|
75
|
+
const env = [
|
|
76
|
+
{ name: "MACRO_AGENT_ID", value: opts.agentId },
|
|
77
|
+
{ name: "MACRO_PARENT_ID", value: opts.parentId },
|
|
78
|
+
{ name: "MACRO_TASK_ID", value: opts.taskId },
|
|
79
|
+
{ name: "MACRO_AGENT_CWD", value: opts.cwd },
|
|
80
|
+
{ name: "MACRO_PERMISSION_MODE", value: opts.permissionMode },
|
|
81
|
+
{
|
|
82
|
+
name: "MACRO_TASK_BACKEND",
|
|
83
|
+
value: configTaskBackend ?? process.env.MACRO_TASK_BACKEND ?? "",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "OPENTASKS_SOCKET_PATH",
|
|
87
|
+
value: configOpenTasksSocketPath ?? process.env.OPENTASKS_SOCKET_PATH ?? "",
|
|
88
|
+
},
|
|
89
|
+
// Pass streamId so MCP subprocess can include it in lifecycle context
|
|
90
|
+
// (WorkspaceManager is not available in subprocess)
|
|
91
|
+
{ name: "MACRO_STREAM_ID", value: opts.streamId ?? "" },
|
|
92
|
+
];
|
|
93
|
+
if (serverUrl) {
|
|
94
|
+
// Thin-client mode: forward tool calls to main server via MAP WebSocket
|
|
95
|
+
env.push({ name: "MACRO_SERVER_URL", value: serverUrl }, {
|
|
96
|
+
name: "MACRO_AGENT_LINEAGE",
|
|
97
|
+
value: JSON.stringify(opts.lineage ?? []),
|
|
98
|
+
}, { name: "MACRO_SESSION_ID", value: opts.sessionId ?? "" });
|
|
99
|
+
// Auth tokens for thin-client connections
|
|
100
|
+
if (serverToken) {
|
|
101
|
+
env.push({ name: "MACRO_SERVER_TOKEN", value: serverToken });
|
|
102
|
+
}
|
|
103
|
+
if (agentTokenManager) {
|
|
104
|
+
const agentToken = agentTokenManager.createToken(opts.agentId);
|
|
105
|
+
env.push({ name: "MACRO_AGENT_TOKEN", value: agentToken });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Legacy mode: create local service stack with shared SQLite
|
|
110
|
+
env.push({ name: "MACRO_INSTANCE_ID", value: eventStore.instanceId }, { name: "MACRO_BASE_DIR", value: eventStore.baseDir });
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
name: "macro-agent",
|
|
114
|
+
command: "npx",
|
|
115
|
+
args: ["multiagent-mcp"],
|
|
116
|
+
env,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
60
119
|
// ─────────────────────────────────────────────────────────────────
|
|
61
120
|
// Lifecycle
|
|
62
121
|
// ─────────────────────────────────────────────────────────────────
|
|
63
122
|
async function spawn(rawOptions) {
|
|
123
|
+
if (isShuttingDown) {
|
|
124
|
+
throw new AgentManagerError("Cannot spawn agent during shutdown", "SHUTDOWN_IN_PROGRESS");
|
|
125
|
+
}
|
|
64
126
|
// Apply spawn interceptor if set (used by TeamRuntime for team context injection)
|
|
65
127
|
const options = spawnInterceptor
|
|
66
128
|
? await spawnInterceptor(rawOptions)
|
|
67
129
|
: rawOptions;
|
|
68
130
|
const { task, task_id, parent, cwd = defaultCwd, permissionMode = defaultPermissionMode, subscribeParent = true, topics = [], config: agentConfig, agentType = defaultAgentType, customPrompt, interactionPatterns,
|
|
69
131
|
// Workspace-related fields (Phase 2)
|
|
70
|
-
role, streamId, streamConfig, dataplaneTaskId, } = options;
|
|
132
|
+
role, team_instance, streamId, streamConfig, dataplaneTaskId, capabilities, } = options;
|
|
71
133
|
// Generate IDs upfront (including session_id so we can persist before starting MCP)
|
|
72
134
|
const agentId = `agent_${nanoid(12)}`;
|
|
73
135
|
const taskId = task_id ?? `task_${nanoid(12)}`;
|
|
@@ -140,10 +202,18 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
140
202
|
task_id: taskId,
|
|
141
203
|
parent: parent ?? null,
|
|
142
204
|
role: role ?? undefined,
|
|
205
|
+
team_instance: team_instance ?? undefined,
|
|
143
206
|
config: agentConfig ?? {},
|
|
144
207
|
cwd,
|
|
145
208
|
},
|
|
146
209
|
});
|
|
210
|
+
// Generate a human-readable default name
|
|
211
|
+
const generatedName = uniqueNamesGenerator({
|
|
212
|
+
dictionaries: [adjectives, animals],
|
|
213
|
+
separator: "-",
|
|
214
|
+
length: 2,
|
|
215
|
+
});
|
|
216
|
+
eventStore.updateAgentMetadata(agentId, { name: generatedName });
|
|
147
217
|
// Persist immediately so MCP server subprocess can read the agent
|
|
148
218
|
await eventStore.persist();
|
|
149
219
|
// Verify the agent is now in the store
|
|
@@ -157,162 +227,204 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
157
227
|
permissionMode,
|
|
158
228
|
env: agentConfig?.env,
|
|
159
229
|
});
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
try {
|
|
231
|
+
// ─────────────────────────────────────────────────────────────────
|
|
232
|
+
// Workspace Creation (before session, so cwd reflects worktree)
|
|
233
|
+
// ─────────────────────────────────────────────────────────────────
|
|
234
|
+
let workspace;
|
|
235
|
+
let resolvedStreamId = streamId;
|
|
236
|
+
if (workspaceManager && role) {
|
|
237
|
+
try {
|
|
238
|
+
workspace = await createWorkspaceForRole(workspaceManager, agentId, role, {
|
|
239
|
+
streamId,
|
|
240
|
+
streamConfig,
|
|
241
|
+
dataplaneTaskId,
|
|
242
|
+
capabilities,
|
|
243
|
+
cwd,
|
|
244
|
+
});
|
|
245
|
+
if (workspace) {
|
|
246
|
+
agentWorkspaces.set(agentId, workspace);
|
|
247
|
+
resolvedStreamId = workspace.streamId;
|
|
248
|
+
// Create and claim a dataplane task so the worktree gets a real
|
|
249
|
+
// worker branch. Without this, the worktree stays in detached
|
|
250
|
+
// HEAD and done() would detect "HEAD" instead of the actual
|
|
251
|
+
// worker branch name (e.g. worker/<agentId>/<taskId>).
|
|
252
|
+
if (workspace.role === "worker" && workspace.streamId) {
|
|
253
|
+
try {
|
|
254
|
+
const dpTaskId = workspaceManager.createTask(workspace.streamId, { title: task ?? `Task for ${agentId}` });
|
|
255
|
+
workspaceManager.claimTask(dpTaskId, agentId, workspace.path);
|
|
256
|
+
}
|
|
257
|
+
catch (claimErr) {
|
|
258
|
+
console.error(`[AgentManager] Failed to create/claim dataplane task for ${agentId}:`, claimErr);
|
|
259
|
+
// Continue without a branch — worktree stays in detached HEAD
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Register with parent coordinator if applicable
|
|
263
|
+
const isChildRole = role === "worker" || role === "integrator" ||
|
|
264
|
+
(capabilities && (capabilities.includes("workspace.worktree") || capabilities.includes("workspace.integrate")));
|
|
265
|
+
if (parent && isChildRole) {
|
|
266
|
+
const parentWorkspace = agentWorkspaces.get(parent);
|
|
267
|
+
if (parentWorkspace?.role === "coordinator") {
|
|
268
|
+
workspaceManager.registerChildWorkspace(parent, agentId, workspace.path);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch (wsError) {
|
|
274
|
+
console.error(`[AgentManager] Failed to create workspace for ${agentId}: ${wsError}`);
|
|
275
|
+
// Continue without workspace — don't fail the spawn
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// Use workspace path as the agent's working directory when available.
|
|
279
|
+
// This ensures the agent process, MCP subprocess (MACRO_AGENT_CWD), and
|
|
280
|
+
// done handler all use the worktree path instead of the repo root.
|
|
281
|
+
const effectiveCwd = workspace?.path ?? cwd;
|
|
282
|
+
// Update agent's cwd in EventStore so resume() also uses workspace path
|
|
283
|
+
if (workspace) {
|
|
284
|
+
eventStore.updateAgentMetadata(agentId, { cwd: effectiveCwd });
|
|
285
|
+
await eventStore.persist();
|
|
286
|
+
}
|
|
287
|
+
const macroAgentMcp = buildMacroAgentMcp({
|
|
288
|
+
agentId,
|
|
289
|
+
parentId: parent ?? "",
|
|
290
|
+
taskId,
|
|
291
|
+
cwd: effectiveCwd,
|
|
292
|
+
permissionMode,
|
|
293
|
+
lineage: parentAgent?.lineage
|
|
294
|
+
? [...parentAgent.lineage, parent]
|
|
295
|
+
: [],
|
|
296
|
+
sessionId,
|
|
297
|
+
streamId,
|
|
298
|
+
});
|
|
299
|
+
// Combine with any user-provided MCP servers
|
|
300
|
+
// Note: Like macroAgentMcp, user MCP servers use stdio (no 'type' field)
|
|
301
|
+
const userMcpServers = agentConfig?.mcpServers?.map((s) => ({
|
|
302
|
+
name: s.name,
|
|
303
|
+
command: s.command,
|
|
304
|
+
args: s.args ?? [],
|
|
305
|
+
env: s.env
|
|
306
|
+
? Object.entries(s.env).map(([name, value]) => ({ name, value }))
|
|
307
|
+
: [],
|
|
308
|
+
})) ?? [];
|
|
309
|
+
// Create session with MCP servers
|
|
310
|
+
// Note: The MCP server subprocess will start here and look for the agent
|
|
311
|
+
// in EventStore. We already persisted the spawn event above.
|
|
312
|
+
//
|
|
313
|
+
// When permissionMode is "interactive", we strip settingSources so that
|
|
314
|
+
// the Claude Code subprocess doesn't read pre-approved tool rules from
|
|
315
|
+
// the user's ~/.claude/settings.local.json. This ensures ALL tool calls
|
|
316
|
+
// go through the canUseTool → requestPermission ACP flow.
|
|
317
|
+
const agentMeta = permissionMode === "interactive"
|
|
318
|
+
? { claudeCode: { options: { settingSources: [] } } }
|
|
319
|
+
: undefined;
|
|
320
|
+
const session = await handle.createSession(effectiveCwd, {
|
|
321
|
+
mcpServers: [macroAgentMcp, ...userMcpServers],
|
|
322
|
+
...(agentMeta && { agentMeta }),
|
|
323
|
+
});
|
|
324
|
+
// Emit started status (session is ready)
|
|
325
|
+
// Include the provider's session ID (e.g., Claude Code UUID) so
|
|
326
|
+
// it can be used for handle.loadSession() during resume
|
|
327
|
+
eventStore.emit({
|
|
328
|
+
type: "status",
|
|
329
|
+
source: { agent_id: agentId },
|
|
330
|
+
payload: {
|
|
331
|
+
status_type: "started",
|
|
332
|
+
summary: "Agent session started",
|
|
333
|
+
provider_session_id: session.id,
|
|
334
|
+
},
|
|
335
|
+
});
|
|
336
|
+
// Persist the status event
|
|
337
|
+
await eventStore.persist();
|
|
338
|
+
// Set up default subscriptions via MessageRouter
|
|
339
|
+
messageRouter.setupDefaultSubscriptions({
|
|
340
|
+
agent_id: agentId,
|
|
341
|
+
parent_id: parent ?? undefined,
|
|
342
|
+
task_id: taskId,
|
|
343
|
+
subscribe_parent: subscribeParent,
|
|
344
|
+
additional_topics: topics,
|
|
345
|
+
role: role ?? undefined,
|
|
346
|
+
});
|
|
347
|
+
// ─────────────────────────────────────────────────────────────────
|
|
348
|
+
// Mail: Create task conversation for this agent
|
|
349
|
+
// ─────────────────────────────────────────────────────────────────
|
|
350
|
+
if (mailService && conversationMap) {
|
|
351
|
+
try {
|
|
352
|
+
const parentConversationId = parent
|
|
353
|
+
? (conversationMap.getAgentConversation(parent) ??
|
|
354
|
+
conversationMap.getSessionConversation(parent))
|
|
355
|
+
: undefined;
|
|
356
|
+
const { conversationId: taskConvId } = mailService.createConversation({
|
|
357
|
+
type: "task",
|
|
358
|
+
subject: task?.slice(0, 80),
|
|
359
|
+
createdBy: parent ?? agentId,
|
|
360
|
+
parentConversationId: parentConversationId,
|
|
361
|
+
});
|
|
362
|
+
// Join parent and child as participants
|
|
363
|
+
if (parent) {
|
|
364
|
+
mailService.joinConversation({
|
|
365
|
+
conversationId: taskConvId,
|
|
366
|
+
participantId: parent,
|
|
367
|
+
participantType: "agent",
|
|
368
|
+
role: "initiator",
|
|
369
|
+
agentId: parent,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
232
372
|
mailService.joinConversation({
|
|
233
373
|
conversationId: taskConvId,
|
|
234
|
-
participantId:
|
|
374
|
+
participantId: agentId,
|
|
235
375
|
participantType: "agent",
|
|
236
|
-
role: "
|
|
237
|
-
agentId
|
|
376
|
+
role: "worker",
|
|
377
|
+
agentId,
|
|
238
378
|
});
|
|
379
|
+
conversationMap.setAgentConversation(agentId, taskConvId);
|
|
380
|
+
}
|
|
381
|
+
catch (err) {
|
|
382
|
+
// Never fail spawn due to mail errors
|
|
383
|
+
console.warn(`[AgentManager] Failed to create task conversation for ${agentId}:`, err);
|
|
239
384
|
}
|
|
240
|
-
mailService.joinConversation({
|
|
241
|
-
conversationId: taskConvId,
|
|
242
|
-
participantId: agentId,
|
|
243
|
-
participantType: "agent",
|
|
244
|
-
role: "worker",
|
|
245
|
-
agentId,
|
|
246
|
-
});
|
|
247
|
-
conversationMap.setAgentConversation(agentId, taskConvId);
|
|
248
385
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
386
|
+
// Track active session
|
|
387
|
+
const activeSession = {
|
|
388
|
+
agentId,
|
|
389
|
+
handle,
|
|
390
|
+
session,
|
|
391
|
+
createdAt: Date.now(),
|
|
392
|
+
isPrompting: false,
|
|
393
|
+
};
|
|
394
|
+
activeSessions.set(agentId, activeSession);
|
|
395
|
+
// Get the agent from materialized view
|
|
396
|
+
const agent = eventStore.getAgent(agentId);
|
|
397
|
+
// Notify lifecycle listeners
|
|
398
|
+
notifyLifecycle({ type: "spawned", agent });
|
|
399
|
+
notifyLifecycle({ type: "started", agent });
|
|
400
|
+
// Start health monitoring for coordinators
|
|
401
|
+
if (healthCheckService && role === "coordinator") {
|
|
402
|
+
healthCheckService.startForCoordinator(agentId);
|
|
252
403
|
}
|
|
404
|
+
return {
|
|
405
|
+
id: agentId,
|
|
406
|
+
session_id: sessionId, // Macro-agent's own session ID for ACP protocol mapping
|
|
407
|
+
agent,
|
|
408
|
+
session,
|
|
409
|
+
workspace,
|
|
410
|
+
streamId: resolvedStreamId,
|
|
411
|
+
};
|
|
253
412
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
agentId,
|
|
257
|
-
handle,
|
|
258
|
-
session,
|
|
259
|
-
createdAt: Date.now(),
|
|
260
|
-
isPrompting: false,
|
|
261
|
-
};
|
|
262
|
-
activeSessions.set(agentId, activeSession);
|
|
263
|
-
// Get the agent from materialized view
|
|
264
|
-
const agent = eventStore.getAgent(agentId);
|
|
265
|
-
// ─────────────────────────────────────────────────────────────────
|
|
266
|
-
// Workspace Creation (Phase 2)
|
|
267
|
-
// ─────────────────────────────────────────────────────────────────
|
|
268
|
-
let workspace;
|
|
269
|
-
let resolvedStreamId = streamId;
|
|
270
|
-
if (workspaceManager && role) {
|
|
413
|
+
catch (handleError) {
|
|
414
|
+
// Close the spawned process to prevent orphaning
|
|
271
415
|
try {
|
|
272
|
-
|
|
273
|
-
streamId,
|
|
274
|
-
streamConfig,
|
|
275
|
-
dataplaneTaskId,
|
|
276
|
-
cwd,
|
|
277
|
-
});
|
|
278
|
-
if (workspace) {
|
|
279
|
-
agentWorkspaces.set(agentId, workspace);
|
|
280
|
-
resolvedStreamId = workspace.streamId;
|
|
281
|
-
// Register with parent coordinator if applicable
|
|
282
|
-
if (parent &&
|
|
283
|
-
(role === "worker" || role === "integrator")) {
|
|
284
|
-
const parentWorkspace = agentWorkspaces.get(parent);
|
|
285
|
-
if (parentWorkspace?.role === "coordinator") {
|
|
286
|
-
workspaceManager.registerChildWorkspace(parent, agentId, workspace.path);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
416
|
+
await handle.close();
|
|
290
417
|
}
|
|
291
|
-
catch
|
|
292
|
-
|
|
293
|
-
// Continue without workspace - don't fail the spawn
|
|
418
|
+
catch {
|
|
419
|
+
// Ignore errors during cleanup
|
|
294
420
|
}
|
|
421
|
+
throw handleError;
|
|
295
422
|
}
|
|
296
|
-
// Notify lifecycle listeners
|
|
297
|
-
notifyLifecycle({ type: "spawned", agent });
|
|
298
|
-
notifyLifecycle({ type: "started", agent });
|
|
299
|
-
// Start health monitoring for coordinators
|
|
300
|
-
if (healthCheckService && role === "coordinator") {
|
|
301
|
-
healthCheckService.startForCoordinator(agentId);
|
|
302
|
-
}
|
|
303
|
-
return {
|
|
304
|
-
id: agentId,
|
|
305
|
-
session_id: sessionId, // Macro-agent's own session ID for ACP protocol mapping
|
|
306
|
-
agent,
|
|
307
|
-
session,
|
|
308
|
-
workspace,
|
|
309
|
-
streamId: resolvedStreamId,
|
|
310
|
-
};
|
|
311
423
|
}
|
|
312
424
|
catch (error) {
|
|
313
425
|
// Clean up the spawn event we already emitted
|
|
314
426
|
eventStore.emit({
|
|
315
|
-
type: "
|
|
427
|
+
type: "stop",
|
|
316
428
|
source: { agent_id: agentId },
|
|
317
429
|
payload: {
|
|
318
430
|
reason: "failed",
|
|
@@ -355,6 +467,10 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
355
467
|
// Continue with termination even if workspace cleanup fails
|
|
356
468
|
}
|
|
357
469
|
}
|
|
470
|
+
// Revoke agent authentication token
|
|
471
|
+
if (agentTokenManager) {
|
|
472
|
+
agentTokenManager.revokeToken(agentId);
|
|
473
|
+
}
|
|
358
474
|
// ─────────────────────────────────────────────────────────────────
|
|
359
475
|
// Mail: Close task conversation on terminate
|
|
360
476
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -383,9 +499,9 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
383
499
|
console.warn(`[AgentManager] Failed to close conversation for ${agentId}:`, err);
|
|
384
500
|
}
|
|
385
501
|
}
|
|
386
|
-
// Emit
|
|
502
|
+
// Emit stop event
|
|
387
503
|
eventStore.emit({
|
|
388
|
-
type: "
|
|
504
|
+
type: "stop",
|
|
389
505
|
source: { agent_id: agentId },
|
|
390
506
|
payload: {
|
|
391
507
|
agent_id: agentId,
|
|
@@ -442,7 +558,10 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
442
558
|
}
|
|
443
559
|
}
|
|
444
560
|
}
|
|
445
|
-
async function resume(agentId) {
|
|
561
|
+
async function resume(agentId, overridePermissionMode) {
|
|
562
|
+
if (isShuttingDown) {
|
|
563
|
+
throw new AgentManagerError("Cannot resume agent during shutdown", "SHUTDOWN_IN_PROGRESS", agentId);
|
|
564
|
+
}
|
|
446
565
|
const agent = eventStore.getAgent(agentId);
|
|
447
566
|
if (!agent) {
|
|
448
567
|
throw new AgentManagerError(`Agent not found: ${agentId}`, "AGENT_NOT_FOUND", agentId);
|
|
@@ -451,57 +570,217 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
451
570
|
if (activeSessions.has(agentId)) {
|
|
452
571
|
throw new AgentManagerError(`Agent already has active session: ${agentId}`, "ALREADY_RUNNING", agentId);
|
|
453
572
|
}
|
|
573
|
+
const permissionMode = overridePermissionMode ?? defaultPermissionMode;
|
|
454
574
|
// Spawn new process
|
|
455
575
|
const handle = await AgentFactory.spawn(defaultAgentType, {
|
|
456
|
-
permissionMode
|
|
576
|
+
permissionMode,
|
|
457
577
|
});
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
//
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
578
|
+
try {
|
|
579
|
+
const agentCwd = agent.cwd ?? defaultCwd;
|
|
580
|
+
let session;
|
|
581
|
+
// When interactive mode, strip settings to prevent auto-approval
|
|
582
|
+
const resumeAgentMeta = permissionMode === "interactive"
|
|
583
|
+
? { claudeCode: { options: { settingSources: [] } } }
|
|
584
|
+
: undefined;
|
|
585
|
+
const macroAgentMcp = buildMacroAgentMcp({
|
|
586
|
+
agentId,
|
|
587
|
+
parentId: agent.parent ?? "",
|
|
588
|
+
taskId: agent.task_id ?? "",
|
|
589
|
+
cwd: agentCwd,
|
|
590
|
+
permissionMode,
|
|
591
|
+
lineage: agent.lineage ?? [],
|
|
592
|
+
sessionId: agent.session_id ?? "",
|
|
593
|
+
});
|
|
594
|
+
const mcpServers = [macroAgentMcp];
|
|
595
|
+
if (agent.provider_session_id) {
|
|
596
|
+
// Load existing session using the provider's session ID (e.g., Claude Code UUID)
|
|
597
|
+
// Note: loadSession's TS type for mcpServers is { name, uri }[] but
|
|
598
|
+
// the underlying ACP protocol accepts full McpServerStdio. The JS
|
|
599
|
+
// implementation passes mcpServers through to the connection unchanged.
|
|
600
|
+
session = await handle.loadSession(agent.provider_session_id, agentCwd, mcpServers, resumeAgentMeta ? { agentMeta: resumeAgentMeta } : undefined);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
// No provider session ID available (agent predates this feature or wasn't persisted).
|
|
604
|
+
// Create a new session instead of loading with the macro-agent session_id
|
|
605
|
+
// which is not a valid provider session ID (e.g., Claude Code expects UUIDs).
|
|
606
|
+
session = await handle.createSession(agentCwd, {
|
|
607
|
+
mcpServers,
|
|
608
|
+
...(resumeAgentMeta && { agentMeta: resumeAgentMeta }),
|
|
609
|
+
});
|
|
610
|
+
// Store the provider session ID for future resumes
|
|
611
|
+
eventStore.emit({
|
|
612
|
+
type: "status",
|
|
613
|
+
source: { agent_id: agentId },
|
|
614
|
+
payload: {
|
|
615
|
+
status_type: "started",
|
|
616
|
+
summary: "Agent session created (no provider session to resume)",
|
|
617
|
+
provider_session_id: session.id,
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
// Track active session
|
|
622
|
+
const activeSession = {
|
|
623
|
+
agentId,
|
|
624
|
+
handle,
|
|
625
|
+
session,
|
|
626
|
+
createdAt: Date.now(),
|
|
627
|
+
isPrompting: false,
|
|
628
|
+
};
|
|
629
|
+
activeSessions.set(agentId, activeSession);
|
|
630
|
+
// Emit status event for resume
|
|
470
631
|
eventStore.emit({
|
|
471
632
|
type: "status",
|
|
472
633
|
source: { agent_id: agentId },
|
|
473
634
|
payload: {
|
|
474
635
|
status_type: "started",
|
|
475
|
-
summary: "Agent session
|
|
636
|
+
summary: "Agent session resumed",
|
|
476
637
|
provider_session_id: session.id,
|
|
477
638
|
},
|
|
478
639
|
});
|
|
640
|
+
return {
|
|
641
|
+
id: agentId,
|
|
642
|
+
session_id: agent.session_id, // Macro-agent's own session ID
|
|
643
|
+
agent: eventStore.getAgent(agentId),
|
|
644
|
+
session,
|
|
645
|
+
};
|
|
479
646
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
647
|
+
catch (handleError) {
|
|
648
|
+
// Close the spawned process to prevent orphaning
|
|
649
|
+
try {
|
|
650
|
+
await handle.close();
|
|
651
|
+
}
|
|
652
|
+
catch {
|
|
653
|
+
// Ignore errors during cleanup
|
|
654
|
+
}
|
|
655
|
+
throw handleError;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
// ─────────────────────────────────────────────────────────────────
|
|
659
|
+
// Fork
|
|
660
|
+
// ─────────────────────────────────────────────────────────────────
|
|
661
|
+
async function forkAgent(sourceAgentId, options) {
|
|
662
|
+
if (isShuttingDown) {
|
|
663
|
+
throw new AgentManagerError("Cannot fork agent during shutdown", "SHUTDOWN_IN_PROGRESS", sourceAgentId);
|
|
664
|
+
}
|
|
665
|
+
const sourceAgent = eventStore.getAgent(sourceAgentId);
|
|
666
|
+
if (!sourceAgent) {
|
|
667
|
+
throw new AgentManagerError(`Agent not found: ${sourceAgentId}`, "AGENT_NOT_FOUND", sourceAgentId);
|
|
668
|
+
}
|
|
669
|
+
// Need either an active session or a persisted provider_session_id
|
|
670
|
+
const activeSession = activeSessions.get(sourceAgentId);
|
|
671
|
+
if (!activeSession && !sourceAgent.provider_session_id) {
|
|
672
|
+
throw new AgentManagerError(`Agent has no session to fork: ${sourceAgentId}`, "FORK_NOT_SUPPORTED", sourceAgentId);
|
|
673
|
+
}
|
|
674
|
+
// Generate new IDs
|
|
675
|
+
const agentId = `agent_${nanoid(12)}`;
|
|
676
|
+
const taskId = `task_${nanoid(12)}`;
|
|
677
|
+
const sessionId = `session_${nanoid(12)}`;
|
|
678
|
+
const cwd = options?.cwd ?? sourceAgent.cwd ?? defaultCwd;
|
|
679
|
+
// Emit spawn event with fork metadata
|
|
490
680
|
eventStore.emit({
|
|
491
|
-
type: "
|
|
492
|
-
source: { agent_id:
|
|
681
|
+
type: "spawn",
|
|
682
|
+
source: { agent_id: sourceAgentId },
|
|
493
683
|
payload: {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
684
|
+
agent_id: agentId,
|
|
685
|
+
session_id: sessionId,
|
|
686
|
+
task: options?.name ?? `[Fork of ${sourceAgentId}]`,
|
|
687
|
+
task_id: taskId,
|
|
688
|
+
parent: sourceAgent.parent ?? null,
|
|
689
|
+
role: sourceAgent.role ?? undefined,
|
|
690
|
+
team_instance: sourceAgent.team_instance ?? undefined,
|
|
691
|
+
config: {},
|
|
692
|
+
cwd,
|
|
693
|
+
metadata: { fork_of: sourceAgentId },
|
|
497
694
|
},
|
|
498
695
|
});
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
};
|
|
696
|
+
// Generate a human-readable name
|
|
697
|
+
const generatedName = uniqueNamesGenerator({
|
|
698
|
+
dictionaries: [adjectives, animals],
|
|
699
|
+
separator: "-",
|
|
700
|
+
length: 2,
|
|
701
|
+
});
|
|
702
|
+
eventStore.updateAgentMetadata(agentId, { name: generatedName });
|
|
703
|
+
await eventStore.persist();
|
|
704
|
+
// Get the provider session ID to fork from
|
|
705
|
+
let forkedProviderSessionId;
|
|
706
|
+
if (activeSession) {
|
|
707
|
+
// Active session: fork with flush to ensure data is persisted
|
|
708
|
+
const forkedSession = await activeSession.session.forkWithFlush();
|
|
709
|
+
forkedProviderSessionId = forkedSession.id;
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
// Stopped agent: use the persisted provider session ID directly
|
|
713
|
+
forkedProviderSessionId = sourceAgent.provider_session_id;
|
|
714
|
+
}
|
|
715
|
+
// Spawn a new process
|
|
716
|
+
const handle = await AgentFactory.spawn(defaultAgentType, {
|
|
717
|
+
permissionMode: defaultPermissionMode,
|
|
718
|
+
});
|
|
719
|
+
try {
|
|
720
|
+
const macroAgentMcp = buildMacroAgentMcp({
|
|
721
|
+
agentId,
|
|
722
|
+
parentId: sourceAgent.parent ?? "",
|
|
723
|
+
taskId,
|
|
724
|
+
cwd,
|
|
725
|
+
permissionMode: defaultPermissionMode,
|
|
726
|
+
lineage: sourceAgent.lineage ?? [],
|
|
727
|
+
sessionId,
|
|
728
|
+
});
|
|
729
|
+
// Load the forked session on the new process with correct MCP config.
|
|
730
|
+
// Note: loadSession's TS type for mcpServers is { name, uri }[] but
|
|
731
|
+
// the underlying ACP protocol accepts full McpServerStdio. The JS
|
|
732
|
+
// implementation passes mcpServers through to the connection unchanged.
|
|
733
|
+
const session = await handle.loadSession(forkedProviderSessionId, cwd, [
|
|
734
|
+
macroAgentMcp,
|
|
735
|
+
]);
|
|
736
|
+
// Emit started status with provider session ID
|
|
737
|
+
eventStore.emit({
|
|
738
|
+
type: "status",
|
|
739
|
+
source: { agent_id: agentId },
|
|
740
|
+
payload: {
|
|
741
|
+
status_type: "started",
|
|
742
|
+
summary: "Agent session started (forked)",
|
|
743
|
+
provider_session_id: session.id,
|
|
744
|
+
},
|
|
745
|
+
});
|
|
746
|
+
await eventStore.persist();
|
|
747
|
+
// Set up message router subscriptions
|
|
748
|
+
messageRouter.setupDefaultSubscriptions({
|
|
749
|
+
agent_id: agentId,
|
|
750
|
+
parent_id: sourceAgent.parent ?? undefined,
|
|
751
|
+
task_id: taskId,
|
|
752
|
+
subscribe_parent: false,
|
|
753
|
+
additional_topics: [],
|
|
754
|
+
role: sourceAgent.role ?? undefined,
|
|
755
|
+
});
|
|
756
|
+
// Track active session
|
|
757
|
+
const newActiveSession = {
|
|
758
|
+
agentId,
|
|
759
|
+
handle,
|
|
760
|
+
session,
|
|
761
|
+
createdAt: Date.now(),
|
|
762
|
+
isPrompting: false,
|
|
763
|
+
};
|
|
764
|
+
activeSessions.set(agentId, newActiveSession);
|
|
765
|
+
const agent = eventStore.getAgent(agentId);
|
|
766
|
+
notifyLifecycle({ type: "spawned", agent });
|
|
767
|
+
notifyLifecycle({ type: "started", agent });
|
|
768
|
+
return {
|
|
769
|
+
id: agentId,
|
|
770
|
+
session_id: sessionId,
|
|
771
|
+
agent,
|
|
772
|
+
session,
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
catch (handleError) {
|
|
776
|
+
try {
|
|
777
|
+
await handle.close();
|
|
778
|
+
}
|
|
779
|
+
catch {
|
|
780
|
+
// Ignore errors during cleanup
|
|
781
|
+
}
|
|
782
|
+
throw handleError;
|
|
783
|
+
}
|
|
505
784
|
}
|
|
506
785
|
// ─────────────────────────────────────────────────────────────────
|
|
507
786
|
// Queries
|
|
@@ -654,11 +933,12 @@ export function createAgentManager(eventStore, messageRouter, config = {}) {
|
|
|
654
933
|
const agentCompletedStatus = statusEvents.find((e) => e.source?.agent_id === agentId &&
|
|
655
934
|
(e.payload?.status_type === "completed" ||
|
|
656
935
|
e.payload?.status_type === "failed" ||
|
|
657
|
-
e.payload?.details?.signal ===
|
|
936
|
+
e.payload?.details?.signal ===
|
|
937
|
+
"WORKER_DONE"));
|
|
658
938
|
if (agentCompletedStatus) {
|
|
659
939
|
return {
|
|
660
940
|
called: true,
|
|
661
|
-
status: agentCompletedStatus.payload?.status_type
|
|
941
|
+
status: agentCompletedStatus.payload?.status_type,
|
|
662
942
|
};
|
|
663
943
|
}
|
|
664
944
|
return { called: false };
|
|
@@ -789,6 +1069,29 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
789
1069
|
return false;
|
|
790
1070
|
}
|
|
791
1071
|
}
|
|
1072
|
+
function setPermissionMode(agentId, mode) {
|
|
1073
|
+
const activeSession = activeSessions.get(agentId);
|
|
1074
|
+
if (!activeSession) {
|
|
1075
|
+
console.warn(`[AgentManager] Cannot set permission mode: no active session for agent ${agentId}`);
|
|
1076
|
+
return false;
|
|
1077
|
+
}
|
|
1078
|
+
try {
|
|
1079
|
+
activeSession.handle.setPermissionMode(mode);
|
|
1080
|
+
console.log(`[AgentManager] Set permission mode for agent ${agentId} to ${mode}`);
|
|
1081
|
+
return true;
|
|
1082
|
+
}
|
|
1083
|
+
catch (err) {
|
|
1084
|
+
console.error(`[AgentManager] Error setting permission mode for agent ${agentId}:`, err);
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function getPermissionMode(agentId) {
|
|
1089
|
+
const activeSession = activeSessions.get(agentId);
|
|
1090
|
+
if (!activeSession) {
|
|
1091
|
+
return null;
|
|
1092
|
+
}
|
|
1093
|
+
return activeSession.handle.getPermissionMode();
|
|
1094
|
+
}
|
|
792
1095
|
// ─────────────────────────────────────────────────────────────────
|
|
793
1096
|
// Lifecycle Callbacks
|
|
794
1097
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -807,6 +1110,12 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
807
1110
|
}
|
|
808
1111
|
}
|
|
809
1112
|
// ─────────────────────────────────────────────────────────────────
|
|
1113
|
+
// OpenTasks Socket Path (Late Binding)
|
|
1114
|
+
// ─────────────────────────────────────────────────────────────────
|
|
1115
|
+
function setOpenTasksSocketPath(socketPath) {
|
|
1116
|
+
configOpenTasksSocketPath = socketPath;
|
|
1117
|
+
}
|
|
1118
|
+
// ─────────────────────────────────────────────────────────────────
|
|
810
1119
|
// Mail Services (Late Binding)
|
|
811
1120
|
// ─────────────────────────────────────────────────────────────────
|
|
812
1121
|
function setMailServices(ms, cm) {
|
|
@@ -817,6 +1126,8 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
817
1126
|
// Cleanup
|
|
818
1127
|
// ─────────────────────────────────────────────────────────────────
|
|
819
1128
|
async function close() {
|
|
1129
|
+
// Prevent new spawns/resumes from racing with cleanup
|
|
1130
|
+
isShuttingDown = true;
|
|
820
1131
|
// Stop all health checks
|
|
821
1132
|
if (healthCheckService) {
|
|
822
1133
|
healthCheckService.stopAll();
|
|
@@ -876,9 +1187,7 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
876
1187
|
}
|
|
877
1188
|
const resumeContext = contextLines.join("\n");
|
|
878
1189
|
// Spawn a continuation agent with same role, task, and context
|
|
879
|
-
const taskDescription = options?.task ??
|
|
880
|
-
agent.task ??
|
|
881
|
-
`Continue work from ${agentId}`;
|
|
1190
|
+
const taskDescription = options?.task ?? agent.task ?? `Continue work from ${agentId}`;
|
|
882
1191
|
const newAgent = await spawn({
|
|
883
1192
|
task: taskDescription,
|
|
884
1193
|
role: agent.role,
|
|
@@ -903,6 +1212,7 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
903
1212
|
terminate,
|
|
904
1213
|
resume,
|
|
905
1214
|
continueAgent,
|
|
1215
|
+
forkAgent,
|
|
906
1216
|
get,
|
|
907
1217
|
list,
|
|
908
1218
|
getChildren,
|
|
@@ -918,27 +1228,70 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
|
|
|
918
1228
|
isProcessRunning,
|
|
919
1229
|
respondToPermission,
|
|
920
1230
|
cancelPermission,
|
|
1231
|
+
setPermissionMode,
|
|
1232
|
+
getPermissionMode,
|
|
921
1233
|
onLifecycleEvent,
|
|
922
1234
|
setSpawnInterceptor,
|
|
923
1235
|
getRoleRegistry,
|
|
1236
|
+
setOpenTasksSocketPath,
|
|
924
1237
|
setMailServices,
|
|
925
1238
|
close,
|
|
926
1239
|
};
|
|
927
1240
|
}
|
|
928
1241
|
/**
|
|
929
|
-
* Create a workspace for an agent based on their
|
|
1242
|
+
* Create a workspace for an agent based on their capabilities.
|
|
1243
|
+
*
|
|
1244
|
+
* Dispatches on workspace capabilities (workspace.stream, workspace.integrate,
|
|
1245
|
+
* workspace.worktree) rather than role names. This allows team-defined roles
|
|
1246
|
+
* (e.g., "developer" extending "worker") to get proper workspace allocation
|
|
1247
|
+
* by inheriting workspace capabilities from their base role.
|
|
1248
|
+
*
|
|
1249
|
+
* Falls back to role-name matching for backward compatibility when no
|
|
1250
|
+
* capabilities are provided.
|
|
930
1251
|
*
|
|
931
1252
|
* @param workspaceManager - WorkspaceManager instance
|
|
932
1253
|
* @param agentId - Agent ID
|
|
933
|
-
* @param role - Agent role (
|
|
934
|
-
* @param options -
|
|
1254
|
+
* @param role - Agent role name (used for logging and fallback)
|
|
1255
|
+
* @param options - Workspace options including capabilities
|
|
935
1256
|
* @returns Created workspace or undefined
|
|
936
1257
|
*/
|
|
937
1258
|
async function createWorkspaceForRole(workspaceManager, agentId, role, options) {
|
|
938
|
-
const { streamId, streamConfig, dataplaneTaskId } = options;
|
|
1259
|
+
const { streamId, streamConfig, dataplaneTaskId, capabilities } = options;
|
|
1260
|
+
// Capability-based dispatch (preferred — works for team-defined roles)
|
|
1261
|
+
if (capabilities && capabilities.length > 0) {
|
|
1262
|
+
if (capabilities.includes("workspace.stream")) {
|
|
1263
|
+
// Coordinator pattern: create integration stream.
|
|
1264
|
+
// In team mode, stream is managed by TeamRuntime.setupWorkspaceIntegration(),
|
|
1265
|
+
// so missing streamConfig is expected — return silently.
|
|
1266
|
+
if (!streamConfig) {
|
|
1267
|
+
return undefined;
|
|
1268
|
+
}
|
|
1269
|
+
const newStreamId = workspaceManager.createIntegrationStream(agentId, streamConfig);
|
|
1270
|
+
return workspaceManager.createCoordinatorWorkspace(agentId, newStreamId);
|
|
1271
|
+
}
|
|
1272
|
+
else if (capabilities.includes("workspace.integrate")) {
|
|
1273
|
+
// Integrator pattern: join existing stream
|
|
1274
|
+
if (!streamId) {
|
|
1275
|
+
console.warn(`[AgentManager] ${role} ${agentId} has workspace.integrate but no streamId, skipping workspace`);
|
|
1276
|
+
return undefined;
|
|
1277
|
+
}
|
|
1278
|
+
return workspaceManager.createIntegratorWorkspace(agentId, streamId);
|
|
1279
|
+
}
|
|
1280
|
+
else if (capabilities.includes("workspace.worktree")) {
|
|
1281
|
+
// Worker pattern: create worktree in stream
|
|
1282
|
+
if (!streamId) {
|
|
1283
|
+
console.warn(`[AgentManager] ${role} ${agentId} has workspace.worktree but no streamId, skipping workspace`);
|
|
1284
|
+
return undefined;
|
|
1285
|
+
}
|
|
1286
|
+
const taskId = dataplaneTaskId ?? agentId;
|
|
1287
|
+
return workspaceManager.createWorkerWorkspace(agentId, taskId, streamId);
|
|
1288
|
+
}
|
|
1289
|
+
// Has capabilities but no workspace capability — no workspace needed
|
|
1290
|
+
return undefined;
|
|
1291
|
+
}
|
|
1292
|
+
// Fallback: role-name dispatch (backward compatibility for non-team spawns)
|
|
939
1293
|
switch (role) {
|
|
940
1294
|
case "coordinator": {
|
|
941
|
-
// Coordinators create a new integration stream
|
|
942
1295
|
if (!streamConfig) {
|
|
943
1296
|
console.warn(`[AgentManager] Coordinator ${agentId} spawn missing streamConfig, skipping workspace`);
|
|
944
1297
|
return undefined;
|
|
@@ -947,7 +1300,6 @@ async function createWorkspaceForRole(workspaceManager, agentId, role, options)
|
|
|
947
1300
|
return workspaceManager.createCoordinatorWorkspace(agentId, newStreamId);
|
|
948
1301
|
}
|
|
949
1302
|
case "integrator": {
|
|
950
|
-
// Integrators join an existing stream
|
|
951
1303
|
if (!streamId) {
|
|
952
1304
|
console.warn(`[AgentManager] Integrator ${agentId} spawn missing streamId, skipping workspace`);
|
|
953
1305
|
return undefined;
|
|
@@ -956,24 +1308,16 @@ async function createWorkspaceForRole(workspaceManager, agentId, role, options)
|
|
|
956
1308
|
}
|
|
957
1309
|
case "worker":
|
|
958
1310
|
case "worker.resolver": {
|
|
959
|
-
// Workers need streamId and either dataplaneTaskId or create a new task
|
|
960
1311
|
if (!streamId) {
|
|
961
1312
|
console.warn(`[AgentManager] Worker ${agentId} spawn missing streamId, skipping workspace`);
|
|
962
1313
|
return undefined;
|
|
963
1314
|
}
|
|
964
|
-
|
|
965
|
-
const taskId = dataplaneTaskId;
|
|
966
|
-
if (!taskId) {
|
|
967
|
-
console.warn(`[AgentManager] Worker ${agentId} spawn missing dataplaneTaskId, skipping workspace`);
|
|
968
|
-
return undefined;
|
|
969
|
-
}
|
|
1315
|
+
const taskId = dataplaneTaskId ?? agentId;
|
|
970
1316
|
return workspaceManager.createWorkerWorkspace(agentId, taskId, streamId);
|
|
971
1317
|
}
|
|
972
1318
|
case "monitor":
|
|
973
|
-
// Monitors don't need workspaces
|
|
974
1319
|
return undefined;
|
|
975
1320
|
default:
|
|
976
|
-
// Unknown role - no workspace
|
|
977
1321
|
return undefined;
|
|
978
1322
|
}
|
|
979
1323
|
}
|