macro-agent 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (660) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/.sudocode/issues.jsonl +28 -0
  3. package/.sudocode/specs.jsonl +8 -0
  4. package/CLAUDE.md +25 -17
  5. package/README.md +11 -29
  6. package/dist/acp/macro-agent.d.ts +15 -0
  7. package/dist/acp/macro-agent.d.ts.map +1 -1
  8. package/dist/acp/macro-agent.js +131 -35
  9. package/dist/acp/macro-agent.js.map +1 -1
  10. package/dist/acp/types.d.ts +32 -1
  11. package/dist/acp/types.d.ts.map +1 -1
  12. package/dist/acp/types.js.map +1 -1
  13. package/dist/agent/agent-manager.d.ts +65 -1
  14. package/dist/agent/agent-manager.d.ts.map +1 -1
  15. package/dist/agent/agent-manager.js +544 -200
  16. package/dist/agent/agent-manager.js.map +1 -1
  17. package/dist/agent/types.d.ts +8 -1
  18. package/dist/agent/types.d.ts.map +1 -1
  19. package/dist/agent/types.js.map +1 -1
  20. package/dist/api/server.d.ts +8 -1
  21. package/dist/api/server.d.ts.map +1 -1
  22. package/dist/api/server.js +136 -8
  23. package/dist/api/server.js.map +1 -1
  24. package/dist/api/types.d.ts +1 -1
  25. package/dist/api/types.d.ts.map +1 -1
  26. package/dist/auth/index.d.ts +2 -0
  27. package/dist/auth/index.d.ts.map +1 -0
  28. package/dist/auth/index.js +2 -0
  29. package/dist/auth/index.js.map +1 -0
  30. package/dist/auth/token.d.ts +41 -0
  31. package/dist/auth/token.d.ts.map +1 -0
  32. package/dist/auth/token.js +73 -0
  33. package/dist/auth/token.js.map +1 -0
  34. package/dist/cli/acp.d.ts +2 -23
  35. package/dist/cli/acp.d.ts.map +1 -1
  36. package/dist/cli/acp.js +197 -61
  37. package/dist/cli/acp.js.map +1 -1
  38. package/dist/cli/index.js +152 -16
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/mcp.d.ts +6 -0
  41. package/dist/cli/mcp.d.ts.map +1 -1
  42. package/dist/cli/mcp.js +279 -173
  43. package/dist/cli/mcp.js.map +1 -1
  44. package/dist/cli/parse-args.d.ts +20 -0
  45. package/dist/cli/parse-args.d.ts.map +1 -0
  46. package/dist/cli/parse-args.js +43 -0
  47. package/dist/cli/parse-args.js.map +1 -0
  48. package/dist/cli/stable-instance-id.d.ts +8 -0
  49. package/dist/cli/stable-instance-id.d.ts.map +1 -0
  50. package/dist/cli/stable-instance-id.js +14 -0
  51. package/dist/cli/stable-instance-id.js.map +1 -0
  52. package/dist/config/project-config.d.ts +85 -7
  53. package/dist/config/project-config.d.ts.map +1 -1
  54. package/dist/config/project-config.js +133 -20
  55. package/dist/config/project-config.js.map +1 -1
  56. package/dist/index.d.ts +1 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +2 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/lifecycle/handlers/index.d.ts +7 -3
  61. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  62. package/dist/lifecycle/handlers/index.js +25 -8
  63. package/dist/lifecycle/handlers/index.js.map +1 -1
  64. package/dist/lifecycle/types.d.ts +2 -0
  65. package/dist/lifecycle/types.d.ts.map +1 -1
  66. package/dist/lifecycle/types.js.map +1 -1
  67. package/dist/map/adapter/acp-over-map.d.ts +17 -0
  68. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  69. package/dist/map/adapter/acp-over-map.js +384 -23
  70. package/dist/map/adapter/acp-over-map.js.map +1 -1
  71. package/dist/map/adapter/connection-manager.d.ts.map +1 -1
  72. package/dist/map/adapter/connection-manager.js +3 -0
  73. package/dist/map/adapter/connection-manager.js.map +1 -1
  74. package/dist/map/adapter/event-log.d.ts +87 -0
  75. package/dist/map/adapter/event-log.d.ts.map +1 -0
  76. package/dist/map/adapter/event-log.js +122 -0
  77. package/dist/map/adapter/event-log.js.map +1 -0
  78. package/dist/map/adapter/event-translator.js +6 -6
  79. package/dist/map/adapter/event-translator.js.map +1 -1
  80. package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
  81. package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
  82. package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
  83. package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
  84. package/dist/map/adapter/extensions/index.d.ts +13 -1
  85. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  86. package/dist/map/adapter/extensions/index.js +61 -0
  87. package/dist/map/adapter/extensions/index.js.map +1 -1
  88. package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
  89. package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
  90. package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
  91. package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
  92. package/dist/map/adapter/extensions/rename.d.ts +29 -0
  93. package/dist/map/adapter/extensions/rename.d.ts.map +1 -0
  94. package/dist/map/adapter/extensions/rename.js +49 -0
  95. package/dist/map/adapter/extensions/rename.js.map +1 -0
  96. package/dist/map/adapter/extensions/streams.d.ts +95 -0
  97. package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
  98. package/dist/map/adapter/extensions/streams.js +515 -0
  99. package/dist/map/adapter/extensions/streams.js.map +1 -0
  100. package/dist/map/adapter/extensions/task.d.ts.map +1 -1
  101. package/dist/map/adapter/extensions/task.js +10 -0
  102. package/dist/map/adapter/extensions/task.js.map +1 -1
  103. package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
  104. package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
  105. package/dist/map/adapter/extensions/update-metadata.js +67 -0
  106. package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
  107. package/dist/map/adapter/index.d.ts +2 -1
  108. package/dist/map/adapter/index.d.ts.map +1 -1
  109. package/dist/map/adapter/index.js +10 -2
  110. package/dist/map/adapter/index.js.map +1 -1
  111. package/dist/map/adapter/interface.d.ts +2 -0
  112. package/dist/map/adapter/interface.d.ts.map +1 -1
  113. package/dist/map/adapter/map-adapter.d.ts +3 -0
  114. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  115. package/dist/map/adapter/map-adapter.js +258 -35
  116. package/dist/map/adapter/map-adapter.js.map +1 -1
  117. package/dist/map/adapter/subscription-manager.d.ts.map +1 -1
  118. package/dist/map/adapter/subscription-manager.js +5 -1
  119. package/dist/map/adapter/subscription-manager.js.map +1 -1
  120. package/dist/map/adapter/types.d.ts +3 -1
  121. package/dist/map/adapter/types.d.ts.map +1 -1
  122. package/dist/mcp/map-client.d.ts +39 -0
  123. package/dist/mcp/map-client.d.ts.map +1 -0
  124. package/dist/mcp/map-client.js +129 -0
  125. package/dist/mcp/map-client.js.map +1 -0
  126. package/dist/mcp/mcp-server.d.ts +16 -0
  127. package/dist/mcp/mcp-server.d.ts.map +1 -1
  128. package/dist/mcp/mcp-server.js +125 -88
  129. package/dist/mcp/mcp-server.js.map +1 -1
  130. package/dist/mcp/tools/done.d.ts.map +1 -1
  131. package/dist/mcp/tools/done.js +18 -0
  132. package/dist/mcp/tools/done.js.map +1 -1
  133. package/dist/mcp/types.d.ts +9 -1
  134. package/dist/mcp/types.d.ts.map +1 -1
  135. package/dist/mcp/types.js.map +1 -1
  136. package/dist/metrics/metrics.js +1 -1
  137. package/dist/metrics/metrics.js.map +1 -1
  138. package/dist/roles/builtin/coordinator.d.ts.map +1 -1
  139. package/dist/roles/builtin/coordinator.js +2 -1
  140. package/dist/roles/builtin/coordinator.js.map +1 -1
  141. package/dist/roles/builtin/integrator.d.ts.map +1 -1
  142. package/dist/roles/builtin/integrator.js +2 -1
  143. package/dist/roles/builtin/integrator.js.map +1 -1
  144. package/dist/roles/builtin/worker.d.ts.map +1 -1
  145. package/dist/roles/builtin/worker.js +3 -1
  146. package/dist/roles/builtin/worker.js.map +1 -1
  147. package/dist/roles/capabilities.d.ts +9 -1
  148. package/dist/roles/capabilities.d.ts.map +1 -1
  149. package/dist/roles/capabilities.js +27 -7
  150. package/dist/roles/capabilities.js.map +1 -1
  151. package/dist/roles/config-loader.d.ts +6 -6
  152. package/dist/roles/config-loader.d.ts.map +1 -1
  153. package/dist/roles/config-loader.js +8 -7
  154. package/dist/roles/config-loader.js.map +1 -1
  155. package/dist/roles/registry.d.ts +2 -2
  156. package/dist/roles/registry.js +2 -2
  157. package/dist/roles/types.d.ts +3 -1
  158. package/dist/roles/types.d.ts.map +1 -1
  159. package/dist/server/combined-server.d.ts +28 -1
  160. package/dist/server/combined-server.d.ts.map +1 -1
  161. package/dist/server/combined-server.js +111 -8
  162. package/dist/server/combined-server.js.map +1 -1
  163. package/dist/store/event-store.d.ts +2 -1
  164. package/dist/store/event-store.d.ts.map +1 -1
  165. package/dist/store/event-store.js +80 -24
  166. package/dist/store/event-store.js.map +1 -1
  167. package/dist/store/instance.d.ts +1 -1
  168. package/dist/store/instance.d.ts.map +1 -1
  169. package/dist/store/instance.js +2 -2
  170. package/dist/store/instance.js.map +1 -1
  171. package/dist/store/types/agents.d.ts +23 -0
  172. package/dist/store/types/agents.d.ts.map +1 -1
  173. package/dist/store/types/events.d.ts +1 -1
  174. package/dist/store/types/events.d.ts.map +1 -1
  175. package/dist/task/backend/index.d.ts +47 -29
  176. package/dist/task/backend/index.d.ts.map +1 -1
  177. package/dist/task/backend/index.js +109 -71
  178. package/dist/task/backend/index.js.map +1 -1
  179. package/dist/task/backend/memory.d.ts +1 -0
  180. package/dist/task/backend/memory.d.ts.map +1 -1
  181. package/dist/task/backend/memory.js +3 -0
  182. package/dist/task/backend/memory.js.map +1 -1
  183. package/dist/task/backend/opentasks/backend.d.ts +140 -0
  184. package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
  185. package/dist/task/backend/opentasks/backend.js +1023 -0
  186. package/dist/task/backend/opentasks/backend.js.map +1 -0
  187. package/dist/task/backend/opentasks/client.d.ts +337 -0
  188. package/dist/task/backend/opentasks/client.d.ts.map +1 -0
  189. package/dist/task/backend/opentasks/client.js +225 -0
  190. package/dist/task/backend/opentasks/client.js.map +1 -0
  191. package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
  192. package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
  193. package/dist/task/backend/opentasks/daemon-manager.js +195 -0
  194. package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
  195. package/dist/task/backend/opentasks/index.d.ts +21 -0
  196. package/dist/task/backend/opentasks/index.d.ts.map +1 -0
  197. package/dist/task/backend/opentasks/index.js +21 -0
  198. package/dist/task/backend/opentasks/index.js.map +1 -0
  199. package/dist/task/backend/opentasks/mapping.d.ts +48 -0
  200. package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
  201. package/dist/task/backend/opentasks/mapping.js +77 -0
  202. package/dist/task/backend/opentasks/mapping.js.map +1 -0
  203. package/dist/task/backend/types.d.ts +33 -53
  204. package/dist/task/backend/types.d.ts.map +1 -1
  205. package/dist/task/backend/types.js +7 -11
  206. package/dist/task/backend/types.js.map +1 -1
  207. package/dist/task/backend/unified-tool-provider.d.ts +57 -0
  208. package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
  209. package/dist/task/backend/unified-tool-provider.js +623 -0
  210. package/dist/task/backend/unified-tool-provider.js.map +1 -0
  211. package/dist/teams/index.d.ts +3 -1
  212. package/dist/teams/index.d.ts.map +1 -1
  213. package/dist/teams/index.js +2 -0
  214. package/dist/teams/index.js.map +1 -1
  215. package/dist/teams/seed-defaults.d.ts +20 -0
  216. package/dist/teams/seed-defaults.d.ts.map +1 -0
  217. package/dist/teams/seed-defaults.js +71 -0
  218. package/dist/teams/seed-defaults.js.map +1 -0
  219. package/dist/teams/team-loader.d.ts +7 -3
  220. package/dist/teams/team-loader.d.ts.map +1 -1
  221. package/dist/teams/team-loader.js +156 -164
  222. package/dist/teams/team-loader.js.map +1 -1
  223. package/dist/teams/team-manager.d.ts +112 -0
  224. package/dist/teams/team-manager.d.ts.map +1 -0
  225. package/dist/teams/team-manager.js +305 -0
  226. package/dist/teams/team-manager.js.map +1 -0
  227. package/dist/teams/team-runtime.d.ts +125 -19
  228. package/dist/teams/team-runtime.d.ts.map +1 -1
  229. package/dist/teams/team-runtime.js +529 -119
  230. package/dist/teams/team-runtime.js.map +1 -1
  231. package/dist/teams/types.d.ts +41 -151
  232. package/dist/teams/types.d.ts.map +1 -1
  233. package/dist/teams/types.js +2 -3
  234. package/dist/teams/types.js.map +1 -1
  235. package/docs/architecture.md +7 -6
  236. package/docs/configuration.md +26 -62
  237. package/docs/implementation-details.md +5 -5
  238. package/docs/implementation-summary.md +17 -17
  239. package/docs/plan-self-driving-support.md +4 -4
  240. package/docs/spec-self-driving-support.md +10 -10
  241. package/docs/team-templates.md +2 -2
  242. package/docs/teams.md +76 -3
  243. package/docs/troubleshooting.md +10 -11
  244. package/package.json +7 -4
  245. package/references/minimem/.claude/settings.json +7 -0
  246. package/references/minimem/.sudocode/issues.jsonl +18 -0
  247. package/references/minimem/.sudocode/specs.jsonl +1 -0
  248. package/references/minimem/CLAUDE.md +310 -0
  249. package/references/minimem/README.md +562 -0
  250. package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
  251. package/references/minimem/claude-plugin/.mcp.json +7 -0
  252. package/references/minimem/claude-plugin/README.md +158 -0
  253. package/references/minimem/claude-plugin/commands/recall.md +47 -0
  254. package/references/minimem/claude-plugin/commands/remember.md +41 -0
  255. package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
  256. package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
  257. package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
  258. package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
  259. package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
  260. package/references/minimem/media/banner.png +0 -0
  261. package/references/minimem/package-lock.json +5373 -0
  262. package/references/minimem/package.json +72 -0
  263. package/references/minimem/scripts/postbuild.js +35 -0
  264. package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
  265. package/references/minimem/src/__tests__/errors.test.ts +265 -0
  266. package/references/minimem/src/__tests__/helpers.ts +199 -0
  267. package/references/minimem/src/__tests__/internal.test.ts +407 -0
  268. package/references/minimem/src/__tests__/knowledge.test.ts +287 -0
  269. package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
  270. package/references/minimem/src/__tests__/session.test.ts +190 -0
  271. package/references/minimem/src/cli/__tests__/commands.test.ts +759 -0
  272. package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
  273. package/references/minimem/src/cli/commands/append.ts +76 -0
  274. package/references/minimem/src/cli/commands/config.ts +262 -0
  275. package/references/minimem/src/cli/commands/conflicts.ts +413 -0
  276. package/references/minimem/src/cli/commands/daemon.ts +169 -0
  277. package/references/minimem/src/cli/commands/index.ts +12 -0
  278. package/references/minimem/src/cli/commands/init.ts +88 -0
  279. package/references/minimem/src/cli/commands/mcp.ts +177 -0
  280. package/references/minimem/src/cli/commands/push-pull.ts +213 -0
  281. package/references/minimem/src/cli/commands/search.ts +158 -0
  282. package/references/minimem/src/cli/commands/status.ts +84 -0
  283. package/references/minimem/src/cli/commands/sync-init.ts +290 -0
  284. package/references/minimem/src/cli/commands/sync.ts +70 -0
  285. package/references/minimem/src/cli/commands/upsert.ts +197 -0
  286. package/references/minimem/src/cli/config.ts +584 -0
  287. package/references/minimem/src/cli/index.ts +264 -0
  288. package/references/minimem/src/cli/shared.ts +161 -0
  289. package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
  290. package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
  291. package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
  292. package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
  293. package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
  294. package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
  295. package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
  296. package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
  297. package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
  298. package/references/minimem/src/cli/sync/central.ts +292 -0
  299. package/references/minimem/src/cli/sync/conflicts.ts +204 -0
  300. package/references/minimem/src/cli/sync/daemon.ts +407 -0
  301. package/references/minimem/src/cli/sync/detection.ts +138 -0
  302. package/references/minimem/src/cli/sync/index.ts +107 -0
  303. package/references/minimem/src/cli/sync/operations.ts +373 -0
  304. package/references/minimem/src/cli/sync/registry.ts +279 -0
  305. package/references/minimem/src/cli/sync/state.ts +355 -0
  306. package/references/minimem/src/cli/sync/validation.ts +206 -0
  307. package/references/minimem/src/cli/sync/watcher.ts +234 -0
  308. package/references/minimem/src/cli/version.ts +34 -0
  309. package/references/minimem/src/core/index.ts +9 -0
  310. package/references/minimem/src/core/indexer.ts +628 -0
  311. package/references/minimem/src/core/searcher.ts +221 -0
  312. package/references/minimem/src/db/schema.ts +183 -0
  313. package/references/minimem/src/db/sqlite-vec.ts +24 -0
  314. package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
  315. package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
  316. package/references/minimem/src/embeddings/batch-openai.ts +409 -0
  317. package/references/minimem/src/embeddings/embeddings.ts +434 -0
  318. package/references/minimem/src/index.ts +109 -0
  319. package/references/minimem/src/internal.ts +299 -0
  320. package/references/minimem/src/minimem.ts +1276 -0
  321. package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
  322. package/references/minimem/src/search/graph.ts +234 -0
  323. package/references/minimem/src/search/hybrid.ts +151 -0
  324. package/references/minimem/src/search/search.ts +256 -0
  325. package/references/minimem/src/server/__tests__/mcp.test.ts +341 -0
  326. package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
  327. package/references/minimem/src/server/mcp.ts +326 -0
  328. package/references/minimem/src/server/tools.ts +720 -0
  329. package/references/minimem/src/session.ts +460 -0
  330. package/references/minimem/tsconfig.json +19 -0
  331. package/references/minimem/tsup.config.ts +26 -0
  332. package/references/minimem/vitest.config.ts +24 -0
  333. package/references/openteams/.claude/settings.json +6 -0
  334. package/references/openteams/README.md +1 -0
  335. package/references/openteams/SKILL.md +341 -0
  336. package/references/openteams/design.md +411 -0
  337. package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
  338. package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
  339. package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
  340. package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
  341. package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
  342. package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
  343. package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
  344. package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
  345. package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
  346. package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
  347. package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
  348. package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
  349. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
  350. package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
  351. package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
  352. package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
  353. package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
  354. package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
  355. package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
  356. package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
  357. package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
  358. package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
  359. package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
  360. package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
  361. package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
  362. package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
  363. package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
  364. package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
  365. package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
  366. package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
  367. package/references/openteams/examples/bmad-method/team.yaml +161 -0
  368. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/ROLE.md +17 -0
  369. package/references/openteams/examples/get-shit-done/prompts/codebase-mapper/SOUL.md +5 -0
  370. package/references/openteams/examples/get-shit-done/prompts/debugger/ROLE.md +25 -0
  371. package/references/openteams/examples/get-shit-done/prompts/debugger/SOUL.md +5 -0
  372. package/references/openteams/examples/get-shit-done/prompts/executor/ROLE.md +34 -0
  373. package/references/openteams/examples/get-shit-done/prompts/executor/SOUL.md +5 -0
  374. package/references/openteams/examples/get-shit-done/prompts/integration-checker/ROLE.md +18 -0
  375. package/references/openteams/examples/get-shit-done/prompts/integration-checker/SOUL.md +3 -0
  376. package/references/openteams/examples/get-shit-done/prompts/orchestrator/ROLE.md +42 -0
  377. package/references/openteams/examples/get-shit-done/prompts/orchestrator/SOUL.md +5 -0
  378. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/ROLE.md +15 -0
  379. package/references/openteams/examples/get-shit-done/prompts/phase-researcher/SOUL.md +3 -0
  380. package/references/openteams/examples/get-shit-done/prompts/plan-checker/ROLE.md +17 -0
  381. package/references/openteams/examples/get-shit-done/prompts/plan-checker/SOUL.md +3 -0
  382. package/references/openteams/examples/get-shit-done/prompts/planner/ROLE.md +28 -0
  383. package/references/openteams/examples/get-shit-done/prompts/planner/SOUL.md +5 -0
  384. package/references/openteams/examples/get-shit-done/prompts/project-researcher/ROLE.md +16 -0
  385. package/references/openteams/examples/get-shit-done/prompts/project-researcher/SOUL.md +3 -0
  386. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/ROLE.md +13 -0
  387. package/references/openteams/examples/get-shit-done/prompts/research-synthesizer/SOUL.md +3 -0
  388. package/references/openteams/examples/get-shit-done/prompts/roadmapper/ROLE.md +14 -0
  389. package/references/openteams/examples/get-shit-done/prompts/roadmapper/SOUL.md +3 -0
  390. package/references/openteams/examples/get-shit-done/prompts/verifier/ROLE.md +19 -0
  391. package/references/openteams/examples/get-shit-done/prompts/verifier/SOUL.md +5 -0
  392. package/references/openteams/examples/get-shit-done/roles/codebase-mapper.yaml +8 -0
  393. package/references/openteams/examples/get-shit-done/roles/debugger.yaml +8 -0
  394. package/references/openteams/examples/get-shit-done/roles/executor.yaml +8 -0
  395. package/references/openteams/examples/get-shit-done/roles/integration-checker.yaml +8 -0
  396. package/references/openteams/examples/get-shit-done/roles/orchestrator.yaml +9 -0
  397. package/references/openteams/examples/get-shit-done/roles/phase-researcher.yaml +7 -0
  398. package/references/openteams/examples/get-shit-done/roles/plan-checker.yaml +8 -0
  399. package/references/openteams/examples/get-shit-done/roles/planner.yaml +8 -0
  400. package/references/openteams/examples/get-shit-done/roles/project-researcher.yaml +8 -0
  401. package/references/openteams/examples/get-shit-done/roles/research-synthesizer.yaml +7 -0
  402. package/references/openteams/examples/get-shit-done/roles/roadmapper.yaml +7 -0
  403. package/references/openteams/examples/get-shit-done/roles/verifier.yaml +8 -0
  404. package/references/openteams/examples/get-shit-done/team.yaml +154 -0
  405. package/references/openteams/package-lock.json +2181 -0
  406. package/references/openteams/package.json +48 -0
  407. package/references/openteams/schema/role.schema.json +125 -0
  408. package/references/openteams/schema/team.schema.json +284 -0
  409. package/references/openteams/src/cli/agent.ts +104 -0
  410. package/references/openteams/src/cli/cli.test.ts +381 -0
  411. package/references/openteams/src/cli/generate.ts +220 -0
  412. package/references/openteams/src/cli/message.ts +241 -0
  413. package/references/openteams/src/cli/task.ts +154 -0
  414. package/references/openteams/src/cli/team.ts +104 -0
  415. package/references/openteams/src/cli/template.ts +207 -0
  416. package/references/openteams/src/cli.ts +45 -0
  417. package/references/openteams/src/db/database.test.ts +185 -0
  418. package/references/openteams/src/db/database.ts +240 -0
  419. package/references/openteams/src/generators/agent-prompt-generator.test.ts +332 -0
  420. package/references/openteams/src/generators/agent-prompt-generator.ts +521 -0
  421. package/references/openteams/src/generators/package-generator.test.ts +129 -0
  422. package/references/openteams/src/generators/package-generator.ts +102 -0
  423. package/references/openteams/src/generators/skill-generator.test.ts +246 -0
  424. package/references/openteams/src/generators/skill-generator.ts +374 -0
  425. package/references/openteams/src/index.ts +104 -0
  426. package/references/openteams/src/services/agent-service.test.ts +158 -0
  427. package/references/openteams/src/services/agent-service.ts +84 -0
  428. package/references/openteams/src/services/communication-service.test.ts +455 -0
  429. package/references/openteams/src/services/communication-service.ts +371 -0
  430. package/references/openteams/src/services/message-service.test.ts +342 -0
  431. package/references/openteams/src/services/message-service.ts +203 -0
  432. package/references/openteams/src/services/task-service.test.ts +434 -0
  433. package/references/openteams/src/services/task-service.ts +239 -0
  434. package/references/openteams/src/services/team-service.test.ts +181 -0
  435. package/references/openteams/src/services/team-service.ts +139 -0
  436. package/references/openteams/src/services/template-service.test.ts +306 -0
  437. package/references/openteams/src/services/template-service.ts +182 -0
  438. package/references/openteams/src/spawner/acp-factory.ts +96 -0
  439. package/references/openteams/src/spawner/interface.ts +31 -0
  440. package/references/openteams/src/spawner/mock.test.ts +93 -0
  441. package/references/openteams/src/spawner/mock.ts +59 -0
  442. package/references/openteams/src/template/loader.test.ts +1319 -0
  443. package/references/openteams/src/template/loader.ts +698 -0
  444. package/references/openteams/src/template/types.ts +200 -0
  445. package/references/openteams/src/types.ts +205 -0
  446. package/references/openteams/tsconfig.json +18 -0
  447. package/references/openteams/vitest.config.ts +9 -0
  448. package/references/skill-tree/.claude/settings.json +6 -0
  449. package/references/skill-tree/.sudocode/issues.jsonl +11 -0
  450. package/references/skill-tree/.sudocode/specs.jsonl +1 -0
  451. package/references/skill-tree/CLAUDE.md +150 -0
  452. package/references/skill-tree/README.md +324 -0
  453. package/references/skill-tree/docs/GAPS_v1.md +221 -0
  454. package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
  455. package/references/skill-tree/docs/TODOS.md +91 -0
  456. package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
  457. package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
  458. package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
  459. package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
  460. package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
  461. package/references/skill-tree/docs/scraper/README.md +170 -0
  462. package/references/skill-tree/examples/basic-usage.ts +190 -0
  463. package/references/skill-tree/package-lock.json +1509 -0
  464. package/references/skill-tree/package.json +66 -0
  465. package/references/skill-tree/scraper/README.md +123 -0
  466. package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
  467. package/references/skill-tree/scraper/docs/PLAN.md +336 -0
  468. package/references/skill-tree/scraper/drizzle.config.ts +10 -0
  469. package/references/skill-tree/scraper/package-lock.json +6329 -0
  470. package/references/skill-tree/scraper/package.json +68 -0
  471. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
  472. package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
  473. package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
  474. package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
  475. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
  476. package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
  477. package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
  478. package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
  479. package/references/skill-tree/scraper/tsup.config.ts +14 -0
  480. package/references/skill-tree/scraper/vitest.config.ts +17 -0
  481. package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
  482. package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
  483. package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
  484. package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
  485. package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
  486. package/references/skill-tree/test/run-all.ts +106 -0
  487. package/references/skill-tree/test/utils.ts +128 -0
  488. package/references/skill-tree/vitest.config.ts +16 -0
  489. package/src/__tests__/e2e/agent-spawn-visibility.e2e.test.ts +761 -0
  490. package/src/__tests__/e2e/full-agent-conflict-resolution.e2e.test.ts +2 -2
  491. package/src/__tests__/e2e/mcp-thin-client-bridge.e2e.test.ts +304 -0
  492. package/src/__tests__/e2e/mcp-tools-available.e2e.test.ts +324 -0
  493. package/src/__tests__/e2e/multi-agent.e2e.test.ts +5 -5
  494. package/src/__tests__/e2e/spawn-session-streaming.e2e.test.ts +563 -0
  495. package/src/acp/__tests__/integration.test.ts +56 -31
  496. package/src/acp/__tests__/macro-agent.test.ts +16 -7
  497. package/src/acp/macro-agent.ts +170 -36
  498. package/src/acp/types.ts +46 -1
  499. package/src/agent/__tests__/agent-manager.test.ts +228 -2
  500. package/src/agent/agent-manager.ts +809 -285
  501. package/src/agent/types.ts +12 -1
  502. package/src/api/__tests__/server.test.ts +203 -4
  503. package/src/api/server.ts +169 -10
  504. package/src/api/types.ts +3 -1
  505. package/src/auth/__tests__/token.test.ts +100 -0
  506. package/src/auth/index.ts +1 -0
  507. package/src/auth/token.ts +82 -0
  508. package/src/cli/__tests__/acp.test.ts +1 -1
  509. package/src/cli/__tests__/stable-instance-id.test.ts +1 -1
  510. package/src/cli/acp.ts +197 -72
  511. package/src/cli/index.ts +125 -15
  512. package/src/cli/mcp.ts +315 -197
  513. package/src/cli/parse-args.ts +54 -0
  514. package/src/cli/stable-instance-id.ts +14 -0
  515. package/src/config/project-config.ts +214 -27
  516. package/src/index.ts +3 -0
  517. package/src/lifecycle/__tests__/cascade-termination.test.ts +1 -1
  518. package/src/lifecycle/__tests__/handlers.test.ts +53 -0
  519. package/src/lifecycle/handlers/index.ts +25 -8
  520. package/src/lifecycle/types.ts +3 -0
  521. package/src/map/adapter/__tests__/acp-over-map-cancel.test.ts +22 -4
  522. package/src/map/adapter/__tests__/acp-over-map-getmodels.test.ts +355 -0
  523. package/src/map/adapter/__tests__/acp-over-map-history.test.ts +263 -0
  524. package/src/map/adapter/__tests__/acp-over-map-persistence.e2e.test.ts +1 -1
  525. package/src/map/adapter/__tests__/event-broadcast.test.ts +420 -0
  526. package/src/map/adapter/__tests__/event-log.test.ts +527 -0
  527. package/src/map/adapter/__tests__/event-translator.test.ts +3 -3
  528. package/src/map/adapter/__tests__/extensions.test.ts +408 -0
  529. package/src/map/adapter/__tests__/map-adapter.test.ts +99 -0
  530. package/src/map/adapter/__tests__/mcp-bridge.test.ts +1187 -0
  531. package/src/map/adapter/__tests__/multi-client-broadcast.test.ts +711 -0
  532. package/src/map/adapter/__tests__/stream-extensions.test.ts +494 -0
  533. package/src/map/adapter/__tests__/websocket-integration.test.ts +218 -0
  534. package/src/map/adapter/acp-over-map.ts +678 -66
  535. package/src/map/adapter/connection-manager.ts +3 -0
  536. package/src/map/adapter/event-log.ts +208 -0
  537. package/src/map/adapter/event-translator.ts +6 -6
  538. package/src/map/adapter/extensions/agent-lifecycle.ts +267 -0
  539. package/src/map/adapter/extensions/index.ts +96 -0
  540. package/src/map/adapter/extensions/mcp-bridge.ts +995 -0
  541. package/src/map/adapter/extensions/streams.ts +839 -0
  542. package/src/map/adapter/extensions/task.ts +11 -0
  543. package/src/map/adapter/extensions/update-metadata.ts +126 -0
  544. package/src/map/adapter/index.ts +33 -0
  545. package/src/map/adapter/interface.ts +2 -0
  546. package/src/map/adapter/map-adapter.ts +312 -47
  547. package/src/map/adapter/subscription-manager.ts +5 -1
  548. package/src/map/adapter/types.ts +10 -1
  549. package/src/mcp/__tests__/map-client.test.ts +386 -0
  550. package/src/mcp/__tests__/mcp-server-thin-client.test.ts +368 -0
  551. package/src/mcp/__tests__/mcp-server.test.ts +100 -1
  552. package/src/mcp/map-client.ts +177 -0
  553. package/src/mcp/mcp-server.ts +205 -103
  554. package/src/mcp/tools/done.ts +19 -0
  555. package/src/mcp/types.ts +6 -1
  556. package/src/metrics/metrics.ts +1 -1
  557. package/src/monitor/__tests__/stale-agent-flow.integration.test.ts +1 -1
  558. package/src/roles/__tests__/config-loader.test.ts +7 -7
  559. package/src/roles/builtin/coordinator.ts +2 -0
  560. package/src/roles/builtin/integrator.ts +2 -0
  561. package/src/roles/builtin/worker.ts +3 -0
  562. package/src/roles/capabilities.ts +28 -7
  563. package/src/roles/config-loader.ts +8 -7
  564. package/src/roles/registry.ts +2 -2
  565. package/src/roles/types.ts +7 -0
  566. package/src/server/__tests__/combined-server.test.ts +94 -21
  567. package/src/server/combined-server.ts +203 -33
  568. package/src/steering/__tests__/steering-integration.test.ts +1 -1
  569. package/src/store/__tests__/event-store-oob.test.ts +109 -0
  570. package/src/store/__tests__/event-store.test.ts +196 -1
  571. package/src/store/__tests__/instance.test.ts +3 -3
  572. package/src/store/event-store.ts +92 -23
  573. package/src/store/instance.ts +2 -2
  574. package/src/store/types/agents.ts +20 -0
  575. package/src/store/types/events.ts +1 -1
  576. package/src/task/backend/__tests__/create-task-backend.test.ts +225 -0
  577. package/src/task/backend/__tests__/e2e/unified-tool-provider-opentasks.e2e.test.ts +524 -0
  578. package/src/task/backend/__tests__/memory-pull-mode.test.ts +153 -0
  579. package/src/task/backend/__tests__/unified-tool-provider.test.ts +579 -0
  580. package/src/task/backend/index.ts +156 -106
  581. package/src/task/backend/memory.ts +4 -0
  582. package/src/task/backend/opentasks/__tests__/backend.test.ts +968 -0
  583. package/src/task/backend/opentasks/__tests__/daemon-manager.test.ts +406 -0
  584. package/src/task/backend/opentasks/__tests__/mapping.test.ts +84 -0
  585. package/src/task/backend/opentasks/__tests__/opentasks-backend.e2e.test.ts +1338 -0
  586. package/src/task/backend/opentasks/backend.ts +1323 -0
  587. package/src/task/backend/opentasks/client.ts +652 -0
  588. package/src/task/backend/opentasks/daemon-manager.ts +256 -0
  589. package/src/task/backend/opentasks/index.ts +69 -0
  590. package/src/task/backend/opentasks/mapping.ts +94 -0
  591. package/src/task/backend/types.ts +42 -66
  592. package/src/task/backend/unified-tool-provider.ts +779 -0
  593. package/src/teams/CLAUDE.md +180 -0
  594. package/src/teams/__tests__/cross-subsystem.integration.test.ts +1 -1
  595. package/src/teams/__tests__/e2e/workspace-isolation.e2e.test.ts +1263 -0
  596. package/src/teams/__tests__/team-manager.test.ts +814 -0
  597. package/src/teams/__tests__/team-system.test.ts +1291 -8
  598. package/src/teams/index.ts +21 -3
  599. package/src/teams/seed-defaults.ts +79 -0
  600. package/src/teams/team-loader.ts +202 -236
  601. package/src/teams/team-manager.ts +387 -0
  602. package/src/teams/team-runtime.ts +592 -121
  603. package/src/teams/types.ts +99 -200
  604. package/test_fixtures/README.md +2 -3
  605. package/test_fixtures/fixtures/index.ts +0 -3
  606. package/test_fixtures/fixtures/projects/project-with-specs.ts +7 -149
  607. package/test_fixtures/fixtures/repos/index.ts +1 -3
  608. package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -116
  609. package/test_fixtures/fixtures/repos/types.ts +0 -11
  610. package/test_fixtures/harness/__tests__/fixtures.test.ts +10 -102
  611. package/test_fixtures/harness/__tests__/temp-repo-and-simulator.test.ts +0 -33
  612. package/test_fixtures/harness/simulator/agent-simulator.ts +4 -4
  613. package/vitest.config.ts +1 -1
  614. package/vitest.e2e.config.ts +1 -1
  615. package/vitest.setup.ts +1 -30
  616. package/.macro-agent/teams/self-driving/prompts/grinder.md +0 -27
  617. package/.macro-agent/teams/self-driving/prompts/judge.md +0 -27
  618. package/.macro-agent/teams/self-driving/prompts/planner.md +0 -33
  619. package/.macro-agent/teams/self-driving/roles/grinder.yaml +0 -17
  620. package/.macro-agent/teams/self-driving/roles/judge.yaml +0 -24
  621. package/.macro-agent/teams/self-driving/roles/planner.yaml +0 -18
  622. package/.macro-agent/teams/self-driving/team.yaml +0 -103
  623. package/.macro-agent/teams/structured/prompts/developer.md +0 -26
  624. package/.macro-agent/teams/structured/prompts/lead.md +0 -25
  625. package/.macro-agent/teams/structured/prompts/reviewer.md +0 -24
  626. package/.macro-agent/teams/structured/roles/developer.yaml +0 -12
  627. package/.macro-agent/teams/structured/roles/lead.yaml +0 -11
  628. package/.macro-agent/teams/structured/roles/reviewer.yaml +0 -19
  629. package/.macro-agent/teams/structured/team.yaml +0 -89
  630. package/docs/sudocode-integration.md +0 -383
  631. package/src/task/backend/__tests__/backend-parity.test.ts +0 -451
  632. package/src/task/backend/__tests__/tool-provider-edge-cases.test.ts +0 -430
  633. package/src/task/backend/__tests__/tool-provider.test.ts +0 -983
  634. package/src/task/backend/sudocode/__tests__/backend-edge-cases.test.ts +0 -575
  635. package/src/task/backend/sudocode/__tests__/backend.test.ts +0 -1194
  636. package/src/task/backend/sudocode/__tests__/client-integration.test.ts +0 -418
  637. package/src/task/backend/sudocode/__tests__/client.test.ts +0 -345
  638. package/src/task/backend/sudocode/__tests__/e2e/backend.e2e.test.ts +0 -753
  639. package/src/task/backend/sudocode/__tests__/e2e/server-client.e2e.test.ts +0 -680
  640. package/src/task/backend/sudocode/__tests__/e2e-workflow.test.ts +0 -666
  641. package/src/task/backend/sudocode/__tests__/integration/standalone-client.integration.test.ts +0 -396
  642. package/src/task/backend/sudocode/__tests__/integration/sudocode-cli.integration.test.ts +0 -328
  643. package/src/task/backend/sudocode/__tests__/integration/test-utils.ts +0 -175
  644. package/src/task/backend/sudocode/__tests__/mapping-edge-cases.test.ts +0 -265
  645. package/src/task/backend/sudocode/__tests__/server-client.test.ts +0 -675
  646. package/src/task/backend/sudocode/__tests__/sync-policy-edge-cases.test.ts +0 -521
  647. package/src/task/backend/sudocode/__tests__/sync-policy.test.ts +0 -519
  648. package/src/task/backend/sudocode/__tests__/tools.test.ts +0 -471
  649. package/src/task/backend/sudocode/backend.ts +0 -1237
  650. package/src/task/backend/sudocode/client.ts +0 -515
  651. package/src/task/backend/sudocode/index.ts +0 -120
  652. package/src/task/backend/sudocode/mapping.ts +0 -93
  653. package/src/task/backend/sudocode/server-client.ts +0 -522
  654. package/src/task/backend/sudocode/standalone-client.ts +0 -623
  655. package/src/task/backend/sudocode/sync-policy.ts +0 -387
  656. package/src/task/backend/sudocode/tools.ts +0 -896
  657. package/src/task/backend/tool-provider.ts +0 -506
  658. package/test_fixtures/fixtures/sudocode/index.ts +0 -29
  659. package/test_fixtures/fixtures/sudocode/issues.ts +0 -185
  660. package/test_fixtures/fixtures/sudocode/specs.ts +0 -159
@@ -0,0 +1,761 @@
1
+ /**
2
+ * E2E test: Agent Spawn Visibility
3
+ *
4
+ * Verifies that agents spawned via various paths are visible through:
5
+ * 1. query_index MCP bridge (agentManager.list())
6
+ * 2. MAP subscription events (agent_registered notifications)
7
+ *
8
+ * Tests the full pipeline from spawn → EventStore → query/subscription.
9
+ */
10
+
11
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
12
+ import { WebSocket } from "ws";
13
+ import { createEventStore, type EventStore } from "../../store/event-store.js";
14
+ import {
15
+ createAgentManager,
16
+ type AgentManager,
17
+ } from "../../agent/agent-manager.js";
18
+ import { createTaskManager, type TaskManager } from "../../task/task-manager.js";
19
+ import {
20
+ createMessageRouter,
21
+ type MessageRouter,
22
+ } from "../../router/message-router.js";
23
+ import {
24
+ createCombinedServer,
25
+ type CombinedServer,
26
+ type CombinedServerServices,
27
+ } from "../../server/combined-server.js";
28
+ import { mapCall } from "../../mcp/map-client.js";
29
+
30
+ // =============================================================================
31
+ // Helpers
32
+ // =============================================================================
33
+
34
+ function getRandomPort(): number {
35
+ return 10000 + Math.floor(Math.random() * 50000);
36
+ }
37
+
38
+ function agentContext(agentId: string, taskId?: string) {
39
+ return {
40
+ agent_id: agentId,
41
+ session_id: "sess_test",
42
+ task_id: taskId ?? "task_test",
43
+ lineage: [],
44
+ cwd: "/test/cwd",
45
+ };
46
+ }
47
+
48
+ interface JsonRpcMessage {
49
+ jsonrpc: "2.0";
50
+ id?: number;
51
+ method?: string;
52
+ params?: unknown;
53
+ result?: unknown;
54
+ error?: { code: number; message: string; data?: unknown };
55
+ }
56
+
57
+ /**
58
+ * WebSocket MAP client for receiving subscription events.
59
+ */
60
+ class MAPTestClient {
61
+ private ws!: WebSocket;
62
+ private waiters: Map<
63
+ number,
64
+ { resolve: (r: JsonRpcMessage) => void; reject: (e: Error) => void }
65
+ > = new Map();
66
+ private nextId = 1;
67
+ private url: string;
68
+
69
+ readonly notifications: JsonRpcMessage[] = [];
70
+
71
+ private notificationWaiters: Array<{
72
+ check: (msg: JsonRpcMessage) => boolean;
73
+ resolve: (msg: JsonRpcMessage) => void;
74
+ reject: (e: Error) => void;
75
+ timeout: ReturnType<typeof setTimeout>;
76
+ }> = [];
77
+
78
+ constructor(url: string) {
79
+ this.url = url;
80
+ }
81
+
82
+ async connect(): Promise<void> {
83
+ this.ws = new WebSocket(this.url);
84
+ return new Promise((resolve, reject) => {
85
+ const timeout = setTimeout(
86
+ () => reject(new Error("Connection timeout")),
87
+ 5000,
88
+ );
89
+ this.ws.on("open", () => {
90
+ clearTimeout(timeout);
91
+ resolve();
92
+ });
93
+ this.ws.on("error", (err) => {
94
+ clearTimeout(timeout);
95
+ reject(err);
96
+ });
97
+ this.ws.on("message", (data: Buffer) => {
98
+ try {
99
+ const msg = JSON.parse(data.toString()) as JsonRpcMessage;
100
+ if (msg.id != null) {
101
+ const waiter = this.waiters.get(msg.id);
102
+ if (waiter) {
103
+ this.waiters.delete(msg.id);
104
+ waiter.resolve(msg);
105
+ }
106
+ } else if (msg.method) {
107
+ this.notifications.push(msg);
108
+ for (let i = this.notificationWaiters.length - 1; i >= 0; i--) {
109
+ const w = this.notificationWaiters[i];
110
+ if (w.check(msg)) {
111
+ clearTimeout(w.timeout);
112
+ this.notificationWaiters.splice(i, 1);
113
+ w.resolve(msg);
114
+ }
115
+ }
116
+ }
117
+ } catch {
118
+ // ignore
119
+ }
120
+ });
121
+ });
122
+ }
123
+
124
+ async request(method: string, params?: unknown): Promise<JsonRpcMessage> {
125
+ const id = this.nextId++;
126
+ return new Promise((resolve, reject) => {
127
+ const timeout = setTimeout(() => {
128
+ this.waiters.delete(id);
129
+ reject(new Error(`Request timeout: ${method}`));
130
+ }, 30000);
131
+ this.waiters.set(id, {
132
+ resolve: (r) => {
133
+ clearTimeout(timeout);
134
+ resolve(r);
135
+ },
136
+ reject: (e) => {
137
+ clearTimeout(timeout);
138
+ reject(e);
139
+ },
140
+ });
141
+ this.ws.send(JSON.stringify({ jsonrpc: "2.0", method, params, id }));
142
+ });
143
+ }
144
+
145
+ waitForNotification(
146
+ check: (msg: JsonRpcMessage) => boolean,
147
+ timeoutMs = 15000,
148
+ ): Promise<JsonRpcMessage> {
149
+ const existing = this.notifications.find(check);
150
+ if (existing) return Promise.resolve(existing);
151
+
152
+ return new Promise((resolve, reject) => {
153
+ const timeout = setTimeout(() => {
154
+ const idx = this.notificationWaiters.findIndex(
155
+ (w) => w.resolve === resolve,
156
+ );
157
+ if (idx >= 0) this.notificationWaiters.splice(idx, 1);
158
+ reject(
159
+ new Error(
160
+ `Timeout waiting for notification. Received ${this.notifications.length} notifications:\n` +
161
+ this.notifications
162
+ .map((n) => {
163
+ const p = n.params as Record<string, unknown> | undefined;
164
+ const evt = p?.event as Record<string, unknown> | undefined;
165
+ return ` ${n.method} → type=${evt?.type}, data=${JSON.stringify(evt?.data)}`;
166
+ })
167
+ .join("\n"),
168
+ ),
169
+ );
170
+ }, timeoutMs);
171
+ this.notificationWaiters.push({ check, resolve, reject, timeout });
172
+ });
173
+ }
174
+
175
+ close(): void {
176
+ for (const w of this.notificationWaiters) {
177
+ clearTimeout(w.timeout);
178
+ }
179
+ this.notificationWaiters.length = 0;
180
+ try {
181
+ this.ws?.close();
182
+ } catch {
183
+ // ignore
184
+ }
185
+ }
186
+ }
187
+
188
+ function isEventOfType(type: string) {
189
+ return (msg: JsonRpcMessage) => {
190
+ if (msg.method !== "map/event") return false;
191
+ const params = msg.params as Record<string, unknown> | undefined;
192
+ const event = params?.event as Record<string, unknown> | undefined;
193
+ return event?.type === type;
194
+ };
195
+ }
196
+
197
+ function isEventForAgent(type: string, agentId: string) {
198
+ return (msg: JsonRpcMessage) => {
199
+ if (msg.method !== "map/event") return false;
200
+ const params = msg.params as Record<string, unknown> | undefined;
201
+ const event = params?.event as Record<string, unknown> | undefined;
202
+ if (event?.type !== type) return false;
203
+ const data = event?.data as Record<string, unknown> | undefined;
204
+ return data?.agentId === agentId;
205
+ };
206
+ }
207
+
208
+ // =============================================================================
209
+ // Tests
210
+ // =============================================================================
211
+
212
+ describe("Agent Spawn Visibility E2E", () => {
213
+ let eventStore: EventStore;
214
+ let agentManager: AgentManager;
215
+ let taskManager: TaskManager;
216
+ let messageRouter: MessageRouter;
217
+ let server: CombinedServer;
218
+ let port: number;
219
+ let serverUrl: string;
220
+ const clients: MAPTestClient[] = [];
221
+
222
+ beforeEach(async () => {
223
+ port = getRandomPort();
224
+ serverUrl = `http://localhost:${port}`;
225
+
226
+ eventStore = await createEventStore({ inMemory: true });
227
+ messageRouter = createMessageRouter(eventStore);
228
+ agentManager = createAgentManager(eventStore, messageRouter, {
229
+ defaultPermissionMode: "auto-approve",
230
+ defaultCwd: "/test/cwd",
231
+ });
232
+ taskManager = createTaskManager(eventStore);
233
+
234
+ const services: CombinedServerServices = {
235
+ eventStore,
236
+ agentManager,
237
+ taskManager,
238
+ messageRouter,
239
+ };
240
+
241
+ server = createCombinedServer(services, { port, host: "localhost" });
242
+ await server.start();
243
+ });
244
+
245
+ afterEach(async () => {
246
+ for (const c of clients) {
247
+ c.close();
248
+ }
249
+ clients.length = 0;
250
+ await server.stop().catch(() => {});
251
+ await agentManager.close();
252
+ await eventStore.close();
253
+ });
254
+
255
+ function createClient(): MAPTestClient {
256
+ const client = new MAPTestClient(`ws://localhost:${port}/map`);
257
+ clients.push(client);
258
+ return client;
259
+ }
260
+
261
+ // ─────────────────────────────────────────────────────────────────
262
+ // query_index visibility
263
+ // ─────────────────────────────────────────────────────────────────
264
+
265
+ describe("query_index visibility", () => {
266
+ it("returns parent agent seeded via eventStore.emit", async () => {
267
+ // Seed root agent
268
+ eventStore.emit({
269
+ type: "spawn",
270
+ source: { agent_id: "system" },
271
+ payload: {
272
+ agent_id: "agent_root",
273
+ session_id: "sess_root",
274
+ task: "Root task",
275
+ task_id: "task_root",
276
+ parent: null,
277
+ config: {},
278
+ cwd: "/test",
279
+ },
280
+ });
281
+
282
+ const result = await mapCall<{
283
+ entries: Array<{ type: string; id: string; summary: string; state?: string }>;
284
+ total: number;
285
+ }>(serverUrl, "_macro/mcp/query_index", {
286
+ context: agentContext("agent_root"),
287
+ type: "agents",
288
+ });
289
+
290
+ expect(result.entries.length).toBeGreaterThanOrEqual(1);
291
+ expect(result.entries.some((e) => e.id === "agent_root")).toBe(true);
292
+ });
293
+
294
+ it("returns child agent after parent seeds it via eventStore.emit", async () => {
295
+ // Seed root agent
296
+ eventStore.emit({
297
+ type: "spawn",
298
+ source: { agent_id: "system" },
299
+ payload: {
300
+ agent_id: "agent_parent",
301
+ session_id: "sess_parent",
302
+ task: "Parent task",
303
+ task_id: "task_parent",
304
+ parent: null,
305
+ config: {},
306
+ cwd: "/test",
307
+ },
308
+ });
309
+
310
+ // Seed child agent (simulating what agentManager.spawn does internally)
311
+ eventStore.emit({
312
+ type: "spawn",
313
+ source: { agent_id: "agent_parent" },
314
+ payload: {
315
+ agent_id: "agent_child",
316
+ session_id: "sess_child",
317
+ task: "Child task",
318
+ task_id: "task_child",
319
+ parent: "agent_parent",
320
+ config: {},
321
+ cwd: "/test",
322
+ },
323
+ });
324
+
325
+ // Query from child's perspective — should see both agents
326
+ const result = await mapCall<{
327
+ entries: Array<{ type: string; id: string; summary: string; state?: string }>;
328
+ total: number;
329
+ }>(serverUrl, "_macro/mcp/query_index", {
330
+ context: agentContext("agent_parent"),
331
+ type: "agents",
332
+ });
333
+
334
+ expect(result.entries.length).toBeGreaterThanOrEqual(2);
335
+ expect(result.entries.some((e) => e.id === "agent_parent")).toBe(true);
336
+ expect(result.entries.some((e) => e.id === "agent_child")).toBe(true);
337
+
338
+ // Verify child has correct parent info
339
+ const child = result.entries.find((e) => e.id === "agent_child")!;
340
+ expect(child.summary).toBe("Child task");
341
+ expect(child.state).toBe("spawning");
342
+ });
343
+
344
+ it("returns agents with various states", async () => {
345
+ // Seed agent in spawning state
346
+ eventStore.emit({
347
+ type: "spawn",
348
+ source: { agent_id: "system" },
349
+ payload: {
350
+ agent_id: "agent_spawning",
351
+ session_id: "sess_1",
352
+ task: "Spawning agent",
353
+ task_id: "task_1",
354
+ parent: null,
355
+ config: {},
356
+ cwd: "/test",
357
+ },
358
+ });
359
+
360
+ // Seed another agent and transition to running via status event
361
+ eventStore.emit({
362
+ type: "spawn",
363
+ source: { agent_id: "system" },
364
+ payload: {
365
+ agent_id: "agent_running",
366
+ session_id: "sess_2",
367
+ task: "Running agent",
368
+ task_id: "task_2",
369
+ parent: null,
370
+ config: {},
371
+ cwd: "/test",
372
+ },
373
+ });
374
+ eventStore.emit({
375
+ type: "status",
376
+ source: { agent_id: "agent_running" },
377
+ payload: { status_type: "started", summary: "Agent started" },
378
+ });
379
+
380
+ // Seed a stopped agent
381
+ eventStore.emit({
382
+ type: "spawn",
383
+ source: { agent_id: "system" },
384
+ payload: {
385
+ agent_id: "agent_stopped",
386
+ session_id: "sess_3",
387
+ task: "Stopped agent",
388
+ task_id: "task_3",
389
+ parent: null,
390
+ config: {},
391
+ cwd: "/test",
392
+ },
393
+ });
394
+ eventStore.emit({
395
+ type: "stop",
396
+ source: { agent_id: "agent_stopped" },
397
+ payload: { reason: "completed" },
398
+ });
399
+
400
+ // query_index should return ALL agents (no state filter by default)
401
+ const result = await mapCall<{
402
+ entries: Array<{ type: string; id: string; state?: string }>;
403
+ total: number;
404
+ }>(serverUrl, "_macro/mcp/query_index", {
405
+ context: agentContext("agent_spawning"),
406
+ type: "agents",
407
+ });
408
+
409
+ expect(result.entries.length).toBe(3);
410
+
411
+ const spawning = result.entries.find((e) => e.id === "agent_spawning")!;
412
+ const running = result.entries.find((e) => e.id === "agent_running")!;
413
+ const stopped = result.entries.find((e) => e.id === "agent_stopped")!;
414
+
415
+ expect(spawning.state).toBe("spawning");
416
+ expect(running.state).toBe("running");
417
+ expect(stopped.state).toBe("stopped");
418
+ });
419
+ });
420
+
421
+ // ─────────────────────────────────────────────────────────────────
422
+ // MAP subscription visibility (agent_registered events)
423
+ // ─────────────────────────────────────────────────────────────────
424
+
425
+ describe("MAP subscription agent_registered events", () => {
426
+ it("subscriber receives agent_registered when agent is spawned via lifecycle", { timeout: 15_000 }, async () => {
427
+ // Connect a MAP subscriber
428
+ const subscriber = createClient();
429
+ await subscriber.connect();
430
+ const subRes = await subscriber.request("map/subscribe", {
431
+ filter: { eventTypes: ["agent_registered"] },
432
+ });
433
+ expect(subRes.error).toBeUndefined();
434
+
435
+ // Seed an agent via eventStore.emit — this simulates what
436
+ // agentManager.spawn() does internally. However, the lifecycle
437
+ // listener is on agentManager, not eventStore.emit.
438
+ // We need to trigger the lifecycle event.
439
+ //
440
+ // The lifecycle event is fired by notifyLifecycle({ type: "spawned", agent })
441
+ // which is called INSIDE agentManager.spawn() after the agent is created.
442
+ //
443
+ // Since we can't call agentManager.spawn() (needs real processes),
444
+ // we'll directly check if seeding via eventStore.emit triggers
445
+ // the MAP adapter's lifecycle listener.
446
+
447
+ // First, verify direct eventStore.emit does NOT trigger lifecycle
448
+ // (lifecycle is tied to agentManager, not eventStore)
449
+ eventStore.emit({
450
+ type: "spawn",
451
+ source: { agent_id: "system" },
452
+ payload: {
453
+ agent_id: "agent_direct",
454
+ session_id: "sess_direct",
455
+ task: "Direct seed",
456
+ task_id: "task_direct",
457
+ parent: null,
458
+ config: {},
459
+ cwd: "/test",
460
+ },
461
+ });
462
+
463
+ // Wait briefly to see if any notification arrives
464
+ await new Promise((r) => setTimeout(r, 1000));
465
+ const directNotifications = subscriber.notifications.filter(
466
+ isEventOfType("agent_registered"),
467
+ );
468
+
469
+ // Direct eventStore.emit bypasses agentManager lifecycle —
470
+ // this tells us whether agent_registered events rely on lifecycle
471
+ console.log(
472
+ `Direct seed produced ${directNotifications.length} agent_registered notifications`,
473
+ );
474
+ });
475
+
476
+ it("subscriber receives agent_registered with correct data shape for TUI", { timeout: 15_000 }, async () => {
477
+ // Connect subscriber
478
+ const subscriber = createClient();
479
+ await subscriber.connect();
480
+ const subRes = await subscriber.request("map/subscribe", {
481
+ filter: { eventTypes: ["agent_registered", "agent_state_changed"] },
482
+ });
483
+ expect(subRes.error).toBeUndefined();
484
+
485
+ // Use agentManager's lifecycle notification directly if available
486
+ // Seed an agent with proper metadata
487
+ eventStore.emit({
488
+ type: "spawn",
489
+ source: { agent_id: "system" },
490
+ payload: {
491
+ agent_id: "agent_tui_test",
492
+ session_id: "sess_tui",
493
+ task: "TUI visibility test",
494
+ task_id: "task_tui",
495
+ parent: null,
496
+ role: "worker",
497
+ config: {},
498
+ cwd: "/test",
499
+ },
500
+ });
501
+ eventStore.updateAgentMetadata("agent_tui_test" as any, {
502
+ name: "test-agent",
503
+ });
504
+
505
+ // Now manually trigger what the MAP adapter's lifecycle listener does
506
+ // by calling emitEvent on the server's MAP adapter.
507
+ // Since we can't access the adapter directly, we check if the
508
+ // onAgentChange listener on eventStore triggers it.
509
+
510
+ // The MAP adapter listens to agentManager.onLifecycleEvent,
511
+ // NOT eventStore.onAgentChange. So direct seeding won't emit
512
+ // MAP events. This is likely part of the bug.
513
+
514
+ // Let's verify by checking if there's an eventStore.onAgentChange
515
+ // listener that could emit agent_registered
516
+ await new Promise((r) => setTimeout(r, 1000));
517
+
518
+ console.log(
519
+ `Total notifications after seed: ${subscriber.notifications.length}`,
520
+ );
521
+ console.log(
522
+ `Notification types: ${subscriber.notifications.map((n) => {
523
+ const p = n.params as Record<string, unknown>;
524
+ const e = p?.event as Record<string, unknown>;
525
+ return e?.type;
526
+ }).join(", ")}`,
527
+ );
528
+
529
+ // If no agent_registered notification arrived, the bug is that
530
+ // the MAP adapter only listens to agentManager lifecycle events,
531
+ // but seeding via eventStore.emit (which is what the bridge handler does)
532
+ // doesn't trigger lifecycle events.
533
+ });
534
+ });
535
+
536
+ // ─────────────────────────────────────────────────────────────────
537
+ // Spawn via bridge + query visibility (critical integration test)
538
+ // ─────────────────────────────────────────────────────────────────
539
+
540
+ describe("spawn then query integration", () => {
541
+ it("spawn_agent bridge handler makes child visible in query_index", { timeout: 30_000 }, async () => {
542
+ // Seed a root agent (the "caller")
543
+ eventStore.emit({
544
+ type: "spawn",
545
+ source: { agent_id: "system" },
546
+ payload: {
547
+ agent_id: "agent_caller",
548
+ session_id: "sess_caller",
549
+ task: "Caller agent",
550
+ task_id: "task_caller",
551
+ parent: null,
552
+ config: {},
553
+ cwd: "/test/cwd",
554
+ },
555
+ });
556
+
557
+ // Try to spawn a child via the bridge
558
+ // NOTE: This may fail because agentManager.spawn() tries to start
559
+ // a real subprocess via AgentFactory. If it does, we catch and
560
+ // analyze where it fails.
561
+ let spawnedAgentId: string | undefined;
562
+ let spawnError: Error | undefined;
563
+
564
+ try {
565
+ const result = await mapCall<{
566
+ agent_id: string;
567
+ task_id: string;
568
+ session_id: string;
569
+ }>(serverUrl, "_macro/mcp/spawn_agent", {
570
+ context: agentContext("agent_caller", "task_caller"),
571
+ task: "Child task from bridge",
572
+ });
573
+ spawnedAgentId = result.agent_id;
574
+ console.log(`spawn_agent succeeded: ${JSON.stringify(result)}`);
575
+ } catch (err) {
576
+ spawnError = err as Error;
577
+ console.log(`spawn_agent failed: ${spawnError.message}`);
578
+ }
579
+
580
+ if (spawnedAgentId) {
581
+ // Spawn succeeded — verify the child appears in query_index
582
+ const result = await mapCall<{
583
+ entries: Array<{ type: string; id: string; summary: string }>;
584
+ total: number;
585
+ }>(serverUrl, "_macro/mcp/query_index", {
586
+ context: agentContext("agent_caller"),
587
+ type: "agents",
588
+ });
589
+
590
+ console.log(`query_index returned ${result.entries.length} agents:`);
591
+ for (const entry of result.entries) {
592
+ console.log(` ${entry.id}: ${entry.summary}`);
593
+ }
594
+
595
+ expect(
596
+ result.entries.some((e) => e.id === spawnedAgentId),
597
+ `Spawned agent ${spawnedAgentId} should appear in query_index`,
598
+ ).toBe(true);
599
+ } else {
600
+ // Spawn failed — expected in test env without real processes.
601
+ // Verify the root agent still exists and no orphaned state.
602
+ console.log(
603
+ "spawn_agent requires real process — testing with direct seeding instead",
604
+ );
605
+
606
+ // Directly seed a child (like spawn does internally)
607
+ eventStore.emit({
608
+ type: "spawn",
609
+ source: { agent_id: "agent_caller" },
610
+ payload: {
611
+ agent_id: "agent_child_direct",
612
+ session_id: "sess_child",
613
+ task: "Direct child",
614
+ task_id: "task_child",
615
+ parent: "agent_caller",
616
+ config: {},
617
+ cwd: "/test/cwd",
618
+ },
619
+ });
620
+
621
+ const result = await mapCall<{
622
+ entries: Array<{ type: string; id: string; summary: string }>;
623
+ total: number;
624
+ }>(serverUrl, "_macro/mcp/query_index", {
625
+ context: agentContext("agent_caller"),
626
+ type: "agents",
627
+ });
628
+
629
+ expect(
630
+ result.entries.some((e) => e.id === "agent_child_direct"),
631
+ "Directly seeded child should appear in query_index",
632
+ ).toBe(true);
633
+ }
634
+ });
635
+
636
+ it("MAP subscriber receives agent_registered when spawn_agent succeeds", { timeout: 30_000 }, async () => {
637
+ // Set up subscriber first
638
+ const subscriber = createClient();
639
+ await subscriber.connect();
640
+ await subscriber.request("map/subscribe", {
641
+ filter: { eventTypes: ["agent_registered", "agent_state_changed"] },
642
+ });
643
+
644
+ // Seed root agent
645
+ eventStore.emit({
646
+ type: "spawn",
647
+ source: { agent_id: "system" },
648
+ payload: {
649
+ agent_id: "agent_root_sub",
650
+ session_id: "sess_root",
651
+ task: "Root for subscription test",
652
+ task_id: "task_root",
653
+ parent: null,
654
+ config: {},
655
+ cwd: "/test/cwd",
656
+ },
657
+ });
658
+
659
+ // Try spawn via bridge
660
+ let spawnedAgentId: string | undefined;
661
+ try {
662
+ const result = await mapCall<{ agent_id: string }>(
663
+ serverUrl,
664
+ "_macro/mcp/spawn_agent",
665
+ {
666
+ context: agentContext("agent_root_sub", "task_root"),
667
+ task: "Subscriber test child",
668
+ },
669
+ );
670
+ spawnedAgentId = result.agent_id;
671
+ } catch {
672
+ console.log("spawn_agent requires real processes — skipping subscriber verification");
673
+ }
674
+
675
+ if (spawnedAgentId) {
676
+ // Wait for the agent_registered notification
677
+ const notification = await subscriber.waitForNotification(
678
+ isEventForAgent("agent_registered", spawnedAgentId),
679
+ 10000,
680
+ );
681
+
682
+ expect(notification.method).toBe("map/event");
683
+ const params = notification.params as Record<string, unknown>;
684
+ const event = params.event as Record<string, unknown>;
685
+ const data = event.data as Record<string, unknown>;
686
+
687
+ // Verify data shape matches what TUI sync.tsx expects
688
+ expect(data.agentId).toBe(spawnedAgentId);
689
+ expect(data).toHaveProperty("name");
690
+ expect(data).toHaveProperty("role");
691
+ expect(data.role).toBe("worker"); // Defaults to "worker" when not specified
692
+ expect(data).toHaveProperty("state");
693
+ expect(data).toHaveProperty("metadata");
694
+
695
+ console.log("agent_registered event data shape:", JSON.stringify(data, null, 2));
696
+ }
697
+ });
698
+ });
699
+
700
+ // ─────────────────────────────────────────────────────────────────
701
+ // Event shape verification
702
+ // ─────────────────────────────────────────────────────────────────
703
+
704
+ describe("event shape verification for TUI compatibility", () => {
705
+ it("agent_registered notification has SDK format expected by streamEvents", async () => {
706
+ // Connect subscriber
707
+ const subscriber = createClient();
708
+ await subscriber.connect();
709
+ await subscriber.request("map/subscribe", {
710
+ filter: { eventTypes: ["agent_registered"] },
711
+ });
712
+
713
+ // We can't spawn real agents, so let's use the map/replay endpoint
714
+ // to check historical events. First, seed an agent.
715
+ eventStore.emit({
716
+ type: "spawn",
717
+ source: { agent_id: "system" },
718
+ payload: {
719
+ agent_id: "agent_shape_test",
720
+ session_id: "sess_shape",
721
+ task: "Shape test",
722
+ task_id: "task_shape",
723
+ parent: null,
724
+ config: {},
725
+ cwd: "/test",
726
+ },
727
+ });
728
+
729
+ // Use map/replay to see if the spawn was recorded as an agent_registered event
730
+ const replayRes = await subscriber.request("map/replay", {
731
+ filter: { eventTypes: ["agent_registered"] },
732
+ limit: 100,
733
+ });
734
+
735
+ console.log("replay response:", JSON.stringify(replayRes.result, null, 2));
736
+
737
+ // The replay result tells us whether agent_registered events are
738
+ // being recorded. If replay returns empty, the lifecycle listener
739
+ // isn't firing for eventStore.emit-based spawns.
740
+ const result = replayRes.result as {
741
+ events: Array<{ event: { type: string; data: Record<string, unknown> } }>;
742
+ } | null;
743
+
744
+ if (result?.events?.length) {
745
+ // Verify the event shape matches TUI expectations
746
+ const event = result.events[0].event;
747
+ expect(event.type).toBe("agent_registered");
748
+
749
+ // TUI sync.tsx expects data.agentId (line 232-247 of sync.tsx)
750
+ expect(event.data.agentId).toBeDefined();
751
+ console.log("Event data shape:", JSON.stringify(event.data, null, 2));
752
+ } else {
753
+ console.log(
754
+ "No agent_registered events in replay — " +
755
+ "eventStore.emit('spawn') does NOT trigger lifecycle → " +
756
+ "MAP adapter never emits agent_registered for directly seeded agents",
757
+ );
758
+ }
759
+ });
760
+ });
761
+ });