macro-agent 0.0.10 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/.macro-agent/teams/self-driving/prompts/grinder.md +27 -0
  2. package/.macro-agent/teams/self-driving/prompts/judge.md +27 -0
  3. package/.macro-agent/teams/self-driving/prompts/planner.md +33 -0
  4. package/.macro-agent/teams/self-driving/roles/grinder.yaml +17 -0
  5. package/.macro-agent/teams/self-driving/roles/judge.yaml +24 -0
  6. package/.macro-agent/teams/self-driving/roles/planner.yaml +18 -0
  7. package/.macro-agent/teams/self-driving/team.yaml +103 -0
  8. package/.macro-agent/teams/structured/prompts/developer.md +26 -0
  9. package/.macro-agent/teams/structured/prompts/lead.md +25 -0
  10. package/.macro-agent/teams/structured/prompts/reviewer.md +24 -0
  11. package/.macro-agent/teams/structured/roles/developer.yaml +12 -0
  12. package/.macro-agent/teams/structured/roles/lead.yaml +11 -0
  13. package/.macro-agent/teams/structured/roles/reviewer.yaml +19 -0
  14. package/.macro-agent/teams/structured/team.yaml +89 -0
  15. package/.sudocode/issues.jsonl +56 -51
  16. package/.sudocode/specs.jsonl +8 -1
  17. package/CLAUDE.md +121 -30
  18. package/README.md +60 -3
  19. package/dist/acp/macro-agent.d.ts +4 -0
  20. package/dist/acp/macro-agent.d.ts.map +1 -1
  21. package/dist/acp/macro-agent.js +50 -4
  22. package/dist/acp/macro-agent.js.map +1 -1
  23. package/dist/acp/session-mapper.d.ts +20 -1
  24. package/dist/acp/session-mapper.d.ts.map +1 -1
  25. package/dist/acp/session-mapper.js +90 -1
  26. package/dist/acp/session-mapper.js.map +1 -1
  27. package/dist/acp/types.d.ts +24 -1
  28. package/dist/acp/types.d.ts.map +1 -1
  29. package/dist/acp/types.js.map +1 -1
  30. package/dist/agent/agent-manager.d.ts +40 -1
  31. package/dist/agent/agent-manager.d.ts.map +1 -1
  32. package/dist/agent/agent-manager.js +172 -8
  33. package/dist/agent/agent-manager.js.map +1 -1
  34. package/dist/agent/types.d.ts +22 -0
  35. package/dist/agent/types.d.ts.map +1 -1
  36. package/dist/agent/types.js.map +1 -1
  37. package/dist/agent/wake.d.ts +15 -0
  38. package/dist/agent/wake.d.ts.map +1 -1
  39. package/dist/agent/wake.js +15 -0
  40. package/dist/agent/wake.js.map +1 -1
  41. package/dist/agent-detection/command-builder.d.ts +30 -0
  42. package/dist/agent-detection/command-builder.d.ts.map +1 -0
  43. package/dist/agent-detection/command-builder.js +71 -0
  44. package/dist/agent-detection/command-builder.js.map +1 -0
  45. package/dist/agent-detection/detector.d.ts +84 -0
  46. package/dist/agent-detection/detector.d.ts.map +1 -0
  47. package/dist/agent-detection/detector.js +240 -0
  48. package/dist/agent-detection/detector.js.map +1 -0
  49. package/dist/agent-detection/index.d.ts +12 -0
  50. package/dist/agent-detection/index.d.ts.map +1 -0
  51. package/dist/agent-detection/index.js +14 -0
  52. package/dist/agent-detection/index.js.map +1 -0
  53. package/dist/agent-detection/registry.d.ts +53 -0
  54. package/dist/agent-detection/registry.d.ts.map +1 -0
  55. package/dist/agent-detection/registry.js +177 -0
  56. package/dist/agent-detection/registry.js.map +1 -0
  57. package/dist/agent-detection/types.d.ts +121 -0
  58. package/dist/agent-detection/types.d.ts.map +1 -0
  59. package/dist/agent-detection/types.js +20 -0
  60. package/dist/agent-detection/types.js.map +1 -0
  61. package/dist/api/server.d.ts +5 -1
  62. package/dist/api/server.d.ts.map +1 -1
  63. package/dist/api/server.js +362 -0
  64. package/dist/api/server.js.map +1 -1
  65. package/dist/api/types.d.ts +50 -1
  66. package/dist/api/types.d.ts.map +1 -1
  67. package/dist/cli/acp.d.ts +2 -0
  68. package/dist/cli/acp.d.ts.map +1 -1
  69. package/dist/cli/acp.js +8 -1
  70. package/dist/cli/acp.js.map +1 -1
  71. package/dist/cli/index.js +29 -0
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/mcp.js +38 -0
  74. package/dist/cli/mcp.js.map +1 -1
  75. package/dist/config/index.d.ts +2 -0
  76. package/dist/config/index.d.ts.map +1 -0
  77. package/dist/config/index.js +2 -0
  78. package/dist/config/index.js.map +1 -0
  79. package/dist/config/project-config.d.ts +46 -0
  80. package/dist/config/project-config.d.ts.map +1 -0
  81. package/dist/config/project-config.js +68 -0
  82. package/dist/config/project-config.js.map +1 -0
  83. package/dist/lifecycle/cascade.d.ts +1 -1
  84. package/dist/lifecycle/cascade.d.ts.map +1 -1
  85. package/dist/lifecycle/handlers/index.d.ts +4 -0
  86. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  87. package/dist/lifecycle/handlers/index.js +2 -0
  88. package/dist/lifecycle/handlers/index.js.map +1 -1
  89. package/dist/lifecycle/handlers/worker.d.ts +4 -0
  90. package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
  91. package/dist/lifecycle/handlers/worker.js +35 -3
  92. package/dist/lifecycle/handlers/worker.js.map +1 -1
  93. package/dist/mail/conversation-map.d.ts +33 -0
  94. package/dist/mail/conversation-map.d.ts.map +1 -0
  95. package/dist/mail/conversation-map.js +61 -0
  96. package/dist/mail/conversation-map.js.map +1 -0
  97. package/dist/mail/index.d.ts +11 -0
  98. package/dist/mail/index.d.ts.map +1 -0
  99. package/dist/mail/index.js +11 -0
  100. package/dist/mail/index.js.map +1 -0
  101. package/dist/mail/mail-service.d.ts +85 -0
  102. package/dist/mail/mail-service.d.ts.map +1 -0
  103. package/dist/mail/mail-service.js +121 -0
  104. package/dist/mail/mail-service.js.map +1 -0
  105. package/dist/mail/stores/eventstore-conversation-store.d.ts +40 -0
  106. package/dist/mail/stores/eventstore-conversation-store.d.ts.map +1 -0
  107. package/dist/mail/stores/eventstore-conversation-store.js +131 -0
  108. package/dist/mail/stores/eventstore-conversation-store.js.map +1 -0
  109. package/dist/mail/stores/eventstore-participant-store.d.ts +43 -0
  110. package/dist/mail/stores/eventstore-participant-store.d.ts.map +1 -0
  111. package/dist/mail/stores/eventstore-participant-store.js +145 -0
  112. package/dist/mail/stores/eventstore-participant-store.js.map +1 -0
  113. package/dist/mail/stores/eventstore-thread-store.d.ts +46 -0
  114. package/dist/mail/stores/eventstore-thread-store.d.ts.map +1 -0
  115. package/dist/mail/stores/eventstore-thread-store.js +118 -0
  116. package/dist/mail/stores/eventstore-thread-store.js.map +1 -0
  117. package/dist/mail/stores/eventstore-turn-store.d.ts +47 -0
  118. package/dist/mail/stores/eventstore-turn-store.d.ts.map +1 -0
  119. package/dist/mail/stores/eventstore-turn-store.js +153 -0
  120. package/dist/mail/stores/eventstore-turn-store.js.map +1 -0
  121. package/dist/mail/stores/index.d.ts +12 -0
  122. package/dist/mail/stores/index.d.ts.map +1 -0
  123. package/dist/mail/stores/index.js +12 -0
  124. package/dist/mail/stores/index.js.map +1 -0
  125. package/dist/mail/stores/types.d.ts +146 -0
  126. package/dist/mail/stores/types.d.ts.map +1 -0
  127. package/dist/mail/stores/types.js +13 -0
  128. package/dist/mail/stores/types.js.map +1 -0
  129. package/dist/mail/turn-recorder.d.ts +30 -0
  130. package/dist/mail/turn-recorder.d.ts.map +1 -0
  131. package/dist/mail/turn-recorder.js +98 -0
  132. package/dist/mail/turn-recorder.js.map +1 -0
  133. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  134. package/dist/map/adapter/acp-over-map.js +32 -2
  135. package/dist/map/adapter/acp-over-map.js.map +1 -1
  136. package/dist/map/adapter/event-translator.d.ts.map +1 -1
  137. package/dist/map/adapter/event-translator.js +4 -0
  138. package/dist/map/adapter/event-translator.js.map +1 -1
  139. package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
  140. package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
  141. package/dist/map/adapter/extensions/agent-detection.js +91 -0
  142. package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
  143. package/dist/map/adapter/extensions/index.d.ts +10 -1
  144. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  145. package/dist/map/adapter/extensions/index.js +39 -0
  146. package/dist/map/adapter/extensions/index.js.map +1 -1
  147. package/dist/map/adapter/extensions/resume.d.ts +47 -0
  148. package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
  149. package/dist/map/adapter/extensions/resume.js +59 -0
  150. package/dist/map/adapter/extensions/resume.js.map +1 -0
  151. package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
  152. package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
  153. package/dist/map/adapter/extensions/workspace-files.js +338 -0
  154. package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
  155. package/dist/map/adapter/mail-handler-adapter.d.ts +27 -0
  156. package/dist/map/adapter/mail-handler-adapter.d.ts.map +1 -0
  157. package/dist/map/adapter/mail-handler-adapter.js +292 -0
  158. package/dist/map/adapter/mail-handler-adapter.js.map +1 -0
  159. package/dist/map/adapter/map-adapter.d.ts +34 -10
  160. package/dist/map/adapter/map-adapter.d.ts.map +1 -1
  161. package/dist/map/adapter/map-adapter.js +110 -14
  162. package/dist/map/adapter/map-adapter.js.map +1 -1
  163. package/dist/map/adapter/rpc-handler.d.ts +4 -1
  164. package/dist/map/adapter/rpc-handler.d.ts.map +1 -1
  165. package/dist/map/adapter/rpc-handler.js +6 -0
  166. package/dist/map/adapter/rpc-handler.js.map +1 -1
  167. package/dist/map/index.d.ts +1 -0
  168. package/dist/map/index.d.ts.map +1 -1
  169. package/dist/map/index.js +2 -0
  170. package/dist/map/index.js.map +1 -1
  171. package/dist/map/types.d.ts +3 -1
  172. package/dist/map/types.d.ts.map +1 -1
  173. package/dist/map/types.js.map +1 -1
  174. package/dist/mcp/mcp-server.d.ts +6 -0
  175. package/dist/mcp/mcp-server.d.ts.map +1 -1
  176. package/dist/mcp/mcp-server.js +45 -0
  177. package/dist/mcp/mcp-server.js.map +1 -1
  178. package/dist/mcp/tools/claim_task.d.ts +35 -0
  179. package/dist/mcp/tools/claim_task.d.ts.map +1 -0
  180. package/dist/mcp/tools/claim_task.js +58 -0
  181. package/dist/mcp/tools/claim_task.js.map +1 -0
  182. package/dist/mcp/tools/done.d.ts +15 -2
  183. package/dist/mcp/tools/done.d.ts.map +1 -1
  184. package/dist/mcp/tools/done.js +45 -10
  185. package/dist/mcp/tools/done.js.map +1 -1
  186. package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
  187. package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
  188. package/dist/mcp/tools/list_claimable_tasks.js +63 -0
  189. package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
  190. package/dist/mcp/tools/unclaim_task.d.ts +31 -0
  191. package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
  192. package/dist/mcp/tools/unclaim_task.js +47 -0
  193. package/dist/mcp/tools/unclaim_task.js.map +1 -0
  194. package/dist/metrics/index.d.ts +2 -0
  195. package/dist/metrics/index.d.ts.map +1 -0
  196. package/dist/metrics/index.js +2 -0
  197. package/dist/metrics/index.js.map +1 -0
  198. package/dist/metrics/metrics.d.ts +79 -0
  199. package/dist/metrics/metrics.d.ts.map +1 -0
  200. package/dist/metrics/metrics.js +166 -0
  201. package/dist/metrics/metrics.js.map +1 -0
  202. package/dist/roles/capabilities.d.ts +1 -0
  203. package/dist/roles/capabilities.d.ts.map +1 -1
  204. package/dist/roles/capabilities.js +3 -0
  205. package/dist/roles/capabilities.js.map +1 -1
  206. package/dist/roles/types.d.ts +1 -1
  207. package/dist/roles/types.d.ts.map +1 -1
  208. package/dist/router/channels.d.ts +2 -4
  209. package/dist/router/channels.d.ts.map +1 -1
  210. package/dist/router/channels.js.map +1 -1
  211. package/dist/router/message-router.d.ts +85 -9
  212. package/dist/router/message-router.d.ts.map +1 -1
  213. package/dist/router/message-router.js +203 -14
  214. package/dist/router/message-router.js.map +1 -1
  215. package/dist/router/role-resolver.d.ts +10 -1
  216. package/dist/router/role-resolver.d.ts.map +1 -1
  217. package/dist/router/role-resolver.js +15 -1
  218. package/dist/router/role-resolver.js.map +1 -1
  219. package/dist/router/types.d.ts +30 -1
  220. package/dist/router/types.d.ts.map +1 -1
  221. package/dist/router/types.js.map +1 -1
  222. package/dist/server/combined-server.d.ts +6 -0
  223. package/dist/server/combined-server.d.ts.map +1 -1
  224. package/dist/server/combined-server.js +24 -2
  225. package/dist/server/combined-server.js.map +1 -1
  226. package/dist/store/event-store.d.ts +14 -1
  227. package/dist/store/event-store.d.ts.map +1 -1
  228. package/dist/store/event-store.js +456 -4
  229. package/dist/store/event-store.js.map +1 -1
  230. package/dist/store/types/agents.d.ts +1 -1
  231. package/dist/store/types/agents.d.ts.map +1 -1
  232. package/dist/store/types/conversations.d.ts +91 -0
  233. package/dist/store/types/conversations.d.ts.map +1 -0
  234. package/dist/store/types/conversations.js +8 -0
  235. package/dist/store/types/conversations.js.map +1 -0
  236. package/dist/store/types/events.d.ts +1 -1
  237. package/dist/store/types/events.d.ts.map +1 -1
  238. package/dist/store/types/events.js.map +1 -1
  239. package/dist/store/types/index.d.ts +2 -0
  240. package/dist/store/types/index.d.ts.map +1 -1
  241. package/dist/store/types/index.js +2 -0
  242. package/dist/store/types/index.js.map +1 -1
  243. package/dist/store/types/sessions.d.ts +44 -0
  244. package/dist/store/types/sessions.d.ts.map +1 -0
  245. package/dist/store/types/sessions.js +9 -0
  246. package/dist/store/types/sessions.js.map +1 -0
  247. package/dist/store/types/tasks.d.ts +2 -0
  248. package/dist/store/types/tasks.d.ts.map +1 -1
  249. package/dist/task/backend/memory.d.ts +4 -1
  250. package/dist/task/backend/memory.d.ts.map +1 -1
  251. package/dist/task/backend/memory.js +81 -0
  252. package/dist/task/backend/memory.js.map +1 -1
  253. package/dist/task/backend/types.d.ts +30 -0
  254. package/dist/task/backend/types.d.ts.map +1 -1
  255. package/dist/task/backend/types.js.map +1 -1
  256. package/dist/teams/index.d.ts +4 -0
  257. package/dist/teams/index.d.ts.map +1 -0
  258. package/dist/teams/index.js +4 -0
  259. package/dist/teams/index.js.map +1 -0
  260. package/dist/teams/team-loader.d.ts +20 -0
  261. package/dist/teams/team-loader.d.ts.map +1 -0
  262. package/dist/teams/team-loader.js +293 -0
  263. package/dist/teams/team-loader.js.map +1 -0
  264. package/dist/teams/team-runtime.d.ts +139 -0
  265. package/dist/teams/team-runtime.d.ts.map +1 -0
  266. package/dist/teams/team-runtime.js +613 -0
  267. package/dist/teams/team-runtime.js.map +1 -0
  268. package/dist/teams/types.d.ts +266 -0
  269. package/dist/teams/types.d.ts.map +1 -0
  270. package/dist/teams/types.js +20 -0
  271. package/dist/teams/types.js.map +1 -0
  272. package/dist/trigger/router/trigger-router.d.ts +30 -3
  273. package/dist/trigger/router/trigger-router.d.ts.map +1 -1
  274. package/dist/trigger/router/trigger-router.js +30 -3
  275. package/dist/trigger/router/trigger-router.js.map +1 -1
  276. package/dist/trigger/wake/types.d.ts +31 -5
  277. package/dist/trigger/wake/types.d.ts.map +1 -1
  278. package/dist/trigger/wake/types.js +19 -0
  279. package/dist/trigger/wake/types.js.map +1 -1
  280. package/dist/workspace/dataplane-adapter.d.ts +1 -1
  281. package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
  282. package/dist/workspace/dataplane-adapter.js +1 -1
  283. package/dist/workspace/dataplane-adapter.js.map +1 -1
  284. package/dist/workspace/index.d.ts +1 -1
  285. package/dist/workspace/index.d.ts.map +1 -1
  286. package/dist/workspace/strategies/index.d.ts +6 -0
  287. package/dist/workspace/strategies/index.d.ts.map +1 -0
  288. package/dist/workspace/strategies/index.js +5 -0
  289. package/dist/workspace/strategies/index.js.map +1 -0
  290. package/dist/workspace/strategies/optimistic.d.ts +26 -0
  291. package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
  292. package/dist/workspace/strategies/optimistic.js +121 -0
  293. package/dist/workspace/strategies/optimistic.js.map +1 -0
  294. package/dist/workspace/strategies/queue.d.ts +26 -0
  295. package/dist/workspace/strategies/queue.d.ts.map +1 -0
  296. package/dist/workspace/strategies/queue.js +67 -0
  297. package/dist/workspace/strategies/queue.js.map +1 -0
  298. package/dist/workspace/strategies/registry.d.ts +37 -0
  299. package/dist/workspace/strategies/registry.d.ts.map +1 -0
  300. package/dist/workspace/strategies/registry.js +63 -0
  301. package/dist/workspace/strategies/registry.js.map +1 -0
  302. package/dist/workspace/strategies/trunk.d.ts +20 -0
  303. package/dist/workspace/strategies/trunk.d.ts.map +1 -0
  304. package/dist/workspace/strategies/trunk.js +108 -0
  305. package/dist/workspace/strategies/trunk.js.map +1 -0
  306. package/dist/workspace/strategies/types.d.ts +104 -0
  307. package/dist/workspace/strategies/types.d.ts.map +1 -0
  308. package/dist/workspace/strategies/types.js +11 -0
  309. package/dist/workspace/strategies/types.js.map +1 -0
  310. package/dist/workspace/types.d.ts +1 -1
  311. package/dist/workspace/types.d.ts.map +1 -1
  312. package/dist/workspace/workspace-manager.d.ts +1 -1
  313. package/dist/workspace/workspace-manager.d.ts.map +1 -1
  314. package/docs/implementation-details.md +1127 -0
  315. package/docs/implementation-summary.md +448 -0
  316. package/docs/mail-integration.md +608 -0
  317. package/docs/plan-self-driving-support.md +433 -0
  318. package/docs/spec-self-driving-support.md +462 -0
  319. package/docs/team-templates.md +860 -0
  320. package/docs/teams.md +233 -0
  321. package/package.json +5 -3
  322. package/src/acp/__tests__/integration.test.ts +161 -1
  323. package/src/acp/__tests__/macro-agent.test.ts +95 -0
  324. package/src/acp/__tests__/session-persistence.test.ts +276 -0
  325. package/src/acp/macro-agent.ts +79 -7
  326. package/src/acp/session-mapper.ts +108 -1
  327. package/src/acp/types.ts +33 -1
  328. package/src/agent/agent-manager.ts +278 -6
  329. package/src/agent/types.ts +27 -0
  330. package/src/agent/wake.ts +15 -0
  331. package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
  332. package/src/agent-detection/__tests__/detector.test.ts +768 -0
  333. package/src/agent-detection/__tests__/registry.test.ts +254 -0
  334. package/src/agent-detection/command-builder.ts +90 -0
  335. package/src/agent-detection/detector.ts +307 -0
  336. package/src/agent-detection/index.ts +36 -0
  337. package/src/agent-detection/registry.ts +200 -0
  338. package/src/agent-detection/types.ts +184 -0
  339. package/src/api/__tests__/conversation-api.test.ts +468 -0
  340. package/src/api/server.ts +425 -1
  341. package/src/api/types.ts +64 -1
  342. package/src/cli/acp.ts +9 -1
  343. package/src/cli/index.ts +44 -0
  344. package/src/cli/mcp.ts +47 -0
  345. package/src/config/index.ts +9 -0
  346. package/src/config/project-config.ts +107 -0
  347. package/src/lifecycle/cascade.ts +1 -1
  348. package/src/lifecycle/handlers/index.ts +8 -0
  349. package/src/lifecycle/handlers/worker.ts +48 -3
  350. package/src/mail/__tests__/conversation-lifecycle.test.ts +409 -0
  351. package/src/mail/__tests__/eventstore-stores.test.ts +1073 -0
  352. package/src/mail/__tests__/mail-full-agent.e2e.test.ts +575 -0
  353. package/src/mail/__tests__/mail-integration.test.ts +759 -0
  354. package/src/mail/__tests__/mail-map-protocol.e2e.test.ts +1068 -0
  355. package/src/mail/__tests__/mail-service.test.ts +506 -0
  356. package/src/mail/__tests__/turn-recorder.test.ts +328 -0
  357. package/src/mail/conversation-map.ts +107 -0
  358. package/src/mail/index.ts +25 -0
  359. package/src/mail/mail-service.ts +257 -0
  360. package/src/mail/stores/eventstore-conversation-store.ts +146 -0
  361. package/src/mail/stores/eventstore-participant-store.ts +172 -0
  362. package/src/mail/stores/eventstore-thread-store.ts +129 -0
  363. package/src/mail/stores/eventstore-turn-store.ts +173 -0
  364. package/src/mail/stores/index.ts +12 -0
  365. package/src/mail/stores/types.ts +160 -0
  366. package/src/mail/turn-recorder.ts +124 -0
  367. package/src/map/README.md +79 -0
  368. package/src/map/adapter/__tests__/extensions.test.ts +359 -0
  369. package/src/map/adapter/__tests__/map-adapter.test.ts +90 -0
  370. package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
  371. package/src/map/adapter/acp-over-map.ts +45 -2
  372. package/src/map/adapter/event-translator.ts +4 -0
  373. package/src/map/adapter/extensions/agent-detection.ts +201 -0
  374. package/src/map/adapter/extensions/index.ts +63 -0
  375. package/src/map/adapter/extensions/resume.ts +114 -0
  376. package/src/map/adapter/extensions/workspace-files.ts +449 -0
  377. package/src/map/adapter/mail-handler-adapter.ts +429 -0
  378. package/src/map/adapter/map-adapter.ts +173 -27
  379. package/src/map/adapter/rpc-handler.ts +8 -1
  380. package/src/map/index.ts +3 -0
  381. package/src/map/types.ts +3 -1
  382. package/src/mcp/mcp-server.ts +67 -0
  383. package/src/mcp/tools/claim_task.ts +86 -0
  384. package/src/mcp/tools/done.ts +59 -10
  385. package/src/mcp/tools/list_claimable_tasks.ts +93 -0
  386. package/src/mcp/tools/unclaim_task.ts +71 -0
  387. package/src/metrics/index.ts +9 -0
  388. package/src/metrics/metrics.ts +280 -0
  389. package/src/roles/capabilities.ts +3 -0
  390. package/src/roles/types.ts +2 -1
  391. package/src/router/README.md +120 -0
  392. package/src/router/__tests__/message-router.test.ts +561 -0
  393. package/src/router/channels.ts +3 -4
  394. package/src/router/message-router.ts +308 -22
  395. package/src/router/role-resolver.ts +22 -1
  396. package/src/router/types.ts +36 -1
  397. package/src/server/combined-server.ts +36 -2
  398. package/src/store/README.md +134 -0
  399. package/src/store/event-store.ts +546 -3
  400. package/src/store/types/agents.ts +1 -1
  401. package/src/store/types/conversations.ts +129 -0
  402. package/src/store/types/events.ts +5 -1
  403. package/src/store/types/index.ts +2 -0
  404. package/src/store/types/sessions.ts +53 -0
  405. package/src/store/types/tasks.ts +3 -0
  406. package/src/task/backend/memory.ts +116 -0
  407. package/src/task/backend/types.ts +43 -0
  408. package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
  409. package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
  410. package/src/teams/__tests__/team-system.test.ts +1280 -0
  411. package/src/teams/index.ts +13 -0
  412. package/src/teams/team-loader.ts +434 -0
  413. package/src/teams/team-runtime.ts +727 -0
  414. package/src/teams/types.ts +377 -0
  415. package/src/trigger/router/trigger-router.ts +30 -3
  416. package/src/trigger/wake/types.ts +32 -5
  417. package/src/trigger/wake/wake-manager.ts +2 -2
  418. package/src/workspace/dataplane-adapter.ts +1 -1
  419. package/src/workspace/index.ts +1 -1
  420. package/src/workspace/strategies/index.ts +18 -0
  421. package/src/workspace/strategies/optimistic.ts +136 -0
  422. package/src/workspace/strategies/queue.ts +81 -0
  423. package/src/workspace/strategies/registry.ts +89 -0
  424. package/src/workspace/strategies/trunk.ts +123 -0
  425. package/src/workspace/strategies/types.ts +145 -0
  426. package/src/workspace/types.ts +1 -1
  427. package/src/workspace/workspace-manager.ts +1 -1
  428. package/.claude/settings.local.json +0 -59
  429. package/dist/map/utils/address-translation.d.ts +0 -99
  430. package/dist/map/utils/address-translation.d.ts.map +0 -1
  431. package/dist/map/utils/address-translation.js +0 -285
  432. package/dist/map/utils/address-translation.js.map +0 -1
  433. package/dist/map/utils/index.d.ts +0 -7
  434. package/dist/map/utils/index.d.ts.map +0 -1
  435. package/dist/map/utils/index.js +0 -7
  436. package/dist/map/utils/index.js.map +0 -1
  437. package/openspec/AGENTS.md +0 -456
  438. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/design.md +0 -128
  439. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/proposal.md +0 -49
  440. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/agent-manager/spec.md +0 -150
  441. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/cli-api/spec.md +0 -258
  442. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/event-store/spec.md +0 -160
  443. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/mcp-tools/spec.md +0 -224
  444. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/message-router/spec.md +0 -153
  445. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/specs/task-manager/spec.md +0 -136
  446. package/openspec/changes/archive/2025-12-21-add-mvp-foundation/tasks.md +0 -147
  447. package/openspec/project.md +0 -31
  448. package/openspec/specs/agent-manager/spec.md +0 -154
  449. package/openspec/specs/cli-api/spec.md +0 -262
  450. package/openspec/specs/event-store/spec.md +0 -164
  451. package/openspec/specs/mcp-tools/spec.md +0 -228
  452. package/openspec/specs/message-router/spec.md +0 -157
  453. package/openspec/specs/task-manager/spec.md +0 -140
  454. package/references/acp-factory-ref/CHANGELOG.md +0 -33
  455. package/references/acp-factory-ref/LICENSE +0 -21
  456. package/references/acp-factory-ref/README.md +0 -341
  457. package/references/acp-factory-ref/package-lock.json +0 -3102
  458. package/references/acp-factory-ref/package.json +0 -96
  459. package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
  460. package/references/acp-factory-ref/python/LICENSE +0 -21
  461. package/references/acp-factory-ref/python/Makefile +0 -57
  462. package/references/acp-factory-ref/python/README.md +0 -253
  463. package/references/acp-factory-ref/python/pyproject.toml +0 -73
  464. package/references/acp-factory-ref/python/tests/__init__.py +0 -0
  465. package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
  466. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
  467. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
  468. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
  469. package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
  470. package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
  471. package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
  472. package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
  473. package/references/claude-code-acp/.prettierrc.json +0 -4
  474. package/references/claude-code-acp/CHANGELOG.md +0 -249
  475. package/references/claude-code-acp/LICENSE +0 -222
  476. package/references/claude-code-acp/README.md +0 -53
  477. package/references/claude-code-acp/docs/RELEASES.md +0 -24
  478. package/references/claude-code-acp/eslint.config.js +0 -48
  479. package/references/claude-code-acp/package-lock.json +0 -4570
  480. package/references/claude-code-acp/package.json +0 -88
  481. package/references/claude-code-acp/scripts/release.sh +0 -119
  482. package/references/claude-code-acp/src/acp-agent.ts +0 -2065
  483. package/references/claude-code-acp/src/index.ts +0 -26
  484. package/references/claude-code-acp/src/lib.ts +0 -38
  485. package/references/claude-code-acp/src/mcp-server.ts +0 -911
  486. package/references/claude-code-acp/src/settings.ts +0 -522
  487. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
  488. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
  489. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
  490. package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
  491. package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
  492. package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
  493. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
  494. package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
  495. package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
  496. package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
  497. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
  498. package/references/claude-code-acp/src/tools.ts +0 -819
  499. package/references/claude-code-acp/src/utils.ts +0 -171
  500. package/references/claude-code-acp/tsconfig.json +0 -18
  501. package/references/claude-code-acp/vitest.config.ts +0 -19
  502. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -82
  503. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -9
  504. package/references/multi-agent-protocol/LICENSE +0 -21
  505. package/references/multi-agent-protocol/README.md +0 -113
  506. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -460
  507. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  508. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  509. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  510. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  511. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  512. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  513. package/references/multi-agent-protocol/docs/07-federation.md +0 -259
  514. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  515. package/references/multi-agent-protocol/package-lock.json +0 -3239
  516. package/references/multi-agent-protocol/package.json +0 -56
  517. package/references/multi-agent-protocol/schema/meta.json +0 -337
  518. package/references/multi-agent-protocol/schema/schema.json +0 -1828
package/docs/teams.md ADDED
@@ -0,0 +1,233 @@
1
+ # Team Templates
2
+
3
+ Team templates define reusable multi-agent configurations that can be loaded and bootstrapped by the TeamRuntime. Templates live in `.macro-agent/teams/<name>/` directories.
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ .macro-agent/teams/<name>/
9
+ ├── team.yaml # Main manifest (required)
10
+ ├── roles/
11
+ │ ├── <role>.yaml # Custom role definitions
12
+ │ └── ...
13
+ └── prompts/
14
+ ├── <role>.md # System prompts for each role
15
+ └── ...
16
+ ```
17
+
18
+ ## Schema Reference
19
+
20
+ ### team.yaml
21
+
22
+ ```yaml
23
+ name: string # Team identifier (matches directory name)
24
+ description: string # Human-readable description
25
+ version: 1 # Schema version (currently 1)
26
+
27
+ roles: # List of role names used by this team
28
+ - <role_name>
29
+
30
+ topology: # Agent spawn structure
31
+ root: # Initial agent (always spawned first)
32
+ role: string # Role name from roles list
33
+ prompt: string # Relative path to prompt file
34
+ config:
35
+ model: string # Model to use (sonnet, haiku, opus)
36
+
37
+ companions: # Peer agents (spawned alongside root, not as children)
38
+ - role: string
39
+ prompt: string
40
+ config:
41
+ model: string
42
+
43
+ spawn_rules: # Which roles can spawn which other roles
44
+ <role>: [<role>, ...]
45
+
46
+ communication: # Signal routing configuration
47
+ channels: # Named signal groups
48
+ <channel_name>:
49
+ description: string
50
+ signals: [string, ...]
51
+
52
+ subscriptions: # Which signals each role receives
53
+ <role>:
54
+ - channel: string
55
+ signals: [string, ...] # Optional; omit for all signals
56
+
57
+ emissions: # Which signals each role can emit
58
+ <role>: [string, ...]
59
+
60
+ routing:
61
+ status: upstream # Status events flow to parent
62
+ peers: # Direct peer-to-peer routes
63
+ - from: string
64
+ to: string
65
+ via: direct
66
+ signals: [string, ...]
67
+
68
+ enforcement: permissive | strict | audit
69
+
70
+ macro_agent: # Runtime behavior configuration
71
+ task_assignment:
72
+ mode: push | pull
73
+ pull: # Only for pull mode
74
+ idle_timeout_s: number
75
+ claim_retry_delay_ms: number
76
+ max_concurrent_per_agent: number
77
+
78
+ integration:
79
+ strategy: queue | trunk | optimistic
80
+ config: # Strategy-specific options
81
+ max_retries: number # trunk/optimistic: retry count
82
+ conflict_action: string # trunk: abandon|rebase
83
+ require_review: boolean # queue: gate on review
84
+
85
+ lifecycle:
86
+ continuations:
87
+ enabled: boolean
88
+ max_history_messages: number
89
+ checkpoint_interval: round_trip | none
90
+ scaling:
91
+ min_workers: number
92
+ max_workers: number
93
+ scale_on: task_queue_depth | manual
94
+ idle_drain: boolean
95
+
96
+ observability:
97
+ metrics_window_s: number
98
+ snapshot_interval_s: number
99
+ ```
100
+
101
+ ### Role Definitions (roles/*.yaml)
102
+
103
+ ```yaml
104
+ name: string # Role identifier
105
+ extends: string # Base role: worker, coordinator, monitor, integrator
106
+ display_name: string # Human-readable name
107
+ description: string
108
+
109
+ # Capability modification (pick one approach)
110
+ capabilities: [string] # Full replacement of base capabilities
111
+ capabilities_add: [string] # Add to base capabilities
112
+ capabilities_remove: [string] # Remove from base capabilities
113
+
114
+ prompt: string # Relative path to prompt file
115
+
116
+ macro_agent:
117
+ workspace:
118
+ type: own | shared | none
119
+ branch_pattern: string # Pattern with {agent-id} placeholder
120
+ cleanup_on_terminate: boolean
121
+ lifecycle:
122
+ type: ephemeral | persistent | daemon | event-driven
123
+ cascade_terminate: boolean
124
+ self_cleanup: boolean
125
+ task_bound: boolean
126
+ parent_bound: boolean
127
+ max_duration_ms: number
128
+ ```
129
+
130
+ ## Task Assignment Modes
131
+
132
+ ### Push Mode
133
+
134
+ The coordinator creates tasks and explicitly assigns them to spawned agents. This is the traditional hierarchical model.
135
+
136
+ - Coordinator spawns workers and assigns tasks via `assign_task`
137
+ - Workers execute their assigned task and call `done()`
138
+ - Workers terminate after task completion
139
+
140
+ ### Pull Mode
141
+
142
+ Agents autonomously claim tasks from a shared pool. Best for large, parallelizable workloads.
143
+
144
+ - A planner role creates and prioritizes tasks
145
+ - Worker agents call `claim_task` to pick up work
146
+ - After completing a task, workers claim the next available one
147
+ - Workers that find no tasks wait with configurable idle timeout
148
+
149
+ ## Integration Strategies
150
+
151
+ ### Queue (default)
152
+
153
+ Changes flow through a merge queue managed by an integrator agent. Provides the highest safety with review gates.
154
+
155
+ ### Trunk
156
+
157
+ Workers push directly to the main branch with automatic rebase-and-retry. Fast but requires good test coverage.
158
+
159
+ Configuration:
160
+ - `max_retries`: Number of rebase attempts (default: 3)
161
+ - `conflict_action`: What to do on persistent conflict (`abandon` or `rebase`)
162
+
163
+ ### Optimistic
164
+
165
+ Like trunk, but emits a validation event after push for async verification. Useful when builds are slow.
166
+
167
+ ## Reference Templates
168
+
169
+ ### self-driving
170
+
171
+ Autonomous development with continuous planning. Uses pull-mode task assignment and trunk integration.
172
+
173
+ | Role | Base | Purpose |
174
+ |------|------|---------|
175
+ | planner | coordinator | Explores codebase, creates and prioritizes tasks |
176
+ | grinder | worker | Claims and executes tasks autonomously |
177
+ | judge | monitor | Monitors codebase health, creates fixup tasks |
178
+
179
+ ### structured
180
+
181
+ Hierarchical development with explicit assignment. Uses push-mode task assignment and merge queue.
182
+
183
+ | Role | Base | Purpose |
184
+ |------|------|---------|
185
+ | lead | coordinator | Decomposes work and assigns tasks to developers |
186
+ | developer | worker | Executes assigned tasks in isolated workspaces |
187
+ | reviewer | monitor | Reviews merge requests before they land |
188
+
189
+ ## Creating a Custom Team
190
+
191
+ 1. Create directory: `.macro-agent/teams/my-team/`
192
+ 2. Write `team.yaml` with your manifest
193
+ 3. Define custom roles in `roles/`
194
+ 4. Write system prompts in `prompts/`
195
+ 5. Load with: `TeamLoader.load("my-team")`
196
+
197
+ ### Example: Minimal Custom Team
198
+
199
+ ```yaml
200
+ name: my-team
201
+ description: "Simple worker team"
202
+ version: 1
203
+ roles: [lead, dev]
204
+
205
+ topology:
206
+ root:
207
+ role: lead
208
+ prompt: prompts/lead.md
209
+ spawn_rules:
210
+ lead: [dev]
211
+ dev: []
212
+
213
+ communication:
214
+ channels:
215
+ work:
216
+ signals: [TASK_ASSIGNED, TASK_COMPLETED]
217
+ subscriptions:
218
+ lead:
219
+ - channel: work
220
+ dev:
221
+ - channel: work
222
+ signals: [TASK_ASSIGNED]
223
+ emissions:
224
+ lead: [TASK_ASSIGNED]
225
+ dev: [TASK_COMPLETED]
226
+ enforcement: permissive
227
+
228
+ macro_agent:
229
+ task_assignment:
230
+ mode: push
231
+ integration:
232
+ strategy: queue
233
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "macro-agent",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Interact with multiple agents as if they were a single agent.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,6 +39,7 @@
39
39
  "@sudocode-ai/types": "^0.1.19",
40
40
  "@types/better-sqlite3": "^7.6.13",
41
41
  "@types/express": "^5.0.6",
42
+ "@types/js-yaml": "^4.0.9",
42
43
  "@types/node": "^20.10.0",
43
44
  "@types/supertest": "^6.0.3",
44
45
  "@types/ws": "^8.18.1",
@@ -48,14 +49,15 @@
48
49
  },
49
50
  "dependencies": {
50
51
  "@modelcontextprotocol/sdk": "^1.25.1",
51
- "@multi-agent-protocol/sdk": "^0.0.7",
52
+ "@multi-agent-protocol/sdk": "^0.0.8",
52
53
  "@sudocode-ai/claude-code-acp": "^0.13.8",
53
54
  "acp-factory": "^0.1.9",
54
55
  "better-sqlite3": "^12.5.0",
55
56
  "chalk": "^5.6.2",
56
57
  "commander": "^14.0.2",
57
- "dataplane": "^0.1.3",
58
+ "git-cascade": "0.0.1",
58
59
  "express": "^5.2.1",
60
+ "js-yaml": "^4.1.1",
59
61
  "nanoid": "^5.0.0",
60
62
  "tinybase": "^5.0.0",
61
63
  "ulid": "^3.0.2",
@@ -290,6 +290,43 @@ describe("ACP Mode Integration", () => {
290
290
  expect(loadResponse).toEqual({});
291
291
  });
292
292
 
293
+ it("should load session by agentId via _meta", async () => {
294
+ // Create a session first
295
+ const newResponse = await macroAgent.newSession({
296
+ cwd: "/test/project",
297
+ });
298
+
299
+ const originalSessionId = newResponse.sessionId;
300
+ const originalAgentId = macroAgent.getMappedAgentId(originalSessionId);
301
+
302
+ // Create a new MacroAgent instance (simulating reconnect)
303
+ const newMacroAgent = new MacroAgent(mockConnection, {
304
+ agentManager: mockAgentManager,
305
+ eventStore: mockEventStore,
306
+ taskManager: mockTaskManager,
307
+ defaultCwd: "/test/integration",
308
+ });
309
+
310
+ // Load using _meta.agentId — the server resolves agentId to session_id
311
+ const loadResponse = await newMacroAgent.loadSession({
312
+ sessionId: "_resume_",
313
+ cwd: "/test/project",
314
+ _meta: { agentId: originalAgentId },
315
+ } as any);
316
+
317
+ expect(loadResponse).toEqual({});
318
+ });
319
+
320
+ it("should throw when _meta.agentId references non-existent agent", async () => {
321
+ await expect(
322
+ macroAgent.loadSession({
323
+ sessionId: "_resume_",
324
+ cwd: "/test/project",
325
+ _meta: { agentId: "non-existent-agent" },
326
+ } as any)
327
+ ).rejects.toThrow("Agent not found: non-existent-agent");
328
+ });
329
+
293
330
  it("should handle authenticate (no-op)", async () => {
294
331
  const response = await macroAgent.authenticate({
295
332
  methodId: "none",
@@ -334,7 +371,8 @@ describe("ACP Mode Integration", () => {
334
371
  expect(extensions).toContain("_macro/checkCapability");
335
372
  expect(extensions).toContain("_macro/respondToPermission");
336
373
  expect(extensions).toContain("_macro/cancelPermission");
337
- expect(extensions?.length).toBe(15);
374
+ expect(extensions).toContain("_macro/resume");
375
+ expect(extensions?.length).toBe(16);
338
376
 
339
377
  expect(initResponse.agentCapabilities?._meta?.agentType).toBe(
340
378
  "macro-agent"
@@ -860,4 +898,126 @@ describe("ACP Protocol Compliance", () => {
860
898
  const extensions = initResponse.agentCapabilities?._meta?.extensions;
861
899
  expect(extensions?.every((e: string) => e.startsWith("_"))).toBe(true);
862
900
  });
901
+
902
+ // ─────────────────────────────────────────────────────────────────
903
+ // Agent Resume Flow Integration Tests
904
+ // ─────────────────────────────────────────────────────────────────
905
+
906
+ describe("Extension: _macro/resume", () => {
907
+ it("should resume a stopped sub-agent via head manager", async () => {
908
+ // 1. Create session (head manager)
909
+ await macroAgent.newSession({ cwd: "/test/project" });
910
+
911
+ // 2. Spawn a sub-agent
912
+ const spawnResponse = await macroAgent.extMethod("macro/spawnAgent", {
913
+ task_description: "Worker agent to be resumed",
914
+ });
915
+ const childAgentId = spawnResponse.agentId as string;
916
+
917
+ // 3. Simulate agent being stopped (update store state)
918
+ const childAgent = agentStore.get(childAgentId)!;
919
+ childAgent.state = "stopped";
920
+ agentStore.set(childAgentId, childAgent);
921
+
922
+ // 4. Resume via _macro/resume extension
923
+ const resumeResponse = await macroAgent.extMethod("_macro/resume", {
924
+ agentId: childAgentId,
925
+ });
926
+
927
+ expect(resumeResponse.success).toBe(true);
928
+ expect(resumeResponse.agentId).toBe(childAgentId);
929
+ expect(resumeResponse.sessionId).toBeDefined();
930
+
931
+ // 5. Verify agentManager.resume was called with correct ID
932
+ expect(mockAgentManager.resume).toHaveBeenCalledWith(childAgentId);
933
+ });
934
+
935
+ it("should resume a failed sub-agent", async () => {
936
+ await macroAgent.newSession({ cwd: "/test/project" });
937
+
938
+ const spawnResponse = await macroAgent.extMethod("macro/spawnAgent", {
939
+ task_description: "Agent that failed",
940
+ });
941
+ const childAgentId = spawnResponse.agentId as string;
942
+
943
+ // Simulate failed state
944
+ const childAgent = agentStore.get(childAgentId)!;
945
+ childAgent.state = "failed";
946
+ agentStore.set(childAgentId, childAgent);
947
+
948
+ const resumeResponse = await macroAgent.extMethod("_macro/resume", {
949
+ agentId: childAgentId,
950
+ });
951
+
952
+ expect(resumeResponse.success).toBe(true);
953
+ expect(mockAgentManager.resume).toHaveBeenCalledWith(childAgentId);
954
+ });
955
+
956
+ it("should reject resuming a running agent", async () => {
957
+ await macroAgent.newSession({ cwd: "/test/project" });
958
+
959
+ // Spawn returns a running agent
960
+ const spawnResponse = await macroAgent.extMethod("macro/spawnAgent", {
961
+ task_description: "Running agent",
962
+ });
963
+ const childAgentId = spawnResponse.agentId as string;
964
+
965
+ // Agent is running — resume should fail
966
+ await expect(
967
+ macroAgent.extMethod("_macro/resume", {
968
+ agentId: childAgentId,
969
+ })
970
+ ).rejects.toThrow("only stopped or failed");
971
+ });
972
+
973
+ it("should reject resuming a non-existent agent", async () => {
974
+ await expect(
975
+ macroAgent.extMethod("_macro/resume", {
976
+ agentId: "non-existent-agent",
977
+ })
978
+ ).rejects.toThrow("Agent not found");
979
+ });
980
+
981
+ it("should reject resume without agentId", async () => {
982
+ await expect(
983
+ macroAgent.extMethod("_macro/resume", {})
984
+ ).rejects.toThrow("agentId is required");
985
+ });
986
+
987
+ it("full lifecycle: spawn → stop → resume", async () => {
988
+ // Initialize and create session
989
+ await macroAgent.initialize({
990
+ protocolVersion: 1,
991
+ clientCapabilities: {},
992
+ });
993
+ await macroAgent.newSession({ cwd: "/test/project" });
994
+
995
+ // Spawn sub-agent
996
+ const spawnResponse = await macroAgent.extMethod("macro/spawnAgent", {
997
+ task_description: "Full lifecycle test agent",
998
+ options: { cwd: "/test/spawn" },
999
+ });
1000
+ const agentId = spawnResponse.agentId as string;
1001
+ const sessionId = spawnResponse.sessionId as string;
1002
+
1003
+ // Verify agent is running
1004
+ const runningAgent = agentStore.get(agentId)!;
1005
+ expect(runningAgent.state).toBe("running");
1006
+ expect(runningAgent.session_id).toBe(sessionId);
1007
+
1008
+ // Simulate stop
1009
+ runningAgent.state = "stopped";
1010
+ agentStore.set(agentId, runningAgent);
1011
+
1012
+ // Resume
1013
+ const resumeResponse = await macroAgent.extMethod("_macro/resume", {
1014
+ agentId,
1015
+ });
1016
+
1017
+ expect(resumeResponse.success).toBe(true);
1018
+ expect(resumeResponse.agentId).toBe(agentId);
1019
+ // Session ID is preserved from the mock's resume implementation
1020
+ expect(resumeResponse.sessionId).toBe(sessionId);
1021
+ });
1022
+ });
863
1023
  });
@@ -154,6 +154,9 @@ describe("MacroAgent", () => {
154
154
  expect(response.agentCapabilities?._meta?.extensions).toContain(
155
155
  "_macro/spawnAgent"
156
156
  );
157
+ expect(response.agentCapabilities?._meta?.extensions).toContain(
158
+ "_macro/resume"
159
+ );
157
160
  expect(response.agentCapabilities?._meta?.agentType).toBe("macro-agent");
158
161
  });
159
162
 
@@ -870,6 +873,98 @@ describe("MacroAgent", () => {
870
873
  });
871
874
  });
872
875
 
876
+ // ─────────────────────────────────────────────────────────────────
877
+ // _macro/resume Tests
878
+ // ─────────────────────────────────────────────────────────────────
879
+
880
+ describe("_macro/resume", () => {
881
+ it("should resume a stopped agent", async () => {
882
+ const stoppedAgent = createMockAgent({
883
+ id: "agent-stopped",
884
+ state: "stopped",
885
+ session_id: "session-stopped",
886
+ });
887
+ vi.mocked(mockEventStore.getAgent).mockReturnValue(stoppedAgent);
888
+ vi.mocked(mockAgentManager.resume).mockResolvedValue({
889
+ id: "agent-stopped",
890
+ session_id: "session-stopped",
891
+ agent: stoppedAgent,
892
+ session: {},
893
+ } as any);
894
+
895
+ const result = await macroAgent.extMethod("_macro/resume", {
896
+ agentId: "agent-stopped",
897
+ });
898
+
899
+ expect(mockAgentManager.resume).toHaveBeenCalledWith("agent-stopped");
900
+ expect(result).toEqual({
901
+ success: true,
902
+ agentId: "agent-stopped",
903
+ sessionId: "session-stopped",
904
+ });
905
+ });
906
+
907
+ it("should resume a failed agent", async () => {
908
+ const failedAgent = createMockAgent({
909
+ id: "agent-failed",
910
+ state: "failed",
911
+ session_id: "session-failed",
912
+ });
913
+ vi.mocked(mockEventStore.getAgent).mockReturnValue(failedAgent);
914
+ vi.mocked(mockAgentManager.resume).mockResolvedValue({
915
+ id: "agent-failed",
916
+ session_id: "session-failed",
917
+ agent: failedAgent,
918
+ session: {},
919
+ } as any);
920
+
921
+ const result = await macroAgent.extMethod("_macro/resume", {
922
+ agentId: "agent-failed",
923
+ });
924
+
925
+ expect(mockAgentManager.resume).toHaveBeenCalledWith("agent-failed");
926
+ expect(result).toHaveProperty("success", true);
927
+ });
928
+
929
+ it("should throw for missing agentId", async () => {
930
+ await expect(
931
+ macroAgent.extMethod("_macro/resume", {})
932
+ ).rejects.toThrow("agentId is required");
933
+ });
934
+
935
+ it("should throw for non-existent agent", async () => {
936
+ vi.mocked(mockEventStore.getAgent).mockReturnValue(undefined as any);
937
+
938
+ await expect(
939
+ macroAgent.extMethod("_macro/resume", { agentId: "missing" })
940
+ ).rejects.toThrow("Agent not found");
941
+ });
942
+
943
+ it("should throw for running agent", async () => {
944
+ const runningAgent = createMockAgent({
945
+ id: "agent-running",
946
+ state: "running",
947
+ });
948
+ vi.mocked(mockEventStore.getAgent).mockReturnValue(runningAgent);
949
+
950
+ await expect(
951
+ macroAgent.extMethod("_macro/resume", { agentId: "agent-running" })
952
+ ).rejects.toThrow("only stopped or failed");
953
+ });
954
+
955
+ it("should throw for sleeping agent", async () => {
956
+ const sleepingAgent = createMockAgent({
957
+ id: "agent-sleeping",
958
+ state: "sleeping",
959
+ });
960
+ vi.mocked(mockEventStore.getAgent).mockReturnValue(sleepingAgent);
961
+
962
+ await expect(
963
+ macroAgent.extMethod("_macro/resume", { agentId: "agent-sleeping" })
964
+ ).rejects.toThrow("only stopped or failed");
965
+ });
966
+ });
967
+
873
968
  // ─────────────────────────────────────────────────────────────────
874
969
  // Cancel Tests
875
970
  // ─────────────────────────────────────────────────────────────────