macro-agent 0.0.11 → 0.0.12
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/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
- package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
- package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
- package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
- package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
- package/.macro-agent/teams/self-driving/team.yaml +103 -0
- package/.macro-agent/teams/structured/prompts/developer.md +26 -0
- package/.macro-agent/teams/structured/prompts/lead.md +25 -0
- package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
- package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
- package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
- package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
- package/.macro-agent/teams/structured/team.yaml +89 -0
- package/.sudocode/issues.jsonl +6 -0
- package/.sudocode/specs.jsonl +7 -0
- package/CLAUDE.md +110 -30
- package/README.md +60 -3
- package/dist/acp/macro-agent.d.ts +4 -0
- package/dist/acp/macro-agent.d.ts.map +1 -1
- package/dist/acp/macro-agent.js +50 -4
- package/dist/acp/macro-agent.js.map +1 -1
- package/dist/acp/session-mapper.d.ts +20 -1
- package/dist/acp/session-mapper.d.ts.map +1 -1
- package/dist/acp/session-mapper.js +90 -1
- package/dist/acp/session-mapper.js.map +1 -1
- package/dist/acp/types.d.ts +24 -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 +25 -1
- package/dist/agent/agent-manager.d.ts.map +1 -1
- package/dist/agent/agent-manager.js +93 -7
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +22 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agent-detection/command-builder.d.ts +30 -0
- package/dist/agent-detection/command-builder.d.ts.map +1 -0
- package/dist/agent-detection/command-builder.js +71 -0
- package/dist/agent-detection/command-builder.js.map +1 -0
- package/dist/agent-detection/detector.d.ts +84 -0
- package/dist/agent-detection/detector.d.ts.map +1 -0
- package/dist/agent-detection/detector.js +240 -0
- package/dist/agent-detection/detector.js.map +1 -0
- package/dist/agent-detection/index.d.ts +12 -0
- package/dist/agent-detection/index.d.ts.map +1 -0
- package/dist/agent-detection/index.js +14 -0
- package/dist/agent-detection/index.js.map +1 -0
- package/dist/agent-detection/registry.d.ts +53 -0
- package/dist/agent-detection/registry.d.ts.map +1 -0
- package/dist/agent-detection/registry.js +177 -0
- package/dist/agent-detection/registry.js.map +1 -0
- package/dist/agent-detection/types.d.ts +121 -0
- package/dist/agent-detection/types.d.ts.map +1 -0
- package/dist/agent-detection/types.js +20 -0
- package/dist/agent-detection/types.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +95 -0
- package/dist/api/server.js.map +1 -1
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp.js +38 -0
- package/dist/cli/mcp.js.map +1 -1
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/project-config.d.ts +46 -0
- package/dist/config/project-config.d.ts.map +1 -0
- package/dist/config/project-config.js +68 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/lifecycle/cascade.d.ts +1 -1
- package/dist/lifecycle/cascade.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.d.ts +4 -0
- package/dist/lifecycle/handlers/index.d.ts.map +1 -1
- package/dist/lifecycle/handlers/index.js +2 -0
- package/dist/lifecycle/handlers/index.js.map +1 -1
- package/dist/lifecycle/handlers/worker.d.ts +4 -0
- package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
- package/dist/lifecycle/handlers/worker.js +35 -3
- package/dist/lifecycle/handlers/worker.js.map +1 -1
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
- package/dist/map/adapter/acp-over-map.js +32 -2
- package/dist/map/adapter/acp-over-map.js.map +1 -1
- package/dist/map/adapter/event-translator.d.ts.map +1 -1
- package/dist/map/adapter/event-translator.js +1 -0
- package/dist/map/adapter/event-translator.js.map +1 -1
- package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
- package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-detection.js +91 -0
- package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +10 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +39 -0
- package/dist/map/adapter/extensions/index.js.map +1 -1
- package/dist/map/adapter/extensions/resume.d.ts +47 -0
- package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
- package/dist/map/adapter/extensions/resume.js +59 -0
- package/dist/map/adapter/extensions/resume.js.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.js +338 -0
- package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +6 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +45 -0
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/tools/claim_task.d.ts +35 -0
- package/dist/mcp/tools/claim_task.d.ts.map +1 -0
- package/dist/mcp/tools/claim_task.js +58 -0
- package/dist/mcp/tools/claim_task.js.map +1 -0
- package/dist/mcp/tools/done.d.ts +11 -2
- package/dist/mcp/tools/done.d.ts.map +1 -1
- package/dist/mcp/tools/done.js +15 -10
- package/dist/mcp/tools/done.js.map +1 -1
- package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
- package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
- package/dist/mcp/tools/list_claimable_tasks.js +63 -0
- package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
- package/dist/mcp/tools/unclaim_task.d.ts +31 -0
- package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
- package/dist/mcp/tools/unclaim_task.js +47 -0
- package/dist/mcp/tools/unclaim_task.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +2 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/metrics.d.ts +79 -0
- package/dist/metrics/metrics.d.ts.map +1 -0
- package/dist/metrics/metrics.js +166 -0
- package/dist/metrics/metrics.js.map +1 -0
- package/dist/roles/capabilities.d.ts +1 -0
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +3 -0
- package/dist/roles/capabilities.js.map +1 -1
- package/dist/roles/types.d.ts +1 -1
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/router/message-router.d.ts +41 -0
- package/dist/router/message-router.d.ts.map +1 -1
- package/dist/router/message-router.js +136 -5
- package/dist/router/message-router.js.map +1 -1
- package/dist/store/event-store.d.ts +8 -1
- package/dist/store/event-store.d.ts.map +1 -1
- package/dist/store/event-store.js +120 -4
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +1 -1
- 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/store/types/events.js.map +1 -1
- package/dist/store/types/index.d.ts +1 -0
- package/dist/store/types/index.d.ts.map +1 -1
- package/dist/store/types/index.js +1 -0
- package/dist/store/types/index.js.map +1 -1
- package/dist/store/types/sessions.d.ts +44 -0
- package/dist/store/types/sessions.d.ts.map +1 -0
- package/dist/store/types/sessions.js +9 -0
- package/dist/store/types/sessions.js.map +1 -0
- package/dist/store/types/tasks.d.ts +2 -0
- package/dist/store/types/tasks.d.ts.map +1 -1
- package/dist/task/backend/memory.d.ts +4 -1
- package/dist/task/backend/memory.d.ts.map +1 -1
- package/dist/task/backend/memory.js +81 -0
- package/dist/task/backend/memory.js.map +1 -1
- package/dist/task/backend/types.d.ts +30 -0
- package/dist/task/backend/types.d.ts.map +1 -1
- package/dist/task/backend/types.js.map +1 -1
- package/dist/teams/index.d.ts +4 -0
- package/dist/teams/index.d.ts.map +1 -0
- package/dist/teams/index.js +4 -0
- package/dist/teams/index.js.map +1 -0
- package/dist/teams/team-loader.d.ts +20 -0
- package/dist/teams/team-loader.d.ts.map +1 -0
- package/dist/teams/team-loader.js +293 -0
- package/dist/teams/team-loader.js.map +1 -0
- package/dist/teams/team-runtime.d.ts +139 -0
- package/dist/teams/team-runtime.d.ts.map +1 -0
- package/dist/teams/team-runtime.js +613 -0
- package/dist/teams/team-runtime.js.map +1 -0
- package/dist/teams/types.d.ts +266 -0
- package/dist/teams/types.d.ts.map +1 -0
- package/dist/teams/types.js +20 -0
- package/dist/teams/types.js.map +1 -0
- package/dist/workspace/dataplane-adapter.d.ts +1 -1
- package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
- package/dist/workspace/dataplane-adapter.js +1 -1
- package/dist/workspace/dataplane-adapter.js.map +1 -1
- package/dist/workspace/index.d.ts +1 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/strategies/index.d.ts +6 -0
- package/dist/workspace/strategies/index.d.ts.map +1 -0
- package/dist/workspace/strategies/index.js +5 -0
- package/dist/workspace/strategies/index.js.map +1 -0
- package/dist/workspace/strategies/optimistic.d.ts +26 -0
- package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
- package/dist/workspace/strategies/optimistic.js +121 -0
- package/dist/workspace/strategies/optimistic.js.map +1 -0
- package/dist/workspace/strategies/queue.d.ts +26 -0
- package/dist/workspace/strategies/queue.d.ts.map +1 -0
- package/dist/workspace/strategies/queue.js +67 -0
- package/dist/workspace/strategies/queue.js.map +1 -0
- package/dist/workspace/strategies/registry.d.ts +37 -0
- package/dist/workspace/strategies/registry.d.ts.map +1 -0
- package/dist/workspace/strategies/registry.js +63 -0
- package/dist/workspace/strategies/registry.js.map +1 -0
- package/dist/workspace/strategies/trunk.d.ts +20 -0
- package/dist/workspace/strategies/trunk.d.ts.map +1 -0
- package/dist/workspace/strategies/trunk.js +108 -0
- package/dist/workspace/strategies/trunk.js.map +1 -0
- package/dist/workspace/strategies/types.d.ts +104 -0
- package/dist/workspace/strategies/types.d.ts.map +1 -0
- package/dist/workspace/strategies/types.js +11 -0
- package/dist/workspace/strategies/types.js.map +1 -0
- package/dist/workspace/types.d.ts +1 -1
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +1 -1
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/docs/implementation-details.md +1127 -0
- package/docs/implementation-summary.md +448 -0
- package/docs/plan-self-driving-support.md +433 -0
- package/docs/spec-self-driving-support.md +462 -0
- package/docs/team-templates.md +860 -0
- package/docs/teams.md +233 -0
- package/package.json +4 -2
- package/src/acp/__tests__/integration.test.ts +161 -1
- package/src/acp/__tests__/macro-agent.test.ts +95 -0
- package/src/acp/__tests__/session-persistence.test.ts +276 -0
- package/src/acp/macro-agent.ts +79 -7
- package/src/acp/session-mapper.ts +108 -1
- package/src/acp/types.ts +33 -1
- package/src/agent/agent-manager.ts +158 -6
- package/src/agent/types.ts +27 -0
- package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
- package/src/agent-detection/__tests__/detector.test.ts +768 -0
- package/src/agent-detection/__tests__/registry.test.ts +254 -0
- package/src/agent-detection/command-builder.ts +90 -0
- package/src/agent-detection/detector.ts +307 -0
- package/src/agent-detection/index.ts +36 -0
- package/src/agent-detection/registry.ts +200 -0
- package/src/agent-detection/types.ts +184 -0
- package/src/api/server.ts +110 -0
- package/src/cli/index.ts +44 -0
- package/src/cli/mcp.ts +47 -0
- package/src/config/index.ts +9 -0
- package/src/config/project-config.ts +107 -0
- package/src/lifecycle/cascade.ts +1 -1
- package/src/lifecycle/handlers/index.ts +8 -0
- package/src/lifecycle/handlers/worker.ts +48 -3
- package/src/map/adapter/__tests__/extensions.test.ts +359 -0
- package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
- package/src/map/adapter/acp-over-map.ts +45 -2
- package/src/map/adapter/event-translator.ts +1 -0
- package/src/map/adapter/extensions/agent-detection.ts +201 -0
- package/src/map/adapter/extensions/index.ts +63 -0
- package/src/map/adapter/extensions/resume.ts +114 -0
- package/src/map/adapter/extensions/workspace-files.ts +449 -0
- package/src/mcp/mcp-server.ts +67 -0
- package/src/mcp/tools/claim_task.ts +86 -0
- package/src/mcp/tools/done.ts +24 -10
- package/src/mcp/tools/list_claimable_tasks.ts +93 -0
- package/src/mcp/tools/unclaim_task.ts +71 -0
- package/src/metrics/index.ts +9 -0
- package/src/metrics/metrics.ts +280 -0
- package/src/roles/capabilities.ts +3 -0
- package/src/roles/types.ts +2 -1
- package/src/router/__tests__/message-router.test.ts +561 -0
- package/src/router/message-router.ts +223 -6
- package/src/store/event-store.ts +151 -3
- package/src/store/types/agents.ts +1 -1
- package/src/store/types/events.ts +2 -1
- package/src/store/types/index.ts +1 -0
- package/src/store/types/sessions.ts +53 -0
- package/src/store/types/tasks.ts +3 -0
- package/src/task/backend/memory.ts +116 -0
- package/src/task/backend/types.ts +43 -0
- package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
- package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
- package/src/teams/__tests__/team-system.test.ts +1280 -0
- package/src/teams/index.ts +13 -0
- package/src/teams/team-loader.ts +434 -0
- package/src/teams/team-runtime.ts +727 -0
- package/src/teams/types.ts +377 -0
- package/src/workspace/dataplane-adapter.ts +1 -1
- package/src/workspace/index.ts +1 -1
- package/src/workspace/strategies/index.ts +18 -0
- package/src/workspace/strategies/optimistic.ts +136 -0
- package/src/workspace/strategies/queue.ts +81 -0
- package/src/workspace/strategies/registry.ts +89 -0
- package/src/workspace/strategies/trunk.ts +123 -0
- package/src/workspace/strategies/types.ts +145 -0
- package/src/workspace/types.ts +1 -1
- package/src/workspace/workspace-manager.ts +1 -1
- package/.claude/settings.local.json +0 -59
- package/dist/map/utils/address-translation.d.ts +0 -99
- package/dist/map/utils/address-translation.d.ts.map +0 -1
- package/dist/map/utils/address-translation.js +0 -285
- package/dist/map/utils/address-translation.js.map +0 -1
- package/dist/map/utils/index.d.ts +0 -7
- package/dist/map/utils/index.d.ts.map +0 -1
- package/dist/map/utils/index.js +0 -7
- package/dist/map/utils/index.js.map +0 -1
- package/references/acp-factory-ref/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/LICENSE +0 -21
- package/references/acp-factory-ref/README.md +0 -341
- package/references/acp-factory-ref/package-lock.json +0 -3102
- package/references/acp-factory-ref/package.json +0 -96
- package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
- package/references/acp-factory-ref/python/LICENSE +0 -21
- package/references/acp-factory-ref/python/Makefile +0 -57
- package/references/acp-factory-ref/python/README.md +0 -253
- package/references/acp-factory-ref/python/pyproject.toml +0 -73
- package/references/acp-factory-ref/python/tests/__init__.py +0 -0
- package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
- package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
- package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
- package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
- package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
- package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
- package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
- package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
- package/references/claude-code-acp/.prettierrc.json +0 -4
- package/references/claude-code-acp/CHANGELOG.md +0 -249
- package/references/claude-code-acp/LICENSE +0 -222
- package/references/claude-code-acp/README.md +0 -53
- package/references/claude-code-acp/docs/RELEASES.md +0 -24
- package/references/claude-code-acp/eslint.config.js +0 -48
- package/references/claude-code-acp/package-lock.json +0 -4570
- package/references/claude-code-acp/package.json +0 -88
- package/references/claude-code-acp/scripts/release.sh +0 -119
- package/references/claude-code-acp/src/acp-agent.ts +0 -2065
- package/references/claude-code-acp/src/index.ts +0 -26
- package/references/claude-code-acp/src/lib.ts +0 -38
- package/references/claude-code-acp/src/mcp-server.ts +0 -911
- package/references/claude-code-acp/src/settings.ts +0 -522
- package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
- package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
- package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
- package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
- package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
- package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
- package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
- package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
- package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
- package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
- package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
- package/references/claude-code-acp/src/tools.ts +0 -819
- package/references/claude-code-acp/src/utils.ts +0 -171
- package/references/claude-code-acp/tsconfig.json +0 -18
- package/references/claude-code-acp/vitest.config.ts +0 -19
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -111
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -13
- package/references/multi-agent-protocol/LICENSE +0 -21
- package/references/multi-agent-protocol/README.md +0 -113
- package/references/multi-agent-protocol/docs/00-design-specification.md +0 -496
- package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
- package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
- package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
- package/references/multi-agent-protocol/docs/07-federation.md +0 -259
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
- package/references/multi-agent-protocol/docs/09-authentication.md +0 -680
- package/references/multi-agent-protocol/docs/10-mail-protocol.md +0 -553
- package/references/multi-agent-protocol/docs/agent-iam-integration.md +0 -877
- package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +0 -459
- package/references/multi-agent-protocol/docs/git-transport-draft.md +0 -251
- package/references/multi-agent-protocol/docs-site/Gemfile +0 -22
- package/references/multi-agent-protocol/docs-site/README.md +0 -82
- package/references/multi-agent-protocol/docs-site/_config.yml +0 -91
- package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +0 -20
- package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +0 -42
- package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +0 -34
- package/references/multi-agent-protocol/docs-site/examples/full-integration.md +0 -510
- package/references/multi-agent-protocol/docs-site/examples/index.md +0 -138
- package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +0 -282
- package/references/multi-agent-protocol/docs-site/examples/task-queue.md +0 -399
- package/references/multi-agent-protocol/docs-site/getting-started/index.md +0 -98
- package/references/multi-agent-protocol/docs-site/getting-started/installation.md +0 -219
- package/references/multi-agent-protocol/docs-site/getting-started/overview.md +0 -172
- package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +0 -237
- package/references/multi-agent-protocol/docs-site/index.md +0 -136
- package/references/multi-agent-protocol/docs-site/protocol/authentication.md +0 -391
- package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +0 -376
- package/references/multi-agent-protocol/docs-site/protocol/design.md +0 -284
- package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +0 -312
- package/references/multi-agent-protocol/docs-site/protocol/federation.md +0 -449
- package/references/multi-agent-protocol/docs-site/protocol/index.md +0 -129
- package/references/multi-agent-protocol/docs-site/protocol/permissions.md +0 -398
- package/references/multi-agent-protocol/docs-site/protocol/streaming.md +0 -353
- package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +0 -369
- package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +0 -357
- package/references/multi-agent-protocol/docs-site/sdk/api/client.md +0 -380
- package/references/multi-agent-protocol/docs-site/sdk/api/index.md +0 -62
- package/references/multi-agent-protocol/docs-site/sdk/api/server.md +0 -453
- package/references/multi-agent-protocol/docs-site/sdk/api/types.md +0 -468
- package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +0 -375
- package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +0 -405
- package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +0 -352
- package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +0 -89
- package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +0 -360
- package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +0 -446
- package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +0 -363
- package/references/multi-agent-protocol/docs-site/sdk/index.md +0 -206
- package/references/multi-agent-protocol/package-lock.json +0 -3886
- package/references/multi-agent-protocol/package.json +0 -56
- package/references/multi-agent-protocol/schema/meta.json +0 -467
- package/references/multi-agent-protocol/schema/schema.json +0 -2558
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team Runtime E2E Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the full team system pipeline: template loading, runtime initialization,
|
|
5
|
+
* agent bootstrapping, spawn interception, and role capability propagation to
|
|
6
|
+
* MCP subprocesses.
|
|
7
|
+
*
|
|
8
|
+
* Group 1 (infrastructure) runs without real agents — tests TeamRuntime wiring
|
|
9
|
+
* against real EventStore, AgentManager, MessageRouter.
|
|
10
|
+
*
|
|
11
|
+
* Group 2 (full agent) spawns real Claude Code agents and requires:
|
|
12
|
+
* RUN_FULL_AGENT_TESTS=true
|
|
13
|
+
*
|
|
14
|
+
* Run:
|
|
15
|
+
* npm run test:e2e -- src/teams/__tests__/e2e/team-runtime.e2e.test.ts
|
|
16
|
+
* RUN_FULL_AGENT_TESTS=true npm run test:e2e -- src/teams/__tests__/e2e/team-runtime.e2e.test.ts
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
20
|
+
import * as fs from "fs";
|
|
21
|
+
import * as path from "path";
|
|
22
|
+
import * as os from "os";
|
|
23
|
+
import { execSync } from "child_process";
|
|
24
|
+
|
|
25
|
+
import { createEventStore, type EventStore } from "../../../store/event-store.js";
|
|
26
|
+
import { createAgentManager, type AgentManager } from "../../../agent/agent-manager.js";
|
|
27
|
+
import { createTaskManager, type TaskManager } from "../../../task/task-manager.js";
|
|
28
|
+
import { createMessageRouter, type MessageRouter } from "../../../router/message-router.js";
|
|
29
|
+
import { DefaultRoleRegistry } from "../../../roles/registry.js";
|
|
30
|
+
import type { RoleDefinition } from "../../../roles/types.js";
|
|
31
|
+
import { loadTeam } from "../../team-loader.js";
|
|
32
|
+
import { TeamRuntime, type TeamServices } from "../../team-runtime.js";
|
|
33
|
+
|
|
34
|
+
// ─────────────────────────────────────────────────────────────────
|
|
35
|
+
// Configuration
|
|
36
|
+
// ─────────────────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
const RUN_FULL_AGENT = !!process.env.RUN_FULL_AGENT_TESTS;
|
|
39
|
+
const testFn = RUN_FULL_AGENT ? it : it.skip;
|
|
40
|
+
const PROJECT_ROOT = path.resolve(import.meta.dirname, "../../../..");
|
|
41
|
+
|
|
42
|
+
const log = (msg: string) => console.log(`[TeamRuntime-E2E] ${msg}`);
|
|
43
|
+
|
|
44
|
+
const TIMEOUT = {
|
|
45
|
+
SPAWN: 60000,
|
|
46
|
+
PROMPT: 120000,
|
|
47
|
+
BOOTSTRAP: 180000,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// ─────────────────────────────────────────────────────────────────
|
|
51
|
+
// Helpers
|
|
52
|
+
// ─────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
interface TempTestEnv {
|
|
55
|
+
tmpDir: string;
|
|
56
|
+
repoPath: string;
|
|
57
|
+
cleanup: () => void;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createTestEnv(prefix: string): TempTestEnv {
|
|
61
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), `team-e2e-${prefix}-`));
|
|
62
|
+
const repoPath = path.join(tmpDir, "repo");
|
|
63
|
+
fs.mkdirSync(repoPath);
|
|
64
|
+
execSync("git init", { cwd: repoPath, stdio: "pipe" });
|
|
65
|
+
execSync('git config user.email "test@test.com"', { cwd: repoPath, stdio: "pipe" });
|
|
66
|
+
execSync('git config user.name "Test"', { cwd: repoPath, stdio: "pipe" });
|
|
67
|
+
fs.writeFileSync(path.join(repoPath, "README.md"), "# test\n");
|
|
68
|
+
execSync("git add -A && git commit -m init", { cwd: repoPath, stdio: "pipe" });
|
|
69
|
+
return {
|
|
70
|
+
tmpDir,
|
|
71
|
+
repoPath,
|
|
72
|
+
cleanup: () => fs.rmSync(tmpDir, { recursive: true, force: true }),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function waitForAgentState(
|
|
77
|
+
agentManager: AgentManager,
|
|
78
|
+
agentId: string,
|
|
79
|
+
state: "running" | "stopped",
|
|
80
|
+
timeoutMs = 60000
|
|
81
|
+
): Promise<void> {
|
|
82
|
+
const start = Date.now();
|
|
83
|
+
while (Date.now() - start < timeoutMs) {
|
|
84
|
+
const agent = agentManager.get(agentId);
|
|
85
|
+
if (agent?.state === state) return;
|
|
86
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`Timeout: agent ${agentId} did not reach state '${state}' in ${timeoutMs}ms`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ─────────────────────────────────────────────────────────────────
|
|
92
|
+
// Group 1: Team Infrastructure (no real agents)
|
|
93
|
+
// ─────────────────────────────────────────────────────────────────
|
|
94
|
+
|
|
95
|
+
describe("Team Runtime E2E — Infrastructure", () => {
|
|
96
|
+
let env: TempTestEnv;
|
|
97
|
+
let eventStore: EventStore;
|
|
98
|
+
let agentManager: AgentManager;
|
|
99
|
+
let messageRouter: MessageRouter;
|
|
100
|
+
let taskManager: TaskManager;
|
|
101
|
+
let roleRegistry: DefaultRoleRegistry;
|
|
102
|
+
|
|
103
|
+
beforeEach(async () => {
|
|
104
|
+
env = createTestEnv("infra");
|
|
105
|
+
const instanceId = `team-infra-${Date.now()}`;
|
|
106
|
+
|
|
107
|
+
eventStore = await createEventStore({ instanceId, baseDir: env.tmpDir });
|
|
108
|
+
messageRouter = createMessageRouter(eventStore);
|
|
109
|
+
roleRegistry = new DefaultRoleRegistry();
|
|
110
|
+
agentManager = createAgentManager(eventStore, messageRouter, {
|
|
111
|
+
defaultPermissionMode: "auto-approve",
|
|
112
|
+
defaultCwd: env.repoPath,
|
|
113
|
+
});
|
|
114
|
+
taskManager = createTaskManager(eventStore);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
afterEach(async () => {
|
|
118
|
+
await agentManager?.close();
|
|
119
|
+
await eventStore?.close();
|
|
120
|
+
env?.cleanup();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("loads team template and initializes runtime with serialized roles", async () => {
|
|
124
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
125
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
126
|
+
const runtime = new TeamRuntime(manifest, services);
|
|
127
|
+
|
|
128
|
+
await runtime.initialize();
|
|
129
|
+
|
|
130
|
+
// 1. Roles registered in AgentManager's internal registry
|
|
131
|
+
const amRegistry = agentManager.getRoleRegistry();
|
|
132
|
+
expect(amRegistry.getRole("planner")).toBeDefined();
|
|
133
|
+
expect(amRegistry.getRole("grinder")).toBeDefined();
|
|
134
|
+
expect(amRegistry.getRole("judge")).toBeDefined();
|
|
135
|
+
log("Roles registered in registry");
|
|
136
|
+
|
|
137
|
+
// 2. team_config event emitted to EventStore
|
|
138
|
+
const events = eventStore.query({ type: "status", limit: 50 });
|
|
139
|
+
const configEvent = events.find((e) => e.payload?.team_config != null);
|
|
140
|
+
expect(configEvent).toBeDefined();
|
|
141
|
+
|
|
142
|
+
const tc = configEvent!.payload.team_config as Record<string, unknown>;
|
|
143
|
+
expect(tc.teamName).toBe("self-driving");
|
|
144
|
+
expect(tc.strategy).toBe("trunk");
|
|
145
|
+
expect(tc.taskMode).toBe("pull");
|
|
146
|
+
log("team_config event verified");
|
|
147
|
+
|
|
148
|
+
// 3. Serialized roles included in team_config (Issue #1 fix)
|
|
149
|
+
const roles = tc.roles as Record<string, { name: string; capabilities: string[] }>;
|
|
150
|
+
expect(roles).toBeDefined();
|
|
151
|
+
expect(roles.planner).toBeDefined();
|
|
152
|
+
expect(roles.grinder).toBeDefined();
|
|
153
|
+
expect(roles.judge).toBeDefined();
|
|
154
|
+
expect(roles.grinder.name).toBe("grinder");
|
|
155
|
+
expect(roles.grinder.capabilities).toContain("lifecycle.done");
|
|
156
|
+
expect(roles.planner.capabilities).toContain("task.claim");
|
|
157
|
+
log("Serialized roles in team_config verified");
|
|
158
|
+
|
|
159
|
+
// 4. Integration strategy instantiated (Issue #3 fix)
|
|
160
|
+
const strategy = runtime.getIntegrationStrategy();
|
|
161
|
+
expect(strategy).toBeDefined();
|
|
162
|
+
expect(strategy!.name).toBe("trunk");
|
|
163
|
+
log("Integration strategy instantiated");
|
|
164
|
+
|
|
165
|
+
await runtime.teardown();
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("serialized roles are deserializable in a fresh registry", async () => {
|
|
169
|
+
// Step 1: Initialize team to get serialized roles into EventStore
|
|
170
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
171
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
172
|
+
const runtime = new TeamRuntime(manifest, services);
|
|
173
|
+
await runtime.initialize();
|
|
174
|
+
|
|
175
|
+
// Step 2: Read team_config from EventStore (like MCP subprocess would)
|
|
176
|
+
const events = eventStore.query({ type: "status", limit: 50 });
|
|
177
|
+
const configEvent = events.find((e) => e.payload?.team_config != null);
|
|
178
|
+
const tc = configEvent!.payload.team_config as Record<string, unknown>;
|
|
179
|
+
const serializedRoles = tc.roles as Record<string, Record<string, unknown>>;
|
|
180
|
+
|
|
181
|
+
// Step 3: Create a fresh registry (simulating MCP subprocess)
|
|
182
|
+
const freshRegistry = new DefaultRoleRegistry();
|
|
183
|
+
|
|
184
|
+
// Verify "grinder" is unknown before registration
|
|
185
|
+
const beforeResolve = freshRegistry.resolveRole("grinder");
|
|
186
|
+
// Falls back to generic role which won't have lifecycle.done
|
|
187
|
+
expect(beforeResolve.name).not.toBe("grinder");
|
|
188
|
+
|
|
189
|
+
// Step 4: Register serialized roles
|
|
190
|
+
for (const roleDef of Object.values(serializedRoles)) {
|
|
191
|
+
freshRegistry.registerRole(roleDef as RoleDefinition);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Step 5: Verify capability resolution
|
|
195
|
+
expect(freshRegistry.hasCapability("grinder", "lifecycle.done")).toBe(true);
|
|
196
|
+
expect(freshRegistry.hasCapability("planner", "task.claim")).toBe(true);
|
|
197
|
+
expect(freshRegistry.hasCapability("judge", "lifecycle.done")).toBe(true);
|
|
198
|
+
log("Serialized roles deserialized and resolved correctly in fresh registry");
|
|
199
|
+
|
|
200
|
+
await runtime.teardown();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it("teardown clears interceptor and strategy lifecycle", async () => {
|
|
204
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
205
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
206
|
+
const runtime = new TeamRuntime(manifest, services);
|
|
207
|
+
|
|
208
|
+
await runtime.initialize();
|
|
209
|
+
expect(runtime.getIntegrationStrategy()).toBeDefined();
|
|
210
|
+
|
|
211
|
+
await runtime.teardown();
|
|
212
|
+
|
|
213
|
+
// Getters still work (they read manifest, not mutable state)
|
|
214
|
+
expect(runtime.getStrategyName()).toBe("trunk");
|
|
215
|
+
expect(runtime.getTaskMode()).toBe("pull");
|
|
216
|
+
log("Teardown completed without errors");
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
it("structured team initializes with queue strategy", async () => {
|
|
220
|
+
const manifest = await loadTeam("structured", roleRegistry, PROJECT_ROOT);
|
|
221
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
222
|
+
const runtime = new TeamRuntime(manifest, services);
|
|
223
|
+
|
|
224
|
+
await runtime.initialize();
|
|
225
|
+
|
|
226
|
+
expect(runtime.getStrategyName()).toBe("queue");
|
|
227
|
+
expect(runtime.getTaskMode()).toBe("push");
|
|
228
|
+
|
|
229
|
+
const strategy = runtime.getIntegrationStrategy();
|
|
230
|
+
expect(strategy).toBeDefined();
|
|
231
|
+
expect(strategy!.name).toBe("queue");
|
|
232
|
+
|
|
233
|
+
// Verify structured team roles serialized
|
|
234
|
+
const events = eventStore.query({ type: "status", limit: 50 });
|
|
235
|
+
const configEvent = events.find((e) => e.payload?.team_config != null);
|
|
236
|
+
const tc = configEvent!.payload.team_config as Record<string, unknown>;
|
|
237
|
+
const roles = tc.roles as Record<string, { name: string; capabilities: string[] }>;
|
|
238
|
+
expect(roles.lead).toBeDefined();
|
|
239
|
+
expect(roles.developer).toBeDefined();
|
|
240
|
+
expect(roles.reviewer).toBeDefined();
|
|
241
|
+
log("Structured team initialized correctly");
|
|
242
|
+
|
|
243
|
+
await runtime.teardown();
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// ─────────────────────────────────────────────────────────────────
|
|
248
|
+
// Group 2: Full Agent Tests (requires RUN_FULL_AGENT_TESTS)
|
|
249
|
+
// ─────────────────────────────────────────────────────────────────
|
|
250
|
+
|
|
251
|
+
describe("Team Runtime E2E — Full Agent", () => {
|
|
252
|
+
let env: TempTestEnv;
|
|
253
|
+
let eventStore: EventStore;
|
|
254
|
+
let agentManager: AgentManager;
|
|
255
|
+
let messageRouter: MessageRouter;
|
|
256
|
+
let taskManager: TaskManager;
|
|
257
|
+
let roleRegistry: DefaultRoleRegistry;
|
|
258
|
+
let runtime: TeamRuntime | null = null;
|
|
259
|
+
|
|
260
|
+
beforeEach(async () => {
|
|
261
|
+
if (!RUN_FULL_AGENT) return;
|
|
262
|
+
|
|
263
|
+
env = createTestEnv("agent");
|
|
264
|
+
const instanceId = `team-agent-${Date.now()}`;
|
|
265
|
+
|
|
266
|
+
eventStore = await createEventStore({ instanceId, baseDir: env.tmpDir });
|
|
267
|
+
messageRouter = createMessageRouter(eventStore);
|
|
268
|
+
roleRegistry = new DefaultRoleRegistry();
|
|
269
|
+
agentManager = createAgentManager(eventStore, messageRouter, {
|
|
270
|
+
defaultPermissionMode: "auto-approve",
|
|
271
|
+
defaultCwd: env.repoPath,
|
|
272
|
+
});
|
|
273
|
+
taskManager = createTaskManager(eventStore);
|
|
274
|
+
|
|
275
|
+
log("Services initialized");
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
afterEach(async () => {
|
|
279
|
+
if (!RUN_FULL_AGENT) return;
|
|
280
|
+
|
|
281
|
+
// Teardown team runtime first
|
|
282
|
+
if (runtime) {
|
|
283
|
+
try { await runtime.teardown(); } catch { /* ignore */ }
|
|
284
|
+
runtime = null;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Terminate all running agents
|
|
288
|
+
try {
|
|
289
|
+
for (const agent of agentManager.list()) {
|
|
290
|
+
if (agent.state === "running") {
|
|
291
|
+
try { await agentManager.terminate(agent.id, "test_cleanup"); } catch { /* ignore */ }
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
} catch { /* ignore */ }
|
|
295
|
+
|
|
296
|
+
await agentManager?.close();
|
|
297
|
+
await eventStore?.close();
|
|
298
|
+
env?.cleanup();
|
|
299
|
+
log("Cleanup complete");
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
testFn(
|
|
303
|
+
"team bootstrap spawns root and companion agents",
|
|
304
|
+
async () => {
|
|
305
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
306
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
307
|
+
runtime = new TeamRuntime(manifest, services);
|
|
308
|
+
|
|
309
|
+
await runtime.initialize();
|
|
310
|
+
log("Runtime initialized");
|
|
311
|
+
|
|
312
|
+
const result = await runtime.bootstrap();
|
|
313
|
+
log(`Bootstrap complete: root=${result.rootId}, companions=${result.companionIds.join(", ")}`);
|
|
314
|
+
|
|
315
|
+
// Verify root agent is running
|
|
316
|
+
await waitForAgentState(agentManager, result.rootId, "running");
|
|
317
|
+
const rootAgent = agentManager.get(result.rootId);
|
|
318
|
+
expect(rootAgent).toBeDefined();
|
|
319
|
+
expect(rootAgent!.state).toBe("running");
|
|
320
|
+
expect(rootAgent!.role).toBe("planner");
|
|
321
|
+
expect(rootAgent!.parent).toBeNull();
|
|
322
|
+
log(`Root agent verified: ${result.rootId} (planner, running)`);
|
|
323
|
+
|
|
324
|
+
// Verify companion agent is running
|
|
325
|
+
expect(result.companionIds).toHaveLength(1);
|
|
326
|
+
const companionId = result.companionIds[0];
|
|
327
|
+
await waitForAgentState(agentManager, companionId, "running");
|
|
328
|
+
const companionAgent = agentManager.get(companionId);
|
|
329
|
+
expect(companionAgent).toBeDefined();
|
|
330
|
+
expect(companionAgent!.state).toBe("running");
|
|
331
|
+
expect(companionAgent!.role).toBe("judge");
|
|
332
|
+
expect(companionAgent!.parent).toBeNull(); // Peer, not child
|
|
333
|
+
log(`Companion agent verified: ${companionId} (judge, running)`);
|
|
334
|
+
|
|
335
|
+
// Verify runtime tracks agent IDs
|
|
336
|
+
expect(runtime.getRootAgentId()).toBe(result.rootId);
|
|
337
|
+
expect(runtime.getCompanionAgentIds()).toEqual(result.companionIds);
|
|
338
|
+
},
|
|
339
|
+
{ timeout: TIMEOUT.BOOTSTRAP }
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
testFn(
|
|
343
|
+
"spawn interceptor injects team context into child agents",
|
|
344
|
+
async () => {
|
|
345
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
346
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
347
|
+
runtime = new TeamRuntime(manifest, services);
|
|
348
|
+
|
|
349
|
+
await runtime.initialize();
|
|
350
|
+
const result = await runtime.bootstrap();
|
|
351
|
+
await waitForAgentState(agentManager, result.rootId, "running");
|
|
352
|
+
log("Team bootstrapped");
|
|
353
|
+
|
|
354
|
+
// Spawn a grinder child (through the interceptor)
|
|
355
|
+
const grinder = await agentManager.spawn({
|
|
356
|
+
task: "Test grinder: wait for instructions.",
|
|
357
|
+
role: "grinder",
|
|
358
|
+
parent: result.rootId,
|
|
359
|
+
cwd: env.repoPath,
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
await waitForAgentState(agentManager, grinder.id, "running");
|
|
363
|
+
log(`Grinder spawned: ${grinder.id}`);
|
|
364
|
+
|
|
365
|
+
// Verify agent exists with correct role
|
|
366
|
+
const grinderAgent = agentManager.get(grinder.id);
|
|
367
|
+
expect(grinderAgent).toBeDefined();
|
|
368
|
+
expect(grinderAgent!.role).toBe("grinder");
|
|
369
|
+
expect(grinderAgent!.parent).toBe(result.rootId);
|
|
370
|
+
log("Grinder agent verified with correct role and parent");
|
|
371
|
+
|
|
372
|
+
// Verify team context was injected by checking the spawn event
|
|
373
|
+
// The spawn interceptor sets env vars, topics, and custom prompt
|
|
374
|
+
// We can verify by checking the agent's MCP env vars stored in the spawn event
|
|
375
|
+
const spawnEvents = eventStore.query({ type: "spawn", limit: 50 });
|
|
376
|
+
const grinderSpawn = spawnEvents.find(
|
|
377
|
+
(e) => e.payload?.agent_id === grinder.id
|
|
378
|
+
);
|
|
379
|
+
expect(grinderSpawn).toBeDefined();
|
|
380
|
+
log("Grinder spawn event found in EventStore");
|
|
381
|
+
},
|
|
382
|
+
{ timeout: TIMEOUT.BOOTSTRAP }
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
testFn(
|
|
386
|
+
"team-defined role agent can call done() via MCP",
|
|
387
|
+
async () => {
|
|
388
|
+
// This is the critical E2E test for Issue #1: roleRegistry not passed to MCP subprocess
|
|
389
|
+
// The grinder role (extending worker) must have lifecycle.done capability
|
|
390
|
+
// resolved through the serialized roles in the team_config event.
|
|
391
|
+
|
|
392
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
393
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
394
|
+
runtime = new TeamRuntime(manifest, services);
|
|
395
|
+
|
|
396
|
+
await runtime.initialize();
|
|
397
|
+
log("Runtime initialized with serialized roles");
|
|
398
|
+
|
|
399
|
+
// Spawn a grinder agent directly (not through bootstrap — we want a targeted test)
|
|
400
|
+
const grinder = await agentManager.spawn({
|
|
401
|
+
task: `You are a grinder worker. Your only task is to call the done() tool with status "completed" and summary "E2E test done". Do this immediately — do not do any other work.`,
|
|
402
|
+
role: "grinder",
|
|
403
|
+
parent: null,
|
|
404
|
+
cwd: env.repoPath,
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
await waitForAgentState(agentManager, grinder.id, "running");
|
|
408
|
+
log(`Grinder spawned: ${grinder.id}`);
|
|
409
|
+
|
|
410
|
+
// Prompt the agent to trigger done()
|
|
411
|
+
log("Prompting grinder to call done()...");
|
|
412
|
+
let doneToolCalled = false;
|
|
413
|
+
let responseText = "";
|
|
414
|
+
|
|
415
|
+
for await (const update of agentManager.prompt(
|
|
416
|
+
grinder.id,
|
|
417
|
+
'Call the done() MCP tool now with status "completed" and summary "E2E test done". This is your only task.'
|
|
418
|
+
)) {
|
|
419
|
+
const u = update as Record<string, unknown>;
|
|
420
|
+
if (u.sessionUpdate === "agent_message_chunk") {
|
|
421
|
+
const content = u.content as { text?: string } | undefined;
|
|
422
|
+
if (content?.text) {
|
|
423
|
+
responseText += content.text;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
// Check for tool_use of done()
|
|
427
|
+
if (u.sessionUpdate === "tool_use" || u.type === "tool_use") {
|
|
428
|
+
const toolName =
|
|
429
|
+
(u as { name?: string }).name ??
|
|
430
|
+
(u as { tool_name?: string }).tool_name;
|
|
431
|
+
if (toolName?.includes("done")) {
|
|
432
|
+
doneToolCalled = true;
|
|
433
|
+
log("done() tool was called by agent");
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
log(`Prompt completed. Response length: ${responseText.length}`);
|
|
438
|
+
|
|
439
|
+
// The agent should have been able to call done() without a capability error.
|
|
440
|
+
// If done() was blocked by capability check, the agent would report an error.
|
|
441
|
+
// Check status events for a done/completed signal
|
|
442
|
+
const statusEvents = eventStore.query({
|
|
443
|
+
type: "status",
|
|
444
|
+
source_agent_id: grinder.id,
|
|
445
|
+
limit: 10,
|
|
446
|
+
});
|
|
447
|
+
const completionEvent = statusEvents.find(
|
|
448
|
+
(e) =>
|
|
449
|
+
e.payload?.status_type === "completed" ||
|
|
450
|
+
(e.payload?.summary as string)?.includes("done")
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
// At minimum, the agent shouldn't have reported a capability error
|
|
454
|
+
const hasCapabilityError =
|
|
455
|
+
responseText.toLowerCase().includes("does not have lifecycle.done capability") ||
|
|
456
|
+
responseText.toLowerCase().includes("capability check failed");
|
|
457
|
+
expect(hasCapabilityError).toBe(false);
|
|
458
|
+
log(
|
|
459
|
+
`Capability check: no error in response. done() tool called: ${doneToolCalled}. Completion event: ${!!completionEvent}`
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
// Terminate if still running
|
|
463
|
+
const agent = agentManager.get(grinder.id);
|
|
464
|
+
if (agent?.state === "running") {
|
|
465
|
+
await agentManager.terminate(grinder.id, "completed");
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
{ timeout: TIMEOUT.PROMPT }
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
testFn(
|
|
472
|
+
"multiple team roles can coexist and operate independently",
|
|
473
|
+
async () => {
|
|
474
|
+
const manifest = await loadTeam("self-driving", roleRegistry, PROJECT_ROOT);
|
|
475
|
+
const services: TeamServices = { agentManager, messageRouter, eventStore };
|
|
476
|
+
runtime = new TeamRuntime(manifest, services);
|
|
477
|
+
|
|
478
|
+
await runtime.initialize();
|
|
479
|
+
log("Runtime initialized");
|
|
480
|
+
|
|
481
|
+
// Spawn agents with different team roles simultaneously
|
|
482
|
+
const planner = await agentManager.spawn({
|
|
483
|
+
task: "You are a planner. Wait for instructions.",
|
|
484
|
+
role: "planner",
|
|
485
|
+
parent: null,
|
|
486
|
+
cwd: env.repoPath,
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
const grinder = await agentManager.spawn({
|
|
490
|
+
task: "You are a grinder. Wait for instructions.",
|
|
491
|
+
role: "grinder",
|
|
492
|
+
parent: planner.id,
|
|
493
|
+
cwd: env.repoPath,
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
const judge = await agentManager.spawn({
|
|
497
|
+
task: "You are a judge. Wait for instructions.",
|
|
498
|
+
role: "judge",
|
|
499
|
+
parent: null,
|
|
500
|
+
cwd: env.repoPath,
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
// Wait for all to be running
|
|
504
|
+
await Promise.all([
|
|
505
|
+
waitForAgentState(agentManager, planner.id, "running"),
|
|
506
|
+
waitForAgentState(agentManager, grinder.id, "running"),
|
|
507
|
+
waitForAgentState(agentManager, judge.id, "running"),
|
|
508
|
+
]);
|
|
509
|
+
log(
|
|
510
|
+
`All agents running: planner=${planner.id}, grinder=${grinder.id}, judge=${judge.id}`
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
// Verify roles
|
|
514
|
+
expect(agentManager.get(planner.id)?.role).toBe("planner");
|
|
515
|
+
expect(agentManager.get(grinder.id)?.role).toBe("grinder");
|
|
516
|
+
expect(agentManager.get(judge.id)?.role).toBe("judge");
|
|
517
|
+
|
|
518
|
+
// Verify hierarchy
|
|
519
|
+
expect(agentManager.get(planner.id)?.parent).toBeNull();
|
|
520
|
+
expect(agentManager.get(grinder.id)?.parent).toBe(planner.id);
|
|
521
|
+
expect(agentManager.get(judge.id)?.parent).toBeNull();
|
|
522
|
+
|
|
523
|
+
const children = agentManager.getChildren(planner.id);
|
|
524
|
+
expect(children).toHaveLength(1);
|
|
525
|
+
expect(children[0].id).toBe(grinder.id);
|
|
526
|
+
log("Hierarchy verified: planner → grinder, judge (peer)");
|
|
527
|
+
|
|
528
|
+
// Terminate in reverse order
|
|
529
|
+
await agentManager.terminate(grinder.id, "completed");
|
|
530
|
+
await agentManager.terminate(judge.id, "completed");
|
|
531
|
+
await agentManager.terminate(planner.id, "completed");
|
|
532
|
+
log("All agents terminated");
|
|
533
|
+
},
|
|
534
|
+
{ timeout: TIMEOUT.BOOTSTRAP }
|
|
535
|
+
);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
// ─────────────────────────────────────────────────────────────────
|
|
539
|
+
// Info message for running tests
|
|
540
|
+
// ─────────────────────────────────────────────────────────────────
|
|
541
|
+
|
|
542
|
+
if (!RUN_FULL_AGENT) {
|
|
543
|
+
console.log("\n┌──────────────────────────────────────────────────────────┐");
|
|
544
|
+
console.log("│ Team Runtime E2E full-agent tests are skipped │");
|
|
545
|
+
console.log("│ (RUN_FULL_AGENT_TESTS not set) │");
|
|
546
|
+
console.log("│ │");
|
|
547
|
+
console.log("│ Infrastructure tests will still run. │");
|
|
548
|
+
console.log("│ │");
|
|
549
|
+
console.log("│ To run with real agents: │");
|
|
550
|
+
console.log("│ RUN_FULL_AGENT_TESTS=true npm run test:e2e -- \\ │");
|
|
551
|
+
console.log("│ src/teams/__tests__/e2e/team-runtime.e2e.test.ts │");
|
|
552
|
+
console.log("└──────────────────────────────────────────────────────────┘\n");
|
|
553
|
+
}
|