macro-agent 0.1.0 → 0.1.1
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/specs.jsonl +4 -0
- package/CLAUDE.md +16 -14
- 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 +464 -183
- package/dist/agent/agent-manager.js.map +1 -1
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/api/server.d.ts +3 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +37 -6
- package/dist/api/server.js.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 +127 -61
- package/dist/cli/acp.js.map +1 -1
- package/dist/cli/index.js +147 -15
- 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 +268 -181
- 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 +74 -7
- package/dist/config/project-config.d.ts.map +1 -1
- package/dist/config/project-config.js +123 -20
- package/dist/config/project-config.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 +10 -1
- package/dist/map/adapter/extensions/index.d.ts.map +1 -1
- package/dist/map/adapter/extensions/index.js +34 -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/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 +8 -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 +2 -0
- 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 +14 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +113 -85
- package/dist/mcp/mcp-server.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/capabilities.d.ts +3 -1
- package/dist/roles/capabilities.d.ts.map +1 -1
- package/dist/roles/capabilities.js +17 -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 +6 -6
- 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/server/combined-server.d.ts +20 -0
- package/dist/server/combined-server.d.ts.map +1 -1
- package/dist/server/combined-server.js +107 -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 +69 -20
- package/dist/store/event-store.js.map +1 -1
- package/dist/store/types/agents.d.ts +18 -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/team-loader.d.ts +2 -2
- package/dist/teams/team-loader.js +3 -3
- package/dist/teams/team-loader.js.map +1 -1
- package/dist/teams/team-runtime.d.ts.map +1 -1
- package/dist/teams/team-runtime.js +2 -0
- package/dist/teams/team-runtime.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 +3 -3
- package/docs/troubleshooting.md +10 -11
- package/package.json +6 -4
- 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 +714 -261
- package/src/agent/types.ts +3 -1
- package/src/api/server.ts +41 -7
- 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 +130 -72
- package/src/cli/index.ts +120 -14
- package/src/cli/mcp.ts +311 -207
- package/src/cli/parse-args.ts +54 -0
- package/src/cli/stable-instance-id.ts +14 -0
- package/src/config/project-config.ts +190 -27
- package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
- 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__/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 +60 -0
- package/src/map/adapter/extensions/mcp-bridge.ts +995 -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 +28 -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 +2 -0
- 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 +191 -100
- 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/capabilities.ts +17 -7
- package/src/roles/config-loader.ts +6 -6
- package/src/roles/registry.ts +2 -2
- package/src/server/__tests__/combined-server.test.ts +94 -21
- package/src/server/combined-server.ts +189 -33
- package/src/steering/__tests__/steering-integration.test.ts +1 -1
- 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 +80 -21
- package/src/store/types/agents.ts +15 -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__/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 +253 -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/__tests__/cross-subsystem.integration.test.ts +1 -1
- package/src/teams/team-loader.ts +3 -3
- package/src/teams/team-runtime.ts +2 -0
- 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
package/src/cli/mcp.ts
CHANGED
|
@@ -4,25 +4,17 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Runs the MCP server as a subprocess that agents can connect to.
|
|
6
6
|
* Agent context is passed via environment variables.
|
|
7
|
+
*
|
|
8
|
+
* Two modes:
|
|
9
|
+
* - **Thin-client mode** (MACRO_SERVER_URL set): Tools forward to the main server
|
|
10
|
+
* via ephemeral MAP WebSocket connections. No local services needed.
|
|
11
|
+
* - **Legacy mode** (MACRO_INSTANCE_ID set): Creates a full local service stack
|
|
12
|
+
* with shared SQLite. Used as fallback for backward compatibility.
|
|
7
13
|
*/
|
|
8
14
|
|
|
9
15
|
import * as fs from "fs";
|
|
10
16
|
import * as path from "path";
|
|
11
17
|
import * as os from "os";
|
|
12
|
-
import { createEventStore } from "../store/event-store.js";
|
|
13
|
-
import { createAgentManager } from "../agent/agent-manager.js";
|
|
14
|
-
import { createTaskManager } from "../task/task-manager.js";
|
|
15
|
-
import { createMessageRouter } from "../router/message-router.js";
|
|
16
|
-
import { createMCPServer } from "../mcp/mcp-server.js";
|
|
17
|
-
import {
|
|
18
|
-
createActivityWatcher,
|
|
19
|
-
subscribeAgentToEvents,
|
|
20
|
-
MONITOR_DEFAULT_EVENT_TYPES,
|
|
21
|
-
} from "../activity/index.js";
|
|
22
|
-
import {
|
|
23
|
-
createWakeHandler,
|
|
24
|
-
createSessionProviderFromAgentManager,
|
|
25
|
-
} from "../agent/wake.js";
|
|
26
18
|
|
|
27
19
|
// Debug logging to file (since stderr doesn't show up from MCP subprocess)
|
|
28
20
|
const debugLogPath = path.join(os.tmpdir(), "macro-agent-mcp-debug.log");
|
|
@@ -33,231 +25,343 @@ function debugLog(message: string) {
|
|
|
33
25
|
console.error(message); // Also log to stderr in case it's visible
|
|
34
26
|
}
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Thin-Client Mode (MACRO_SERVER_URL)
|
|
30
|
+
// =============================================================================
|
|
31
|
+
|
|
32
|
+
async function startThinClient() {
|
|
33
|
+
const agentId = process.env.MACRO_AGENT_ID!;
|
|
40
34
|
const taskId = process.env.MACRO_TASK_ID;
|
|
41
35
|
const agentCwd = process.env.MACRO_AGENT_CWD || process.cwd();
|
|
42
|
-
const
|
|
43
|
-
const
|
|
36
|
+
const serverUrl = process.env.MACRO_SERVER_URL!;
|
|
37
|
+
const lineageStr = process.env.MACRO_AGENT_LINEAGE || "[]";
|
|
38
|
+
const sessionId = process.env.MACRO_SESSION_ID || "";
|
|
39
|
+
const serverToken = process.env.MACRO_SERVER_TOKEN || "";
|
|
40
|
+
const agentToken = process.env.MACRO_AGENT_TOKEN || "";
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
let lineage: string[];
|
|
43
|
+
try {
|
|
44
|
+
lineage = JSON.parse(lineageStr);
|
|
45
|
+
} catch {
|
|
46
|
+
lineage = [];
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
49
|
+
debugLog(`[MCP] Thin-client mode: agent=${agentId}, server=${serverUrl}`);
|
|
50
|
+
|
|
51
|
+
const { createMCPServerThinClient } = await import("../mcp/mcp-server.js");
|
|
52
|
+
const { mapCall } = await import("../mcp/map-client.js");
|
|
53
|
+
|
|
54
|
+
const context = {
|
|
55
|
+
agent_id: agentId,
|
|
56
|
+
session_id: sessionId,
|
|
57
|
+
task_id: taskId ?? undefined,
|
|
58
|
+
lineage,
|
|
59
|
+
cwd: agentCwd,
|
|
60
|
+
agent_token: agentToken || undefined,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Also pass permission mode for spawn_agent forwarding
|
|
64
|
+
const permissionMode = process.env.MACRO_PERMISSION_MODE;
|
|
65
|
+
|
|
66
|
+
// Build mapCall options with server token for WebSocket auth
|
|
67
|
+
const callOptions = serverToken ? { serverToken } : undefined;
|
|
68
|
+
|
|
69
|
+
const mcpServer = createMCPServerThinClient(
|
|
70
|
+
context,
|
|
71
|
+
async (method, params, options) => {
|
|
72
|
+
// Merge auth options with per-call options
|
|
73
|
+
const mergedOptions = { ...callOptions, ...options };
|
|
74
|
+
// Inject permission_mode into spawn_agent calls
|
|
75
|
+
if (method === "_macro/mcp/spawn_agent" && permissionMode) {
|
|
76
|
+
const p = (params ?? {}) as Record<string, unknown>;
|
|
77
|
+
p.permission_mode = permissionMode;
|
|
78
|
+
return mapCall(serverUrl, method, p, mergedOptions);
|
|
79
|
+
}
|
|
80
|
+
return mapCall(serverUrl, method, params, mergedOptions);
|
|
81
|
+
}
|
|
82
|
+
);
|
|
54
83
|
|
|
55
|
-
|
|
84
|
+
await mcpServer.start();
|
|
85
|
+
|
|
86
|
+
// Handle graceful shutdown
|
|
87
|
+
const shutdown = async () => {
|
|
88
|
+
await mcpServer.close();
|
|
89
|
+
process.exit(0);
|
|
90
|
+
};
|
|
91
|
+
process.on("SIGINT", shutdown);
|
|
92
|
+
process.on("SIGTERM", shutdown);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// Legacy Mode (MACRO_INSTANCE_ID)
|
|
97
|
+
// =============================================================================
|
|
98
|
+
|
|
99
|
+
async function startLegacy() {
|
|
100
|
+
const agentId = process.env.MACRO_AGENT_ID!;
|
|
101
|
+
const taskId = process.env.MACRO_TASK_ID;
|
|
102
|
+
const agentCwd = process.env.MACRO_AGENT_CWD || process.cwd();
|
|
103
|
+
const instanceId = process.env.MACRO_INSTANCE_ID!;
|
|
104
|
+
const baseDir = process.env.MACRO_BASE_DIR;
|
|
105
|
+
|
|
106
|
+
debugLog(`[MCP] Legacy mode: agent=${agentId}, instanceId=${instanceId}`);
|
|
56
107
|
debugLog(`[MCP] Debug log file: ${debugLogPath}`);
|
|
57
108
|
|
|
109
|
+
const { createEventStore } = await import("../store/event-store.js");
|
|
110
|
+
const { createAgentManager } = await import("../agent/agent-manager.js");
|
|
111
|
+
const { createTaskManager } = await import("../task/task-manager.js");
|
|
112
|
+
const { createMessageRouter } = await import("../router/message-router.js");
|
|
113
|
+
const { createMCPServer } = await import("../mcp/mcp-server.js");
|
|
114
|
+
const { createTaskBackend, loadTaskConfigFromEnv } = await import("../task/backend/index.js");
|
|
115
|
+
const { UnifiedTaskToolProvider } = await import("../task/backend/unified-tool-provider.js");
|
|
116
|
+
const {
|
|
117
|
+
createActivityWatcher,
|
|
118
|
+
subscribeAgentToEvents,
|
|
119
|
+
MONITOR_DEFAULT_EVENT_TYPES,
|
|
120
|
+
} = await import("../activity/index.js");
|
|
121
|
+
const {
|
|
122
|
+
createWakeHandler,
|
|
123
|
+
createSessionProviderFromAgentManager,
|
|
124
|
+
} = await import("../agent/wake.js");
|
|
125
|
+
|
|
126
|
+
// Initialize services with shared file-based storage
|
|
127
|
+
const eventStore = await createEventStore({ inMemory: false, instanceId, baseDir });
|
|
128
|
+
debugLog(`[MCP] EventStore created, path: ${eventStore.instancePath}`);
|
|
129
|
+
const messageRouter = createMessageRouter(eventStore);
|
|
130
|
+
const agentManager = createAgentManager(eventStore, messageRouter);
|
|
131
|
+
const taskManager = createTaskManager(eventStore);
|
|
132
|
+
|
|
133
|
+
// Create task backend from env config
|
|
134
|
+
const taskConfig = loadTaskConfigFromEnv();
|
|
135
|
+
let taskBackend: import("../task/backend/types.js").TaskBackend | undefined;
|
|
136
|
+
let taskToolProvider: InstanceType<typeof UnifiedTaskToolProvider> | undefined;
|
|
137
|
+
let openTasksClient: import("../task/backend/opentasks/client.js").OpenTasksClient | undefined;
|
|
138
|
+
|
|
58
139
|
try {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
debugLog(`[MCP] Initial check: agent found = ${!!agent}, total agents in store = ${allAgentsInitial.length}`);
|
|
73
|
-
if (allAgentsInitial.length > 0) {
|
|
74
|
-
debugLog(`[MCP] Agents in store: ${allAgentsInitial.map(a => a.id).join(', ')}`);
|
|
75
|
-
}
|
|
140
|
+
const result = await createTaskBackend(taskConfig, eventStore);
|
|
141
|
+
taskBackend = result.backend;
|
|
142
|
+
openTasksClient = result.openTasksClient;
|
|
143
|
+
|
|
144
|
+
taskToolProvider = new UnifiedTaskToolProvider(
|
|
145
|
+
taskBackend,
|
|
146
|
+
() => ({ agent_id: agentId! }),
|
|
147
|
+
openTasksClient
|
|
148
|
+
);
|
|
149
|
+
debugLog(`[MCP] Task backend created: ${taskConfig.backend.type}`);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
debugLog(`[MCP] Failed to create task backend: ${err}. Falling back to legacy TaskManager only.`);
|
|
152
|
+
}
|
|
76
153
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
154
|
+
// Get agent lineage for authorization checks
|
|
155
|
+
let agent = eventStore.getAgent(agentId);
|
|
156
|
+
const allAgentsInitial = eventStore.listAgents();
|
|
157
|
+
debugLog(`[MCP] Initial check: agent found = ${!!agent}, total agents in store = ${allAgentsInitial.length}`);
|
|
158
|
+
if (allAgentsInitial.length > 0) {
|
|
159
|
+
debugLog(`[MCP] Agents in store: ${allAgentsInitial.map(a => a.id).join(', ')}`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!agent) {
|
|
163
|
+
for (let i = 0; i < 10; i++) {
|
|
164
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
165
|
+
await eventStore.reload();
|
|
166
|
+
agent = eventStore.getAgent(agentId);
|
|
167
|
+
const allAgentsRetry = eventStore.listAgents();
|
|
168
|
+
debugLog(`[MCP] Retry ${i + 1}: agent found = ${!!agent}, total agents = ${allAgentsRetry.length}`);
|
|
169
|
+
if (agent) {
|
|
170
|
+
debugLog(`[MCP] Found agent ${agentId} after ${i + 1} retries`);
|
|
171
|
+
break;
|
|
91
172
|
}
|
|
92
|
-
} else {
|
|
93
|
-
debugLog(`[MCP] Agent ${agentId} found immediately (no retry needed)`);
|
|
94
173
|
}
|
|
174
|
+
} else {
|
|
175
|
+
debugLog(`[MCP] Agent ${agentId} found immediately (no retry needed)`);
|
|
176
|
+
}
|
|
95
177
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
178
|
+
if (!agent) {
|
|
179
|
+
debugLog(`[MCP] Warning: Agent ${agentId} not found in store after retries. ` +
|
|
180
|
+
`Continuing with limited context. This may affect authorization checks.`);
|
|
181
|
+
const events = eventStore.query({ limit: 50 });
|
|
182
|
+
debugLog(`[MCP] Events in store (${events.length}): ${events.map(e => `${e.type}:${e.payload?.agent_id || e.source?.agent_id}`).join(', ')}`);
|
|
183
|
+
}
|
|
103
184
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Create ActivityWatcher for wait_for_activity MCP tool
|
|
107
|
-
const sessionProvider = createSessionProviderFromAgentManager(agentManager);
|
|
108
|
-
const wakeHandler = createWakeHandler(sessionProvider, agentManager);
|
|
109
|
-
const activityWatcher = createActivityWatcher(
|
|
110
|
-
{
|
|
111
|
-
listAgents: () => agentManager.list(),
|
|
112
|
-
getAgent: (id) => agentManager.get(id),
|
|
113
|
-
},
|
|
114
|
-
wakeHandler
|
|
115
|
-
);
|
|
185
|
+
const lineage = agent?.lineage ?? [];
|
|
116
186
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
timestamp: Date.now(),
|
|
133
|
-
details: { state: changedAgent.state },
|
|
134
|
-
});
|
|
135
|
-
});
|
|
187
|
+
// Create ActivityWatcher for wait_for_activity MCP tool
|
|
188
|
+
const sessionProvider = createSessionProviderFromAgentManager(agentManager);
|
|
189
|
+
const wakeHandler = createWakeHandler(sessionProvider, agentManager);
|
|
190
|
+
const activityWatcher = createActivityWatcher(
|
|
191
|
+
{
|
|
192
|
+
listAgents: () => agentManager.list(),
|
|
193
|
+
getAgent: (id) => agentManager.get(id),
|
|
194
|
+
},
|
|
195
|
+
wakeHandler
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
// Wire EventStore events to ActivityWatcher
|
|
199
|
+
eventStore.onAgentChange((changedAgentId, changedAgent) => {
|
|
200
|
+
if (!activityWatcher.isRunning()) return;
|
|
201
|
+
if (!changedAgent) return;
|
|
136
202
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
activityWatcher.processActivity({
|
|
150
|
-
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
151
|
-
type: eventType,
|
|
152
|
-
source: { agent_id: task.assigned_agent ?? undefined, task_id: changedTaskId },
|
|
153
|
-
timestamp: Date.now(),
|
|
154
|
-
details: { status: task.status },
|
|
155
|
-
});
|
|
203
|
+
const eventType = changedAgent.state === "spawning" ? "agent_spawned"
|
|
204
|
+
: changedAgent.state === "running" ? "agent_started"
|
|
205
|
+
: changedAgent.state === "stopped" ? "agent_terminated"
|
|
206
|
+
: "agent_updated";
|
|
207
|
+
|
|
208
|
+
activityWatcher.processActivity({
|
|
209
|
+
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
210
|
+
type: eventType,
|
|
211
|
+
source: { agent_id: changedAgentId, role: changedAgent.role },
|
|
212
|
+
timestamp: Date.now(),
|
|
213
|
+
details: { state: changedAgent.state },
|
|
156
214
|
});
|
|
215
|
+
});
|
|
157
216
|
|
|
158
|
-
|
|
159
|
-
activityWatcher.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
}
|
|
217
|
+
eventStore.onTaskChange((changedTaskId, task) => {
|
|
218
|
+
if (!activityWatcher.isRunning()) return;
|
|
219
|
+
if (!task) return;
|
|
220
|
+
|
|
221
|
+
const eventType = task.status === "pending" ? "task_created"
|
|
222
|
+
: task.status === "assigned" ? "task_assigned"
|
|
223
|
+
: task.status === "in_progress" ? "task_started"
|
|
224
|
+
: task.status === "completed" ? "task_completed"
|
|
225
|
+
: task.status === "failed" ? "task_failed"
|
|
226
|
+
: "task_updated";
|
|
227
|
+
|
|
228
|
+
activityWatcher.processActivity({
|
|
229
|
+
id: `evt-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
230
|
+
type: eventType,
|
|
231
|
+
source: { agent_id: task.assigned_agent ?? undefined, task_id: changedTaskId },
|
|
232
|
+
timestamp: Date.now(),
|
|
233
|
+
details: { status: task.status },
|
|
177
234
|
});
|
|
235
|
+
});
|
|
178
236
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
237
|
+
activityWatcher.start();
|
|
238
|
+
|
|
239
|
+
// Auto-subscribe Monitor agents to health events when they spawn
|
|
240
|
+
agentManager.onLifecycleEvent((event) => {
|
|
241
|
+
if (event.type === "spawned") {
|
|
242
|
+
const spawnedAgent = event.agent;
|
|
243
|
+
if (spawnedAgent.role === "monitor" || spawnedAgent.role?.startsWith("monitor.")) {
|
|
244
|
+
subscribeAgentToEvents(
|
|
245
|
+
activityWatcher,
|
|
246
|
+
spawnedAgent.id,
|
|
247
|
+
MONITOR_DEFAULT_EVENT_TYPES,
|
|
248
|
+
undefined,
|
|
249
|
+
"high"
|
|
250
|
+
);
|
|
251
|
+
debugLog(`[MCP] Auto-subscribed Monitor ${spawnedAgent.id} to health events`);
|
|
252
|
+
}
|
|
189
253
|
}
|
|
254
|
+
});
|
|
190
255
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
256
|
+
// Read team config from EventStore
|
|
257
|
+
let teamTaskMode: string | undefined;
|
|
258
|
+
const teamEvents = eventStore.query({ type: "status", limit: 50 });
|
|
259
|
+
const teamConfigEvent = teamEvents.find(
|
|
260
|
+
(e) => e.payload?.team_config != null
|
|
261
|
+
);
|
|
262
|
+
if (teamConfigEvent?.payload?.team_config) {
|
|
263
|
+
const tc = teamConfigEvent.payload.team_config as Record<string, unknown>;
|
|
264
|
+
teamTaskMode = tc.taskMode as string | undefined;
|
|
265
|
+
debugLog(`[MCP] Found team config: team=${tc.teamName}, strategy=${tc.strategy}, taskMode=${tc.taskMode}`);
|
|
266
|
+
}
|
|
194
267
|
|
|
195
|
-
|
|
196
|
-
|
|
268
|
+
// Register team roles in local RoleRegistry
|
|
269
|
+
const roleRegistry = agentManager.getRoleRegistry();
|
|
270
|
+
let integrationStrategy: import("../workspace/strategies/types.js").IntegrationStrategy | undefined;
|
|
197
271
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (roles) {
|
|
201
|
-
for (const roleDef of Object.values(roles)) {
|
|
202
|
-
roleRegistry.registerRole(roleDef as import("../roles/types.js").RoleDefinition);
|
|
203
|
-
}
|
|
204
|
-
debugLog(`[MCP] Registered ${Object.keys(roles).length} team roles in RoleRegistry`);
|
|
205
|
-
}
|
|
272
|
+
if (teamConfigEvent?.payload?.team_config) {
|
|
273
|
+
const tc = teamConfigEvent.payload.team_config as Record<string, unknown>;
|
|
206
274
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
|
|
212
|
-
integrationStrategy = defaultStrategyRegistry.get(
|
|
213
|
-
strategyName,
|
|
214
|
-
tc.strategyConfig as Record<string, unknown> | undefined
|
|
215
|
-
);
|
|
216
|
-
debugLog(`[MCP] Instantiated '${strategyName}' integration strategy`);
|
|
217
|
-
} catch (err) {
|
|
218
|
-
debugLog(`[MCP] Failed to instantiate strategy '${strategyName}': ${err}`);
|
|
219
|
-
}
|
|
275
|
+
const roles = tc.roles as Record<string, { name: string; capabilities: string[] }> | undefined;
|
|
276
|
+
if (roles) {
|
|
277
|
+
for (const roleDef of Object.values(roles)) {
|
|
278
|
+
roleRegistry.registerRole(roleDef as import("../roles/types.js").RoleDefinition);
|
|
220
279
|
}
|
|
280
|
+
debugLog(`[MCP] Registered ${Object.keys(roles).length} team roles in RoleRegistry`);
|
|
221
281
|
}
|
|
222
282
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{
|
|
233
|
-
|
|
234
|
-
agentManager,
|
|
235
|
-
taskManager,
|
|
236
|
-
messageRouter,
|
|
237
|
-
activityWatcher,
|
|
238
|
-
taskMode: teamTaskMode as "push" | "pull" | undefined,
|
|
239
|
-
roleRegistry,
|
|
240
|
-
integrationStrategy,
|
|
283
|
+
const strategyName = tc.strategy as string | undefined;
|
|
284
|
+
if (strategyName) {
|
|
285
|
+
try {
|
|
286
|
+
const { defaultStrategyRegistry } = await import("../workspace/strategies/registry.js");
|
|
287
|
+
integrationStrategy = defaultStrategyRegistry.get(
|
|
288
|
+
strategyName,
|
|
289
|
+
tc.strategyConfig as Record<string, unknown> | undefined
|
|
290
|
+
);
|
|
291
|
+
debugLog(`[MCP] Instantiated '${strategyName}' integration strategy`);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
debugLog(`[MCP] Failed to instantiate strategy '${strategyName}': ${err}`);
|
|
241
294
|
}
|
|
242
|
-
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const mcpServer = createMCPServer(
|
|
299
|
+
{
|
|
300
|
+
agent_id: agentId,
|
|
301
|
+
session_id: agent?.session_id ?? "",
|
|
302
|
+
task_id: taskId ?? undefined,
|
|
303
|
+
lineage,
|
|
304
|
+
cwd: agentCwd,
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
eventStore,
|
|
308
|
+
agentManager,
|
|
309
|
+
taskManager,
|
|
310
|
+
messageRouter,
|
|
311
|
+
activityWatcher,
|
|
312
|
+
taskMode: teamTaskMode as "push" | "pull" | undefined,
|
|
313
|
+
roleRegistry,
|
|
314
|
+
integrationStrategy,
|
|
315
|
+
taskBackend,
|
|
316
|
+
taskToolProvider,
|
|
317
|
+
}
|
|
318
|
+
);
|
|
243
319
|
|
|
244
|
-
|
|
245
|
-
await mcpServer.start();
|
|
320
|
+
await mcpServer.start();
|
|
246
321
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
322
|
+
// Handle graceful shutdown
|
|
323
|
+
process.on("SIGINT", async () => {
|
|
324
|
+
activityWatcher.stop();
|
|
325
|
+
try { openTasksClient?.disconnect(); } catch { /* ignore */ }
|
|
326
|
+
await mcpServer.close();
|
|
327
|
+
await eventStore.close();
|
|
328
|
+
process.exit(0);
|
|
329
|
+
});
|
|
254
330
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
331
|
+
process.on("SIGTERM", async () => {
|
|
332
|
+
activityWatcher.stop();
|
|
333
|
+
try { openTasksClient?.disconnect(); } catch { /* ignore */ }
|
|
334
|
+
await mcpServer.close();
|
|
335
|
+
await eventStore.close();
|
|
336
|
+
process.exit(0);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// =============================================================================
|
|
341
|
+
// Main
|
|
342
|
+
// =============================================================================
|
|
343
|
+
|
|
344
|
+
async function main() {
|
|
345
|
+
const agentId = process.env.MACRO_AGENT_ID;
|
|
346
|
+
const serverUrl = process.env.MACRO_SERVER_URL;
|
|
347
|
+
const instanceId = process.env.MACRO_INSTANCE_ID;
|
|
348
|
+
|
|
349
|
+
if (!agentId) {
|
|
350
|
+
console.error("Error: MACRO_AGENT_ID environment variable is required");
|
|
351
|
+
process.exit(1);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
try {
|
|
355
|
+
if (serverUrl) {
|
|
356
|
+
// Thin-client mode: forward tool calls to main server via MAP WebSocket
|
|
357
|
+
await startThinClient();
|
|
358
|
+
} else if (instanceId) {
|
|
359
|
+
// Legacy mode: create full local service stack with shared SQLite
|
|
360
|
+
await startLegacy();
|
|
361
|
+
} else {
|
|
362
|
+
console.error("Error: Either MACRO_SERVER_URL or MACRO_INSTANCE_ID environment variable is required");
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
261
365
|
} catch (error) {
|
|
262
366
|
console.error(`Failed to start MCP server: ${error}`);
|
|
263
367
|
process.exit(1);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
export interface ACPServerOptions {
|
|
6
|
+
/** Working directory for agents */
|
|
7
|
+
cwd?: string;
|
|
8
|
+
/** Stdio ACP-only mode (for embedded use with acp-factory) */
|
|
9
|
+
acp?: boolean;
|
|
10
|
+
/** Port for server (default: 3001) */
|
|
11
|
+
port?: number;
|
|
12
|
+
/** Host for server (default: localhost) */
|
|
13
|
+
host?: string;
|
|
14
|
+
/** Instance ID to reuse an existing event store (omit for new instance) */
|
|
15
|
+
instanceId?: string;
|
|
16
|
+
/** Disable authentication (for local development/testing) */
|
|
17
|
+
noAuth?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Parse command line arguments.
|
|
22
|
+
* @param argv Optional array of arguments (defaults to process.argv.slice(2))
|
|
23
|
+
*/
|
|
24
|
+
export function parseArgs(argv?: string[]): ACPServerOptions {
|
|
25
|
+
const args = argv ?? process.argv.slice(2);
|
|
26
|
+
const options: ACPServerOptions = {};
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < args.length; i++) {
|
|
29
|
+
if (args[i] === "--version" || args[i] === "-v") {
|
|
30
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
31
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "../../package.json"), "utf-8"));
|
|
32
|
+
console.log(pkg.version);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
} else if (args[i] === "--cwd" && args[i + 1]) {
|
|
35
|
+
options.cwd = args[i + 1];
|
|
36
|
+
i++;
|
|
37
|
+
} else if (args[i] === "--acp") {
|
|
38
|
+
options.acp = true;
|
|
39
|
+
} else if (args[i] === "--port" && args[i + 1]) {
|
|
40
|
+
options.port = parseInt(args[i + 1], 10);
|
|
41
|
+
i++;
|
|
42
|
+
} else if (args[i] === "--host" && args[i + 1]) {
|
|
43
|
+
options.host = args[i + 1];
|
|
44
|
+
i++;
|
|
45
|
+
} else if (args[i] === "--instance-id" && args[i + 1]) {
|
|
46
|
+
options.instanceId = args[i + 1];
|
|
47
|
+
i++;
|
|
48
|
+
} else if (args[i] === "--no-auth") {
|
|
49
|
+
options.noAuth = true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return options;
|
|
54
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate a stable, deterministic instance ID from a directory path.
|
|
6
|
+
*
|
|
7
|
+
* This ensures the same project always uses the same EventStore,
|
|
8
|
+
* so agents and sessions persist across server restarts.
|
|
9
|
+
*/
|
|
10
|
+
export function getStableInstanceId(cwd: string): string {
|
|
11
|
+
const normalizedPath = resolve(cwd);
|
|
12
|
+
const hash = createHash("sha256").update(normalizedPath).digest("hex").slice(0, 12);
|
|
13
|
+
return `inst_${hash}`;
|
|
14
|
+
}
|