macro-agent 0.0.17 → 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.
Files changed (338) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/.sudocode/specs.jsonl +4 -0
  3. package/CLAUDE.md +16 -14
  4. package/README.md +11 -29
  5. package/dist/acp/macro-agent.d.ts +17 -0
  6. package/dist/acp/macro-agent.d.ts.map +1 -1
  7. package/dist/acp/macro-agent.js +183 -55
  8. package/dist/acp/macro-agent.js.map +1 -1
  9. package/dist/acp/types.d.ts +32 -1
  10. package/dist/acp/types.d.ts.map +1 -1
  11. package/dist/acp/types.js.map +1 -1
  12. package/dist/agent/agent-manager.d.ts +65 -1
  13. package/dist/agent/agent-manager.d.ts.map +1 -1
  14. package/dist/agent/agent-manager.js +464 -183
  15. package/dist/agent/agent-manager.js.map +1 -1
  16. package/dist/agent/types.d.ts +1 -1
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/api/server.d.ts +3 -0
  19. package/dist/api/server.d.ts.map +1 -1
  20. package/dist/api/server.js +37 -6
  21. package/dist/api/server.js.map +1 -1
  22. package/dist/auth/index.d.ts +2 -0
  23. package/dist/auth/index.d.ts.map +1 -0
  24. package/dist/auth/index.js +2 -0
  25. package/dist/auth/index.js.map +1 -0
  26. package/dist/auth/token.d.ts +41 -0
  27. package/dist/auth/token.d.ts.map +1 -0
  28. package/dist/auth/token.js +73 -0
  29. package/dist/auth/token.js.map +1 -0
  30. package/dist/cli/acp.d.ts +2 -23
  31. package/dist/cli/acp.d.ts.map +1 -1
  32. package/dist/cli/acp.js +127 -61
  33. package/dist/cli/acp.js.map +1 -1
  34. package/dist/cli/index.js +147 -15
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/mcp.d.ts +6 -0
  37. package/dist/cli/mcp.d.ts.map +1 -1
  38. package/dist/cli/mcp.js +268 -181
  39. package/dist/cli/mcp.js.map +1 -1
  40. package/dist/cli/parse-args.d.ts +20 -0
  41. package/dist/cli/parse-args.d.ts.map +1 -0
  42. package/dist/cli/parse-args.js +43 -0
  43. package/dist/cli/parse-args.js.map +1 -0
  44. package/dist/cli/stable-instance-id.d.ts +8 -0
  45. package/dist/cli/stable-instance-id.d.ts.map +1 -0
  46. package/dist/cli/stable-instance-id.js +14 -0
  47. package/dist/cli/stable-instance-id.js.map +1 -0
  48. package/dist/config/project-config.d.ts +74 -7
  49. package/dist/config/project-config.d.ts.map +1 -1
  50. package/dist/config/project-config.js +123 -20
  51. package/dist/config/project-config.js.map +1 -1
  52. package/dist/map/adapter/acp-over-map.d.ts +23 -0
  53. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  54. package/dist/map/adapter/acp-over-map.js +482 -55
  55. package/dist/map/adapter/acp-over-map.js.map +1 -1
  56. package/dist/map/adapter/connection-manager.d.ts.map +1 -1
  57. package/dist/map/adapter/connection-manager.js +3 -0
  58. package/dist/map/adapter/connection-manager.js.map +1 -1
  59. package/dist/map/adapter/event-log.d.ts +87 -0
  60. package/dist/map/adapter/event-log.d.ts.map +1 -0
  61. package/dist/map/adapter/event-log.js +122 -0
  62. package/dist/map/adapter/event-log.js.map +1 -0
  63. package/dist/map/adapter/event-translator.js +6 -6
  64. package/dist/map/adapter/event-translator.js.map +1 -1
  65. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
  66. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
  67. package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
  68. package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
  69. package/dist/map/adapter/extensions/index.d.ts +10 -1
  70. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  71. package/dist/map/adapter/extensions/index.js +34 -0
  72. package/dist/map/adapter/extensions/index.js.map +1 -1
  73. package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
  74. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
  75. package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
  76. package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
  77. package/dist/map/adapter/extensions/rename.d.ts +29 -0
  78. package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
  79. package/dist/map/adapter/extensions/rename.js +49 -0
  80. package/dist/map/adapter/extensions/rename.js.map +1 -0
  81. package/dist/map/adapter/extensions/task.d.ts.map +1 -1
  82. package/dist/map/adapter/extensions/task.js +10 -0
  83. package/dist/map/adapter/extensions/task.js.map +1 -1
  84. package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
  85. package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
  86. package/dist/map/adapter/extensions/update-metadata.js +67 -0
  87. package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
  88. package/dist/map/adapter/index.d.ts +2 -1
  89. package/dist/map/adapter/index.d.ts.map +1 -1
  90. package/dist/map/adapter/index.js +8 -2
  91. package/dist/map/adapter/index.js.map +1 -1
  92. package/dist/map/adapter/interface.d.ts +2 -0
  93. package/dist/map/adapter/interface.d.ts.map +1 -1
  94. package/dist/map/adapter/map-adapter.d.ts +4 -0
  95. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  96. package/dist/map/adapter/map-adapter.js +302 -30
  97. package/dist/map/adapter/map-adapter.js.map +1 -1
  98. package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
  99. package/dist/map/adapter/subscription-manager.js +5 -1
  100. package/dist/map/adapter/subscription-manager.js.map +1 -1
  101. package/dist/map/adapter/types.d.ts +2 -0
  102. package/dist/map/adapter/types.d.ts.map +1 -1
  103. package/dist/mcp/map-client.d.ts +39 -0
  104. package/dist/mcp/map-client.d.ts.map +1 -0
  105. package/dist/mcp/map-client.js +129 -0
  106. package/dist/mcp/map-client.js.map +1 -0
  107. package/dist/mcp/mcp-server.d.ts +14 -0
  108. package/dist/mcp/mcp-server.d.ts.map +1 -1
  109. package/dist/mcp/mcp-server.js +113 -85
  110. package/dist/mcp/mcp-server.js.map +1 -1
  111. package/dist/mcp/types.d.ts +9 -1
  112. package/dist/mcp/types.d.ts.map +1 -1
  113. package/dist/mcp/types.js.map +1 -1
  114. package/dist/metrics/metrics.js +1 -1
  115. package/dist/metrics/metrics.js.map +1 -1
  116. package/dist/roles/capabilities.d.ts +3 -1
  117. package/dist/roles/capabilities.d.ts.map +1 -1
  118. package/dist/roles/capabilities.js +17 -7
  119. package/dist/roles/capabilities.js.map +1 -1
  120. package/dist/roles/config-loader.d.ts +6 -6
  121. package/dist/roles/config-loader.d.ts.map +1 -1
  122. package/dist/roles/config-loader.js +6 -6
  123. package/dist/roles/config-loader.js.map +1 -1
  124. package/dist/roles/registry.d.ts +2 -2
  125. package/dist/roles/registry.js +2 -2
  126. package/dist/server/combined-server.d.ts +20 -0
  127. package/dist/server/combined-server.d.ts.map +1 -1
  128. package/dist/server/combined-server.js +107 -8
  129. package/dist/server/combined-server.js.map +1 -1
  130. package/dist/store/event-store.d.ts +7 -1
  131. package/dist/store/event-store.d.ts.map +1 -1
  132. package/dist/store/event-store.js +91 -8
  133. package/dist/store/event-store.js.map +1 -1
  134. package/dist/store/types/agents.d.ts +23 -0
  135. package/dist/store/types/agents.d.ts.map +1 -1
  136. package/dist/store/types/events.d.ts +1 -1
  137. package/dist/store/types/events.d.ts.map +1 -1
  138. package/dist/task/backend/index.d.ts +47 -29
  139. package/dist/task/backend/index.d.ts.map +1 -1
  140. package/dist/task/backend/index.js +109 -71
  141. package/dist/task/backend/index.js.map +1 -1
  142. package/dist/task/backend/memory.d.ts +1 -0
  143. package/dist/task/backend/memory.d.ts.map +1 -1
  144. package/dist/task/backend/memory.js +3 -0
  145. package/dist/task/backend/memory.js.map +1 -1
  146. package/dist/task/backend/opentasks/backend.d.ts +140 -0
  147. package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
  148. package/dist/task/backend/opentasks/backend.js +1023 -0
  149. package/dist/task/backend/opentasks/backend.js.map +1 -0
  150. package/dist/task/backend/opentasks/client.d.ts +337 -0
  151. package/dist/task/backend/opentasks/client.d.ts.map +1 -0
  152. package/dist/task/backend/opentasks/client.js +225 -0
  153. package/dist/task/backend/opentasks/client.js.map +1 -0
  154. package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
  155. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
  156. package/dist/task/backend/opentasks/daemon-manager.js +195 -0
  157. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
  158. package/dist/task/backend/opentasks/index.d.ts +21 -0
  159. package/dist/task/backend/opentasks/index.d.ts.map +1 -0
  160. package/dist/task/backend/opentasks/index.js +21 -0
  161. package/dist/task/backend/opentasks/index.js.map +1 -0
  162. package/dist/task/backend/opentasks/mapping.d.ts +48 -0
  163. package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
  164. package/dist/task/backend/opentasks/mapping.js +77 -0
  165. package/dist/task/backend/opentasks/mapping.js.map +1 -0
  166. package/dist/task/backend/types.d.ts +33 -53
  167. package/dist/task/backend/types.d.ts.map +1 -1
  168. package/dist/task/backend/types.js +7 -11
  169. package/dist/task/backend/types.js.map +1 -1
  170. package/dist/task/backend/unified-tool-provider.d.ts +57 -0
  171. package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
  172. package/dist/task/backend/unified-tool-provider.js +623 -0
  173. package/dist/task/backend/unified-tool-provider.js.map +1 -0
  174. package/dist/teams/team-loader.d.ts +2 -2
  175. package/dist/teams/team-loader.js +3 -3
  176. package/dist/teams/team-loader.js.map +1 -1
  177. package/dist/teams/team-runtime.d.ts.map +1 -1
  178. package/dist/teams/team-runtime.js +2 -0
  179. package/dist/teams/team-runtime.js.map +1 -1
  180. package/docs/architecture.md +7 -6
  181. package/docs/configuration.md +26 -62
  182. package/docs/implementation-details.md +5 -5
  183. package/docs/implementation-summary.md +17 -17
  184. package/docs/plan-self-driving-support.md +4 -4
  185. package/docs/spec-self-driving-support.md +10 -10
  186. package/docs/team-templates.md +2 -2
  187. package/docs/teams.md +3 -3
  188. package/docs/troubleshooting.md +10 -11
  189. package/package.json +6 -4
  190. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
  191. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
  192. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
  193. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
  194. package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
  195. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
  196. package/src/acp/__tests__/history.test.ts +8 -4
  197. package/src/acp/__tests__/integration.test.ts +56 -31
  198. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  199. package/src/acp/macro-agent.ts +230 -62
  200. package/src/acp/types.ts +46 -1
  201. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  202. package/src/agent/agent-manager.ts +714 -261
  203. package/src/agent/types.ts +3 -1
  204. package/src/api/server.ts +41 -7
  205. package/src/auth/__tests__/token.test.ts +100 -0
  206. package/src/auth/index.ts +1 -0
  207. package/src/auth/token.ts +82 -0
  208. package/src/cli/__tests__/acp.test.ts +1 -1
  209. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  210. package/src/cli/acp.ts +130 -72
  211. package/src/cli/index.ts +120 -14
  212. package/src/cli/mcp.ts +311 -207
  213. package/src/cli/parse-args.ts +54 -0
  214. package/src/cli/stable-instance-id.ts +14 -0
  215. package/src/config/project-config.ts +190 -27
  216. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  217. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +820 -0
  218. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  219. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +724 -2
  220. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  221. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  222. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  223. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  224. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  225. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  226. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  227. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  228. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  229. package/src/map/adapter/acp-over-map.ts +777 -92
  230. package/src/map/adapter/connection-manager.ts +3 -0
  231. package/src/map/adapter/event-log.ts +208 -0
  232. package/src/map/adapter/event-translator.ts +6 -6
  233. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  234. package/src/map/adapter/extensions/index.ts +60 -0
  235. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  236. package/src/map/adapter/extensions/task.ts +11 -0
  237. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  238. package/src/map/adapter/index.ts +28 -0
  239. package/src/map/adapter/interface.ts +2 -0
  240. package/src/map/adapter/map-adapter.ts +373 -38
  241. package/src/map/adapter/subscription-manager.ts +5 -1
  242. package/src/map/adapter/types.ts +2 -0
  243. package/src/mcp/__tests__/map-client.test.ts +386 -0
  244. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  245. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  246. package/src/mcp/map-client.ts +177 -0
  247. package/src/mcp/mcp-server.ts +191 -100
  248. package/src/mcp/types.ts +6 -1
  249. package/src/metrics/metrics.ts +1 -1
  250. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  251. package/src/roles/__tests__/config-loader.test.ts +7 -7
  252. package/src/roles/capabilities.ts +17 -7
  253. package/src/roles/config-loader.ts +6 -6
  254. package/src/roles/registry.ts +2 -2
  255. package/src/server/__tests__/combined-server.test.ts +94 -21
  256. package/src/server/combined-server.ts +189 -33
  257. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  258. package/src/store/__tests__/event-store.test.ts +236 -1
  259. package/src/store/__tests__/instance.test.ts +3 -3
  260. package/src/store/event-store.ts +109 -8
  261. package/src/store/types/agents.ts +16 -0
  262. package/src/store/types/events.ts +1 -1
  263. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  264. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  265. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  266. package/src/task/backend/index.ts +156 -106
  267. package/src/task/backend/memory.ts +4 -0
  268. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  269. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  270. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  271. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  272. package/src/task/backend/opentasks/backend.ts +1323 -0
  273. package/src/task/backend/opentasks/client.ts +652 -0
  274. package/src/task/backend/opentasks/daemon-manager.ts +253 -0
  275. package/src/task/backend/opentasks/index.ts +69 -0
  276. package/src/task/backend/opentasks/mapping.ts +94 -0
  277. package/src/task/backend/types.ts +42 -66
  278. package/src/task/backend/unified-tool-provider.ts +779 -0
  279. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  280. package/src/teams/team-loader.ts +3 -3
  281. package/src/teams/team-runtime.ts +2 -0
  282. package/test_fixtures/README.md +2 -3
  283. package/test_fixtures/fixtures/index.ts +0 -3
  284. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  285. package/test_fixtures/fixtures/repos/index.ts +1 -3
  286. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  287. package/test_fixtures/fixtures/repos/types.ts +0 -11
  288. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  289. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  290. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  291. package/vitest.config.ts +1 -1
  292. package/vitest.e2e.config.ts +1 -1
  293. package/vitest.setup.ts +1 -30
  294. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  295. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  296. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  297. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  298. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  299. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  300. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  301. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  302. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  303. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  304. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  305. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  306. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  307. package/.macro-agent/teams/structured/team.yaml +0 -89
  308. package/docs/sudocode-integration.md +0 -383
  309. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  310. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  311. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  312. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  313. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  314. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  315. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  316. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  317. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  318. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  319. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  320. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  321. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  322. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  323. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  324. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  325. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  326. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  327. package/src/task/backend/sudocode/backend.ts +0 -1237
  328. package/src/task/backend/sudocode/client.ts +0 -515
  329. package/src/task/backend/sudocode/index.ts +0 -120
  330. package/src/task/backend/sudocode/mapping.ts +0 -93
  331. package/src/task/backend/sudocode/server-client.ts +0 -522
  332. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  333. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  334. package/src/task/backend/sudocode/tools.ts +0 -896
  335. package/src/task/backend/tool-provider.ts +0 -506
  336. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  337. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  338. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -0,0 +1,745 @@
1
+ /**
2
+ * MCP Bridge Extensions (_macro/mcp/*)
3
+ *
4
+ * Server-side extension handlers that mirror each MCP tool.
5
+ * When MCP subprocesses run in thin-client mode, their tool calls
6
+ * are routed here via ephemeral MAP WebSocket connections.
7
+ *
8
+ * Each handler receives agent context via `params.context` since the
9
+ * MAP ExtensionContext only has participant info, not agent identity.
10
+ */
11
+ import { RPCError } from "../rpc-handler.js";
12
+ import { ulid } from "ulid";
13
+ import { createDoneHandler } from "../../../mcp/tools/done.js";
14
+ import { createInjectContextHandler } from "../../../mcp/tools/inject_context.js";
15
+ import { createWaitForActivityHandler, } from "../../../mcp/tools/wait_for_activity.js";
16
+ import { createClaimTaskHandler } from "../../../mcp/tools/claim_task.js";
17
+ import { createUnclaimTaskHandler } from "../../../mcp/tools/unclaim_task.js";
18
+ import { createListClaimableTasksHandler } from "../../../mcp/tools/list_claimable_tasks.js";
19
+ // =============================================================================
20
+ // Agent Token Validation (module-level, set by registerMCPBridgeExtensions)
21
+ // =============================================================================
22
+ let _agentTokenManager;
23
+ /**
24
+ * Extract and validate agent context from params.
25
+ */
26
+ function extractContext(params) {
27
+ const p = (params ?? {});
28
+ const context = p.context;
29
+ if (!context?.agent_id) {
30
+ throw RPCError.invalidParams("params.context.agent_id is required");
31
+ }
32
+ // Validate per-agent token if token manager is configured
33
+ if (_agentTokenManager) {
34
+ if (!context.agent_token || !_agentTokenManager.verifyToken(context.agent_id, context.agent_token)) {
35
+ throw RPCError.invalidParams("Invalid or missing agent token");
36
+ }
37
+ }
38
+ // Return everything except context as args
39
+ const { context: _, ...args } = p;
40
+ return { context, args };
41
+ }
42
+ /**
43
+ * Build a ToolContext from the agent context.
44
+ */
45
+ function toToolContext(ctx) {
46
+ return {
47
+ agent_id: ctx.agent_id,
48
+ session_id: ctx.session_id,
49
+ task_id: ctx.task_id,
50
+ lineage: ctx.lineage ?? [],
51
+ cwd: ctx.cwd ?? process.cwd(),
52
+ };
53
+ }
54
+ // =============================================================================
55
+ // Handler Implementations
56
+ // =============================================================================
57
+ function createSpawnAgentBridge(services, emitMAPEvent) {
58
+ return async (_extCtx, params) => {
59
+ const { context, args } = extractContext(params);
60
+ const task = args.task;
61
+ const spawned = await services.agentManager.spawn({
62
+ task,
63
+ parent: context.agent_id,
64
+ subscribeParent: args.subscribe_parent ?? true,
65
+ topics: args.topics ?? [],
66
+ config: args.config,
67
+ cwd: args.cwd ?? context.cwd,
68
+ permissionMode: args.permission_mode,
69
+ });
70
+ // Fire-and-forget initial prompt so the agent starts working on its task.
71
+ // Without this, the agent process is running but idle — waiting for a message.
72
+ if (task) {
73
+ (async () => {
74
+ // Accumulate assistant response parts for history persistence
75
+ const buffer = { parts: [] };
76
+ const toolInfoCache = new Map();
77
+ // Emit user message event so TUI clients can show the task prompt
78
+ emitMAPEvent({
79
+ eventId: ulid(),
80
+ type: "session_user_message",
81
+ timestamp: Date.now(),
82
+ agentId: spawned.id,
83
+ data: {
84
+ agentId: spawned.id,
85
+ sessionId: spawned.session_id,
86
+ content: task,
87
+ },
88
+ });
89
+ try {
90
+ for await (const update of services.agentManager.prompt(spawned.id, task)) {
91
+ // Accumulate content for turn recording (mirrors acp-over-map.ts handlePrompt)
92
+ const u = update;
93
+ const updateType = u.sessionUpdate ?? u.type;
94
+ if (updateType === "agent_message_chunk") {
95
+ const content = u.content;
96
+ if (content?.text) {
97
+ const last = buffer.parts[buffer.parts.length - 1];
98
+ if (last && last.type === "text") {
99
+ last.text += content.text;
100
+ }
101
+ else {
102
+ buffer.parts.push({ type: "text", text: content.text });
103
+ }
104
+ }
105
+ }
106
+ else if (updateType === "tool_call" || updateType === "tool_call_update") {
107
+ const toolCallId = u.toolCallId;
108
+ const status = u.status;
109
+ const meta = u._meta;
110
+ if (updateType === "tool_call" && toolCallId) {
111
+ toolInfoCache.set(toolCallId, {
112
+ title: u.title,
113
+ name: meta?.claudeCode?.toolName,
114
+ input: u.rawInput,
115
+ });
116
+ }
117
+ if (status === "completed" || status === "failed") {
118
+ const cached = toolCallId ? toolInfoCache.get(toolCallId) : undefined;
119
+ const rawOutput = u.rawOutput;
120
+ let output;
121
+ if (typeof rawOutput === "string")
122
+ output = rawOutput;
123
+ else if (Array.isArray(rawOutput)) {
124
+ output = rawOutput
125
+ .filter((item) => item.type === "text" && typeof item.text === "string")
126
+ .map((item) => item.text)
127
+ .join("\n") || undefined;
128
+ }
129
+ buffer.parts.push({
130
+ type: "tool",
131
+ toolCallId,
132
+ title: u.title ?? cached?.title,
133
+ name: meta?.claudeCode?.toolName ?? cached?.name,
134
+ status: u.status,
135
+ input: u.rawInput ?? cached?.input,
136
+ output,
137
+ });
138
+ }
139
+ }
140
+ // Emit each session update as a MAP event for live streaming
141
+ emitMAPEvent({
142
+ eventId: ulid(),
143
+ type: "session_update",
144
+ timestamp: Date.now(),
145
+ agentId: spawned.id,
146
+ data: {
147
+ agentId: spawned.id,
148
+ sessionId: spawned.session_id,
149
+ update,
150
+ },
151
+ });
152
+ }
153
+ // Emit prompt done event
154
+ emitMAPEvent({
155
+ eventId: ulid(),
156
+ type: "session_prompt_done",
157
+ timestamp: Date.now(),
158
+ agentId: spawned.id,
159
+ data: {
160
+ agentId: spawned.id,
161
+ sessionId: spawned.session_id,
162
+ stopReason: "end_turn",
163
+ },
164
+ });
165
+ // Record turns so history is available when TUI reconnects
166
+ const now = Date.now();
167
+ const conversationId = spawned.session_id;
168
+ // Record user turn (the initial task prompt)
169
+ services.eventStore.emit({
170
+ type: "turn",
171
+ source: { agent_id: spawned.id },
172
+ payload: {
173
+ action: "recorded",
174
+ turn_id: `turn_user_${now}_${Math.random().toString(36).slice(2, 8)}`,
175
+ conversation_id: conversationId,
176
+ participant: "user",
177
+ timestamp: now,
178
+ content_type: "user_prompt",
179
+ content: task,
180
+ source_type: "explicit",
181
+ },
182
+ });
183
+ // Record assistant turn with accumulated content
184
+ if (buffer.parts.length > 0) {
185
+ services.eventStore.emit({
186
+ type: "turn",
187
+ source: { agent_id: spawned.id },
188
+ payload: {
189
+ action: "recorded",
190
+ turn_id: `turn_asst_${now}_${Math.random().toString(36).slice(2, 8)}`,
191
+ conversation_id: conversationId,
192
+ participant: spawned.id,
193
+ timestamp: now + 1,
194
+ content_type: "assistant_response",
195
+ content: { parts: buffer.parts },
196
+ source_type: "explicit",
197
+ },
198
+ });
199
+ }
200
+ }
201
+ catch (err) {
202
+ // Emit prompt done with error so TUI stops spinner
203
+ emitMAPEvent({
204
+ eventId: ulid(),
205
+ type: "session_prompt_done",
206
+ timestamp: Date.now(),
207
+ agentId: spawned.id,
208
+ data: {
209
+ agentId: spawned.id,
210
+ sessionId: spawned.session_id,
211
+ stopReason: "error",
212
+ },
213
+ });
214
+ console.error(`[MCP Bridge] Failed to send initial prompt to spawned agent ${spawned.id}:`, err);
215
+ }
216
+ })();
217
+ }
218
+ return {
219
+ agent_id: spawned.id,
220
+ task_id: spawned.agent.task_id,
221
+ session_id: spawned.session_id,
222
+ };
223
+ };
224
+ }
225
+ function createEmitStatusBridge(services, emitMAPEvent) {
226
+ return async (_extCtx, params) => {
227
+ const { context, args } = extractContext(params);
228
+ const event = services.eventStore.emit({
229
+ type: "status",
230
+ source: { agent_id: context.agent_id },
231
+ payload: {
232
+ status_type: args.status_type,
233
+ summary: args.summary,
234
+ details: args.details,
235
+ },
236
+ });
237
+ // Emit MAP event so TUI subscribers see the status update
238
+ const now = Date.now();
239
+ emitMAPEvent({
240
+ eventId: ulid(),
241
+ type: "status_emitted",
242
+ timestamp: now,
243
+ agentId: context.agent_id,
244
+ data: {
245
+ id: event.id,
246
+ agentId: context.agent_id,
247
+ taskId: context.task_id,
248
+ statusType: args.status_type,
249
+ summary: args.summary,
250
+ details: args.details,
251
+ timestamp: now,
252
+ },
253
+ });
254
+ let taskUpdated = false;
255
+ if (args.complete_task && args.status_type === "completed" && context.task_id) {
256
+ try {
257
+ services.taskManager.updateStatus(context.task_id, "completed");
258
+ taskUpdated = true;
259
+ }
260
+ catch { /* Task may not exist */ }
261
+ }
262
+ if (args.complete_task && args.status_type === "failed" && context.task_id) {
263
+ try {
264
+ services.taskManager.updateStatus(context.task_id, "failed");
265
+ taskUpdated = true;
266
+ }
267
+ catch { /* Task may not exist */ }
268
+ }
269
+ return { event_id: event.id, task_updated: taskUpdated };
270
+ };
271
+ }
272
+ function createSendMessageBridge(services) {
273
+ return async (_extCtx, params) => {
274
+ const { context, args } = extractContext(params);
275
+ const to = args.to;
276
+ if (!to) {
277
+ throw RPCError.invalidParams("params.to is required");
278
+ }
279
+ const address = to.agent_id
280
+ ? { agent: to.agent_id }
281
+ : to.task_id
282
+ ? { task: to.task_id }
283
+ : to.topic
284
+ ? { scope: to.topic }
285
+ : null;
286
+ if (!address) {
287
+ throw RPCError.invalidParams("Must specify one of: agent_id, task_id, or topic");
288
+ }
289
+ const result = await services.messageRouter.sendToAddress({
290
+ from: context.agent_id,
291
+ to: address,
292
+ content: args.content,
293
+ options: args.correlation_id ? { correlationId: args.correlation_id } : undefined,
294
+ });
295
+ return {
296
+ message_id: result.id,
297
+ delivered_to: result.delivered.length,
298
+ };
299
+ };
300
+ }
301
+ function createCheckMessagesBridge(services) {
302
+ return async (_extCtx, params) => {
303
+ const { context, args } = extractContext(params);
304
+ const limit = args.limit ?? 10;
305
+ const internalMessages = services.messageRouter.getMessages(context.agent_id, {
306
+ limit,
307
+ includeAcknowledged: args.include_acknowledged ?? false,
308
+ });
309
+ const formattedInternalMessages = internalMessages.map((msg) => ({
310
+ id: msg.id,
311
+ from: `agent:${msg.from.agent_id}`,
312
+ content: msg.content.length > 500 ? msg.content.substring(0, 500) : msg.content,
313
+ timestamp: msg.timestamp,
314
+ truncated: msg.truncated || msg.content.length > 500,
315
+ correlation_id: msg.correlation_id,
316
+ }));
317
+ // Get peer messages if peerManager is available
318
+ let formattedPeerMessages = [];
319
+ if (services.peerManager) {
320
+ const peerMessages = services.peerManager.getPeerMessages(context.agent_id);
321
+ formattedPeerMessages = peerMessages.map((msg) => ({
322
+ id: msg.id,
323
+ from: msg.from,
324
+ content: typeof msg.payload === "string"
325
+ ? msg.payload.length > 500 ? msg.payload.substring(0, 500) : msg.payload
326
+ : JSON.stringify(msg.payload).substring(0, 500),
327
+ timestamp: msg.timestamp,
328
+ truncated: typeof msg.payload === "string" ? msg.payload.length > 500 : false,
329
+ correlation_id: msg.correlationId,
330
+ is_request: msg.isRequest,
331
+ request_id: msg.requestId,
332
+ }));
333
+ }
334
+ const allFormattedMessages = [...formattedInternalMessages, ...formattedPeerMessages]
335
+ .sort((a, b) => a.timestamp - b.timestamp)
336
+ .slice(0, limit);
337
+ const allInternalMessages = services.messageRouter.getMessages(context.agent_id, {
338
+ limit: 1000,
339
+ includeAcknowledged: false,
340
+ });
341
+ const allPeerMessages = services.peerManager ? services.peerManager.getPeerMessages(context.agent_id) : [];
342
+ return {
343
+ messages: allFormattedMessages,
344
+ total_pending: allInternalMessages.length + allPeerMessages.length,
345
+ };
346
+ };
347
+ }
348
+ function createQueryIndexBridge(services) {
349
+ return async (_extCtx, params) => {
350
+ const { context: _context, args } = extractContext(params);
351
+ const entries = [];
352
+ const limit = args.limit ?? 20;
353
+ const offset = args.offset ?? 0;
354
+ const search = args.search?.toLowerCase();
355
+ const filter = args.filter;
356
+ const queryType = args.type;
357
+ if (queryType === "agents" || queryType === "all") {
358
+ let agents = services.agentManager.list();
359
+ if (filter?.state) {
360
+ agents = agents.filter((a) => a.state === filter.state);
361
+ }
362
+ if (filter?.parent !== undefined) {
363
+ agents = agents.filter((a) => a.parent === filter.parent);
364
+ }
365
+ if (search) {
366
+ agents = agents.filter((a) => a.id.toLowerCase().includes(search) ||
367
+ a.task?.toLowerCase().includes(search));
368
+ }
369
+ for (const agent of agents) {
370
+ entries.push({
371
+ type: "agent",
372
+ id: agent.id,
373
+ summary: agent.task ?? "No task description",
374
+ state: agent.state,
375
+ });
376
+ }
377
+ }
378
+ if (queryType === "tasks" || queryType === "all") {
379
+ let tasks = services.taskManager.list();
380
+ if (filter?.status) {
381
+ tasks = tasks.filter((t) => t.status === filter.status);
382
+ }
383
+ if (search) {
384
+ tasks = tasks.filter((t) => t.id.toLowerCase().includes(search) ||
385
+ t.description.toLowerCase().includes(search));
386
+ }
387
+ for (const task of tasks) {
388
+ entries.push({
389
+ type: "task",
390
+ id: task.id,
391
+ summary: task.description,
392
+ status: task.status,
393
+ });
394
+ }
395
+ }
396
+ const paginatedEntries = entries.slice(offset, offset + limit);
397
+ return {
398
+ entries: paginatedEntries,
399
+ total: entries.length,
400
+ has_more: offset + limit < entries.length,
401
+ };
402
+ };
403
+ }
404
+ function createGetHierarchyBridge(services) {
405
+ return async (_extCtx, params) => {
406
+ const { context, args } = extractContext(params);
407
+ let rootId;
408
+ if (args.root) {
409
+ rootId = args.root;
410
+ }
411
+ else {
412
+ rootId = context.lineage.length > 0 ? context.lineage[0] : context.agent_id;
413
+ }
414
+ const hierarchy = services.agentManager.getHierarchy(rootId);
415
+ if (!hierarchy) {
416
+ throw RPCError.notFound("agent", rootId);
417
+ }
418
+ function buildNode(node, currentDepth) {
419
+ const shouldIncludeChildren = args.depth === undefined || currentDepth < args.depth;
420
+ return {
421
+ agent_id: node.agent.id,
422
+ task: node.agent.task ?? "No task",
423
+ state: node.agent.state,
424
+ children: shouldIncludeChildren
425
+ ? node.children.map((c) => buildNode(c, currentDepth + 1))
426
+ : [],
427
+ };
428
+ }
429
+ const tree = buildNode(hierarchy.root, 1);
430
+ return {
431
+ tree,
432
+ depth: hierarchy.depth,
433
+ total_agents: hierarchy.totalAgents,
434
+ };
435
+ };
436
+ }
437
+ function createGetAgentSummaryBridge(services) {
438
+ return async (_extCtx, params) => {
439
+ const { context: _context, args } = extractContext(params);
440
+ const agentId = args.agent_id;
441
+ const agent = services.agentManager.get(agentId);
442
+ if (!agent) {
443
+ throw RPCError.notFound("agent", agentId);
444
+ }
445
+ const children = services.agentManager.getChildren(agentId);
446
+ const statusEvents = services.eventStore.query({
447
+ type: "status",
448
+ source_agent_id: agentId,
449
+ limit: 1,
450
+ });
451
+ const recentStatus = statusEvents.length > 0
452
+ ? {
453
+ type: statusEvents[0].payload.status_type,
454
+ summary: statusEvents[0].payload.summary,
455
+ timestamp: statusEvents[0].timestamp,
456
+ }
457
+ : undefined;
458
+ const lastActivity = agent.stopped_at ?? agent.started_at ?? agent.created_at;
459
+ return {
460
+ id: agent.id,
461
+ session_id: agent.session_id,
462
+ task: agent.task ?? "No task",
463
+ state: agent.state,
464
+ parent: agent.parent,
465
+ children_count: children.length,
466
+ last_activity: lastActivity,
467
+ recent_status: recentStatus,
468
+ };
469
+ };
470
+ }
471
+ function createStopAgentBridge(services) {
472
+ return async (_extCtx, params) => {
473
+ const { context, args } = extractContext(params);
474
+ const targetAgentId = args.agent_id;
475
+ const reason = (args.reason ?? "cancelled");
476
+ const targetAgent = services.agentManager.get(targetAgentId);
477
+ if (!targetAgent) {
478
+ throw RPCError.notFound("agent", targetAgentId);
479
+ }
480
+ // Check subtree authorization
481
+ const isInSubtree = targetAgentId === context.agent_id ||
482
+ targetAgent.lineage?.includes(context.agent_id);
483
+ if (!isInSubtree) {
484
+ throw RPCError.permissionDenied(`Cannot stop agent outside your subtree: ${targetAgentId}`);
485
+ }
486
+ const stoppedAgents = [];
487
+ async function stopRecursive(agentId) {
488
+ const agent = services.agentManager.get(agentId);
489
+ if (!agent || agent.state === "stopped")
490
+ return;
491
+ const children = services.agentManager.getChildren(agentId);
492
+ for (const child of children) {
493
+ await stopRecursive(child.id);
494
+ }
495
+ await services.agentManager.terminate(agentId, reason);
496
+ stoppedAgents.push(agentId);
497
+ }
498
+ await stopRecursive(targetAgentId);
499
+ return {
500
+ success: true,
501
+ stopped_agents: stoppedAgents,
502
+ };
503
+ };
504
+ }
505
+ function createDoneBridge(services) {
506
+ return async (_extCtx, params) => {
507
+ const { context, args } = extractContext(params);
508
+ const toolContext = toToolContext(context);
509
+ const doneDeps = {
510
+ eventStore: services.eventStore,
511
+ agentManager: services.agentManager,
512
+ messageRouter: services.messageRouter,
513
+ taskManager: services.taskManager,
514
+ roleRegistry: services.roleRegistry,
515
+ integrationStrategy: services.integrationStrategy,
516
+ };
517
+ const doneHandler = createDoneHandler(toolContext, doneDeps);
518
+ const result = await doneHandler(args);
519
+ // Handle termination if needed
520
+ if (result.shouldTerminate) {
521
+ setImmediate(async () => {
522
+ try {
523
+ await services.agentManager.terminate(context.agent_id, "completed");
524
+ }
525
+ catch { /* ignore */ }
526
+ });
527
+ }
528
+ return result;
529
+ };
530
+ }
531
+ function createInjectContextBridge(services) {
532
+ return async (_extCtx, params) => {
533
+ const { context, args } = extractContext(params);
534
+ const handler = createInjectContextHandler({ agentManager: services.agentManager, messageRouter: services.messageRouter }, context.agent_id);
535
+ return handler(args);
536
+ };
537
+ }
538
+ function createWaitForActivityBridge(services) {
539
+ return async (_extCtx, params) => {
540
+ const { context, args } = extractContext(params);
541
+ if (!services.activityWatcher) {
542
+ throw RPCError.internalError("ActivityWatcher not available");
543
+ }
544
+ const toolContext = toToolContext(context);
545
+ const handler = createWaitForActivityHandler(toolContext, {
546
+ activityWatcher: services.activityWatcher,
547
+ });
548
+ return handler(args);
549
+ };
550
+ }
551
+ function createClaimTaskBridge(services) {
552
+ return async (_extCtx, params) => {
553
+ const { context, args } = extractContext(params);
554
+ if (!services.taskBackend) {
555
+ throw RPCError.internalError("Task backend not available");
556
+ }
557
+ const toolContext = toToolContext(context);
558
+ const handler = createClaimTaskHandler(toolContext, {
559
+ taskBackend: services.taskBackend,
560
+ });
561
+ return handler(args);
562
+ };
563
+ }
564
+ function createUnclaimTaskBridge(services) {
565
+ return async (_extCtx, params) => {
566
+ const { context, args } = extractContext(params);
567
+ if (!services.taskBackend) {
568
+ throw RPCError.internalError("Task backend not available");
569
+ }
570
+ const toolContext = toToolContext(context);
571
+ const handler = createUnclaimTaskHandler(toolContext, {
572
+ taskBackend: services.taskBackend,
573
+ });
574
+ return handler(args);
575
+ };
576
+ }
577
+ function createListClaimableTasksBridge(services) {
578
+ return async (_extCtx, params) => {
579
+ const { context, args } = extractContext(params);
580
+ if (!services.taskBackend) {
581
+ throw RPCError.internalError("Task backend not available");
582
+ }
583
+ const toolContext = toToolContext(context);
584
+ const handler = createListClaimableTasksHandler(toolContext, {
585
+ taskBackend: services.taskBackend,
586
+ });
587
+ return handler(args);
588
+ };
589
+ }
590
+ // Peer communication bridges
591
+ function createSendPeerMessageBridge(services) {
592
+ return async (_extCtx, params) => {
593
+ const { context, args } = extractContext(params);
594
+ if (!services.peerManager || !services.peerManager.hasTransport()) {
595
+ throw RPCError.internalError("Peer communication not available");
596
+ }
597
+ await services.peerManager.sendMessage(context.agent_id, args.to, {
598
+ type: args.type,
599
+ payload: args.payload,
600
+ metadata: args.correlation_id ? { correlationId: args.correlation_id } : undefined,
601
+ });
602
+ return { success: true, timestamp: Date.now() };
603
+ };
604
+ }
605
+ function createSendPeerRequestBridge(services) {
606
+ return async (_extCtx, params) => {
607
+ const { context, args } = extractContext(params);
608
+ if (!services.peerManager || !services.peerManager.hasTransport()) {
609
+ throw RPCError.internalError("Peer communication not available");
610
+ }
611
+ return services.peerManager.sendRequest(context.agent_id, args.to, {
612
+ method: args.method,
613
+ params: args.params,
614
+ timeout: args.timeout,
615
+ });
616
+ };
617
+ }
618
+ function createRespondToPeerRequestBridge(services) {
619
+ return async (_extCtx, params) => {
620
+ const { context, args } = extractContext(params);
621
+ if (!services.peerManager) {
622
+ throw RPCError.internalError("Peer communication not available");
623
+ }
624
+ services.peerManager.respondToRequest(context.agent_id, args.request_id, {
625
+ result: args.result,
626
+ error: args.error,
627
+ });
628
+ return { success: true };
629
+ };
630
+ }
631
+ // =============================================================================
632
+ // Dynamic Task Tool Bridge
633
+ // =============================================================================
634
+ /**
635
+ * Creates a bridge handler for a dynamic task tool from the TaskToolProvider.
636
+ * The handler extracts agent context from params and delegates to the tool's
637
+ * handler. The TaskToolProvider's getContext() is backed by a mutable holder
638
+ * that we update here before each call (safe since Node.js is single-threaded).
639
+ */
640
+ function createTaskToolBridge(tool, contextHolder) {
641
+ return async (_extCtx, params) => {
642
+ const { context, args } = extractContext(params);
643
+ // Set the calling agent's ID so the tool provider's getContext() returns it
644
+ contextHolder.agent_id = context.agent_id;
645
+ // The tool handler receives the params directly (or unwrapped from the
646
+ // `params` envelope that the thin-client MCP server wraps them in)
647
+ const toolParams = args.params ?? args;
648
+ // The tool handler now calls backend.syncExternalTransition() internally
649
+ // after successful opentasks transitions, which updates the EventStore
650
+ // and triggers MAP events via onTaskChange.
651
+ return await tool.handler(toolParams);
652
+ };
653
+ }
654
+ // =============================================================================
655
+ // Registration
656
+ // =============================================================================
657
+ /**
658
+ * All MCP bridge extension method names.
659
+ */
660
+ export const MCP_BRIDGE_METHODS = [
661
+ "_macro/mcp/spawn_agent",
662
+ "_macro/mcp/emit_status",
663
+ "_macro/mcp/send_message",
664
+ "_macro/mcp/check_messages",
665
+ "_macro/mcp/query_index",
666
+ "_macro/mcp/get_hierarchy",
667
+ "_macro/mcp/get_agent_summary",
668
+ "_macro/mcp/stop_agent",
669
+ "_macro/mcp/done",
670
+ "_macro/mcp/inject_context",
671
+ "_macro/mcp/wait_for_activity",
672
+ "_macro/mcp/claim_task",
673
+ "_macro/mcp/unclaim_task",
674
+ "_macro/mcp/list_claimable_tasks",
675
+ "_macro/mcp/send_peer_message",
676
+ "_macro/mcp/send_peer_request",
677
+ "_macro/mcp/respond_to_peer_request",
678
+ "_macro/mcp/task_tools_list",
679
+ ];
680
+ /**
681
+ * Register all MCP bridge extension methods with the MAP adapter.
682
+ *
683
+ * These handlers mirror each MCP tool, allowing thin-client MCP subprocesses
684
+ * to execute tool logic on the main server via ephemeral WebSocket calls.
685
+ */
686
+ export function registerMCPBridgeExtensions(adapter, services) {
687
+ // Set module-level agent token manager for extractContext() validation
688
+ _agentTokenManager = services.agentTokenManager;
689
+ const emitMAPEvent = (event) => adapter.emitEvent(event);
690
+ adapter.registerExtension("_macro/mcp/spawn_agent", createSpawnAgentBridge(services, emitMAPEvent));
691
+ adapter.registerExtension("_macro/mcp/emit_status", createEmitStatusBridge(services, emitMAPEvent));
692
+ adapter.registerExtension("_macro/mcp/send_message", createSendMessageBridge(services));
693
+ adapter.registerExtension("_macro/mcp/check_messages", createCheckMessagesBridge(services));
694
+ adapter.registerExtension("_macro/mcp/query_index", createQueryIndexBridge(services));
695
+ adapter.registerExtension("_macro/mcp/get_hierarchy", createGetHierarchyBridge(services));
696
+ adapter.registerExtension("_macro/mcp/get_agent_summary", createGetAgentSummaryBridge(services));
697
+ adapter.registerExtension("_macro/mcp/stop_agent", createStopAgentBridge(services));
698
+ adapter.registerExtension("_macro/mcp/done", createDoneBridge(services));
699
+ adapter.registerExtension("_macro/mcp/inject_context", createInjectContextBridge(services));
700
+ if (services.activityWatcher) {
701
+ adapter.registerExtension("_macro/mcp/wait_for_activity", createWaitForActivityBridge(services));
702
+ }
703
+ if (services.taskBackend) {
704
+ adapter.registerExtension("_macro/mcp/claim_task", createClaimTaskBridge(services));
705
+ adapter.registerExtension("_macro/mcp/unclaim_task", createUnclaimTaskBridge(services));
706
+ adapter.registerExtension("_macro/mcp/list_claimable_tasks", createListClaimableTasksBridge(services));
707
+ }
708
+ if (services.peerManager) {
709
+ adapter.registerExtension("_macro/mcp/send_peer_message", createSendPeerMessageBridge(services));
710
+ adapter.registerExtension("_macro/mcp/send_peer_request", createSendPeerRequestBridge(services));
711
+ adapter.registerExtension("_macro/mcp/respond_to_peer_request", createRespondToPeerRequestBridge(services));
712
+ }
713
+ // Register dynamic task tool bridges from the TaskToolProvider
714
+ if (services.taskToolProvider) {
715
+ const contextHolder = services.taskToolContext ?? { agent_id: "" };
716
+ const tools = services.taskToolProvider.getTools();
717
+ for (const tool of tools) {
718
+ const method = `_macro/mcp/task_tool/${tool.name}`;
719
+ adapter.registerExtension(method, createTaskToolBridge(tool, contextHolder));
720
+ }
721
+ // Discovery endpoint: returns list of available task tool names so
722
+ // thin-client MCP subprocesses only register tools the server supports
723
+ adapter.registerExtension("_macro/mcp/task_tools_list", async () => {
724
+ return { tools: tools.map((t) => ({ name: t.name, description: t.description })) };
725
+ });
726
+ }
727
+ else {
728
+ // No task tools available — return empty list
729
+ adapter.registerExtension("_macro/mcp/task_tools_list", async () => {
730
+ return { tools: [] };
731
+ });
732
+ }
733
+ }
734
+ /**
735
+ * Unregister all MCP bridge extension methods.
736
+ */
737
+ export function unregisterMCPBridgeExtensions(adapter) {
738
+ for (const method of MCP_BRIDGE_METHODS) {
739
+ try {
740
+ adapter.unregisterExtension(method);
741
+ }
742
+ catch { /* ignore */ }
743
+ }
744
+ }
745
+ //# sourceMappingURL=mcp-bridge.js.map