macro-agent 0.0.11 → 0.0.13

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 (408) 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 +6 -0
  16. package/.sudocode/specs.jsonl +7 -0
  17. package/CLAUDE.md +110 -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 +25 -1
  31. package/dist/agent/agent-manager.d.ts.map +1 -1
  32. package/dist/agent/agent-manager.js +93 -7
  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-detection/command-builder.d.ts +30 -0
  38. package/dist/agent-detection/command-builder.d.ts.map +1 -0
  39. package/dist/agent-detection/command-builder.js +71 -0
  40. package/dist/agent-detection/command-builder.js.map +1 -0
  41. package/dist/agent-detection/detector.d.ts +84 -0
  42. package/dist/agent-detection/detector.d.ts.map +1 -0
  43. package/dist/agent-detection/detector.js +240 -0
  44. package/dist/agent-detection/detector.js.map +1 -0
  45. package/dist/agent-detection/index.d.ts +12 -0
  46. package/dist/agent-detection/index.d.ts.map +1 -0
  47. package/dist/agent-detection/index.js +14 -0
  48. package/dist/agent-detection/index.js.map +1 -0
  49. package/dist/agent-detection/registry.d.ts +53 -0
  50. package/dist/agent-detection/registry.d.ts.map +1 -0
  51. package/dist/agent-detection/registry.js +177 -0
  52. package/dist/agent-detection/registry.js.map +1 -0
  53. package/dist/agent-detection/types.d.ts +121 -0
  54. package/dist/agent-detection/types.d.ts.map +1 -0
  55. package/dist/agent-detection/types.js +20 -0
  56. package/dist/agent-detection/types.js.map +1 -0
  57. package/dist/api/server.d.ts.map +1 -1
  58. package/dist/api/server.js +95 -0
  59. package/dist/api/server.js.map +1 -1
  60. package/dist/cli/index.js +29 -0
  61. package/dist/cli/index.js.map +1 -1
  62. package/dist/cli/mcp.js +38 -0
  63. package/dist/cli/mcp.js.map +1 -1
  64. package/dist/config/index.d.ts +2 -0
  65. package/dist/config/index.d.ts.map +1 -0
  66. package/dist/config/index.js +2 -0
  67. package/dist/config/index.js.map +1 -0
  68. package/dist/config/project-config.d.ts +46 -0
  69. package/dist/config/project-config.d.ts.map +1 -0
  70. package/dist/config/project-config.js +68 -0
  71. package/dist/config/project-config.js.map +1 -0
  72. package/dist/lifecycle/cascade.d.ts +1 -1
  73. package/dist/lifecycle/cascade.d.ts.map +1 -1
  74. package/dist/lifecycle/handlers/index.d.ts +4 -0
  75. package/dist/lifecycle/handlers/index.d.ts.map +1 -1
  76. package/dist/lifecycle/handlers/index.js +2 -0
  77. package/dist/lifecycle/handlers/index.js.map +1 -1
  78. package/dist/lifecycle/handlers/worker.d.ts +4 -0
  79. package/dist/lifecycle/handlers/worker.d.ts.map +1 -1
  80. package/dist/lifecycle/handlers/worker.js +35 -3
  81. package/dist/lifecycle/handlers/worker.js.map +1 -1
  82. package/dist/map/adapter/acp-over-map.d.ts.map +1 -1
  83. package/dist/map/adapter/acp-over-map.js +32 -2
  84. package/dist/map/adapter/acp-over-map.js.map +1 -1
  85. package/dist/map/adapter/event-translator.d.ts.map +1 -1
  86. package/dist/map/adapter/event-translator.js +1 -0
  87. package/dist/map/adapter/event-translator.js.map +1 -1
  88. package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
  89. package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
  90. package/dist/map/adapter/extensions/agent-detection.js +91 -0
  91. package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
  92. package/dist/map/adapter/extensions/index.d.ts +10 -1
  93. package/dist/map/adapter/extensions/index.d.ts.map +1 -1
  94. package/dist/map/adapter/extensions/index.js +39 -0
  95. package/dist/map/adapter/extensions/index.js.map +1 -1
  96. package/dist/map/adapter/extensions/resume.d.ts +47 -0
  97. package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
  98. package/dist/map/adapter/extensions/resume.js +59 -0
  99. package/dist/map/adapter/extensions/resume.js.map +1 -0
  100. package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
  101. package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
  102. package/dist/map/adapter/extensions/workspace-files.js +338 -0
  103. package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
  104. package/dist/mcp/mcp-server.d.ts +6 -0
  105. package/dist/mcp/mcp-server.d.ts.map +1 -1
  106. package/dist/mcp/mcp-server.js +45 -0
  107. package/dist/mcp/mcp-server.js.map +1 -1
  108. package/dist/mcp/tools/claim_task.d.ts +35 -0
  109. package/dist/mcp/tools/claim_task.d.ts.map +1 -0
  110. package/dist/mcp/tools/claim_task.js +58 -0
  111. package/dist/mcp/tools/claim_task.js.map +1 -0
  112. package/dist/mcp/tools/done.d.ts +11 -2
  113. package/dist/mcp/tools/done.d.ts.map +1 -1
  114. package/dist/mcp/tools/done.js +15 -10
  115. package/dist/mcp/tools/done.js.map +1 -1
  116. package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
  117. package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
  118. package/dist/mcp/tools/list_claimable_tasks.js +63 -0
  119. package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
  120. package/dist/mcp/tools/unclaim_task.d.ts +31 -0
  121. package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
  122. package/dist/mcp/tools/unclaim_task.js +47 -0
  123. package/dist/mcp/tools/unclaim_task.js.map +1 -0
  124. package/dist/metrics/index.d.ts +2 -0
  125. package/dist/metrics/index.d.ts.map +1 -0
  126. package/dist/metrics/index.js +2 -0
  127. package/dist/metrics/index.js.map +1 -0
  128. package/dist/metrics/metrics.d.ts +79 -0
  129. package/dist/metrics/metrics.d.ts.map +1 -0
  130. package/dist/metrics/metrics.js +166 -0
  131. package/dist/metrics/metrics.js.map +1 -0
  132. package/dist/roles/capabilities.d.ts +1 -0
  133. package/dist/roles/capabilities.d.ts.map +1 -1
  134. package/dist/roles/capabilities.js +3 -0
  135. package/dist/roles/capabilities.js.map +1 -1
  136. package/dist/roles/types.d.ts +1 -1
  137. package/dist/roles/types.d.ts.map +1 -1
  138. package/dist/router/message-router.d.ts +41 -0
  139. package/dist/router/message-router.d.ts.map +1 -1
  140. package/dist/router/message-router.js +136 -5
  141. package/dist/router/message-router.js.map +1 -1
  142. package/dist/store/event-store.d.ts +8 -1
  143. package/dist/store/event-store.d.ts.map +1 -1
  144. package/dist/store/event-store.js +120 -4
  145. package/dist/store/event-store.js.map +1 -1
  146. package/dist/store/types/agents.d.ts +1 -1
  147. package/dist/store/types/agents.d.ts.map +1 -1
  148. package/dist/store/types/events.d.ts +1 -1
  149. package/dist/store/types/events.d.ts.map +1 -1
  150. package/dist/store/types/events.js.map +1 -1
  151. package/dist/store/types/index.d.ts +1 -0
  152. package/dist/store/types/index.d.ts.map +1 -1
  153. package/dist/store/types/index.js +1 -0
  154. package/dist/store/types/index.js.map +1 -1
  155. package/dist/store/types/sessions.d.ts +44 -0
  156. package/dist/store/types/sessions.d.ts.map +1 -0
  157. package/dist/store/types/sessions.js +9 -0
  158. package/dist/store/types/sessions.js.map +1 -0
  159. package/dist/store/types/tasks.d.ts +2 -0
  160. package/dist/store/types/tasks.d.ts.map +1 -1
  161. package/dist/task/backend/memory.d.ts +4 -1
  162. package/dist/task/backend/memory.d.ts.map +1 -1
  163. package/dist/task/backend/memory.js +81 -0
  164. package/dist/task/backend/memory.js.map +1 -1
  165. package/dist/task/backend/types.d.ts +30 -0
  166. package/dist/task/backend/types.d.ts.map +1 -1
  167. package/dist/task/backend/types.js.map +1 -1
  168. package/dist/teams/index.d.ts +4 -0
  169. package/dist/teams/index.d.ts.map +1 -0
  170. package/dist/teams/index.js +4 -0
  171. package/dist/teams/index.js.map +1 -0
  172. package/dist/teams/team-loader.d.ts +20 -0
  173. package/dist/teams/team-loader.d.ts.map +1 -0
  174. package/dist/teams/team-loader.js +293 -0
  175. package/dist/teams/team-loader.js.map +1 -0
  176. package/dist/teams/team-runtime.d.ts +139 -0
  177. package/dist/teams/team-runtime.d.ts.map +1 -0
  178. package/dist/teams/team-runtime.js +613 -0
  179. package/dist/teams/team-runtime.js.map +1 -0
  180. package/dist/teams/types.d.ts +266 -0
  181. package/dist/teams/types.d.ts.map +1 -0
  182. package/dist/teams/types.js +20 -0
  183. package/dist/teams/types.js.map +1 -0
  184. package/dist/workspace/dataplane-adapter.d.ts +1 -1
  185. package/dist/workspace/dataplane-adapter.d.ts.map +1 -1
  186. package/dist/workspace/dataplane-adapter.js +1 -1
  187. package/dist/workspace/dataplane-adapter.js.map +1 -1
  188. package/dist/workspace/index.d.ts +1 -1
  189. package/dist/workspace/index.d.ts.map +1 -1
  190. package/dist/workspace/strategies/index.d.ts +6 -0
  191. package/dist/workspace/strategies/index.d.ts.map +1 -0
  192. package/dist/workspace/strategies/index.js +5 -0
  193. package/dist/workspace/strategies/index.js.map +1 -0
  194. package/dist/workspace/strategies/optimistic.d.ts +26 -0
  195. package/dist/workspace/strategies/optimistic.d.ts.map +1 -0
  196. package/dist/workspace/strategies/optimistic.js +121 -0
  197. package/dist/workspace/strategies/optimistic.js.map +1 -0
  198. package/dist/workspace/strategies/queue.d.ts +26 -0
  199. package/dist/workspace/strategies/queue.d.ts.map +1 -0
  200. package/dist/workspace/strategies/queue.js +67 -0
  201. package/dist/workspace/strategies/queue.js.map +1 -0
  202. package/dist/workspace/strategies/registry.d.ts +37 -0
  203. package/dist/workspace/strategies/registry.d.ts.map +1 -0
  204. package/dist/workspace/strategies/registry.js +63 -0
  205. package/dist/workspace/strategies/registry.js.map +1 -0
  206. package/dist/workspace/strategies/trunk.d.ts +20 -0
  207. package/dist/workspace/strategies/trunk.d.ts.map +1 -0
  208. package/dist/workspace/strategies/trunk.js +108 -0
  209. package/dist/workspace/strategies/trunk.js.map +1 -0
  210. package/dist/workspace/strategies/types.d.ts +104 -0
  211. package/dist/workspace/strategies/types.d.ts.map +1 -0
  212. package/dist/workspace/strategies/types.js +11 -0
  213. package/dist/workspace/strategies/types.js.map +1 -0
  214. package/dist/workspace/types.d.ts +1 -1
  215. package/dist/workspace/types.d.ts.map +1 -1
  216. package/dist/workspace/workspace-manager.d.ts +1 -1
  217. package/dist/workspace/workspace-manager.d.ts.map +1 -1
  218. package/docs/implementation-details.md +1127 -0
  219. package/docs/implementation-summary.md +448 -0
  220. package/docs/plan-self-driving-support.md +433 -0
  221. package/docs/spec-self-driving-support.md +462 -0
  222. package/docs/team-templates.md +860 -0
  223. package/docs/teams.md +233 -0
  224. package/package.json +5 -3
  225. package/src/acp/__tests__/integration.test.ts +161 -1
  226. package/src/acp/__tests__/macro-agent.test.ts +95 -0
  227. package/src/acp/__tests__/session-persistence.test.ts +276 -0
  228. package/src/acp/macro-agent.ts +79 -7
  229. package/src/acp/session-mapper.ts +108 -1
  230. package/src/acp/types.ts +33 -1
  231. package/src/agent/agent-manager.ts +158 -6
  232. package/src/agent/types.ts +27 -0
  233. package/src/agent-detection/__tests__/command-builder.test.ts +336 -0
  234. package/src/agent-detection/__tests__/detector.test.ts +768 -0
  235. package/src/agent-detection/__tests__/registry.test.ts +254 -0
  236. package/src/agent-detection/command-builder.ts +90 -0
  237. package/src/agent-detection/detector.ts +307 -0
  238. package/src/agent-detection/index.ts +36 -0
  239. package/src/agent-detection/registry.ts +200 -0
  240. package/src/agent-detection/types.ts +184 -0
  241. package/src/api/server.ts +110 -0
  242. package/src/cli/index.ts +44 -0
  243. package/src/cli/mcp.ts +47 -0
  244. package/src/config/index.ts +9 -0
  245. package/src/config/project-config.ts +107 -0
  246. package/src/lifecycle/cascade.ts +1 -1
  247. package/src/lifecycle/handlers/index.ts +8 -0
  248. package/src/lifecycle/handlers/worker.ts +48 -3
  249. package/src/map/adapter/__tests__/extensions.test.ts +359 -0
  250. package/src/map/adapter/__tests__/workspace-files.test.ts +673 -0
  251. package/src/map/adapter/acp-over-map.ts +45 -2
  252. package/src/map/adapter/event-translator.ts +1 -0
  253. package/src/map/adapter/extensions/agent-detection.ts +201 -0
  254. package/src/map/adapter/extensions/index.ts +63 -0
  255. package/src/map/adapter/extensions/resume.ts +114 -0
  256. package/src/map/adapter/extensions/workspace-files.ts +449 -0
  257. package/src/mcp/mcp-server.ts +67 -0
  258. package/src/mcp/tools/claim_task.ts +86 -0
  259. package/src/mcp/tools/done.ts +24 -10
  260. package/src/mcp/tools/list_claimable_tasks.ts +93 -0
  261. package/src/mcp/tools/unclaim_task.ts +71 -0
  262. package/src/metrics/index.ts +9 -0
  263. package/src/metrics/metrics.ts +280 -0
  264. package/src/roles/capabilities.ts +3 -0
  265. package/src/roles/types.ts +2 -1
  266. package/src/router/__tests__/message-router.test.ts +561 -0
  267. package/src/router/message-router.ts +223 -6
  268. package/src/store/event-store.ts +151 -3
  269. package/src/store/types/agents.ts +1 -1
  270. package/src/store/types/events.ts +2 -1
  271. package/src/store/types/index.ts +1 -0
  272. package/src/store/types/sessions.ts +53 -0
  273. package/src/store/types/tasks.ts +3 -0
  274. package/src/task/backend/memory.ts +116 -0
  275. package/src/task/backend/types.ts +43 -0
  276. package/src/teams/__tests__/cross-subsystem.integration.test.ts +983 -0
  277. package/src/teams/__tests__/e2e/team-runtime.e2e.test.ts +553 -0
  278. package/src/teams/__tests__/team-system.test.ts +1280 -0
  279. package/src/teams/index.ts +13 -0
  280. package/src/teams/team-loader.ts +434 -0
  281. package/src/teams/team-runtime.ts +727 -0
  282. package/src/teams/types.ts +377 -0
  283. package/src/workspace/dataplane-adapter.ts +1 -1
  284. package/src/workspace/index.ts +1 -1
  285. package/src/workspace/strategies/index.ts +18 -0
  286. package/src/workspace/strategies/optimistic.ts +136 -0
  287. package/src/workspace/strategies/queue.ts +81 -0
  288. package/src/workspace/strategies/registry.ts +89 -0
  289. package/src/workspace/strategies/trunk.ts +123 -0
  290. package/src/workspace/strategies/types.ts +145 -0
  291. package/src/workspace/types.ts +1 -1
  292. package/src/workspace/workspace-manager.ts +1 -1
  293. package/.claude/settings.local.json +0 -59
  294. package/dist/map/utils/address-translation.d.ts +0 -99
  295. package/dist/map/utils/address-translation.d.ts.map +0 -1
  296. package/dist/map/utils/address-translation.js +0 -285
  297. package/dist/map/utils/address-translation.js.map +0 -1
  298. package/dist/map/utils/index.d.ts +0 -7
  299. package/dist/map/utils/index.d.ts.map +0 -1
  300. package/dist/map/utils/index.js +0 -7
  301. package/dist/map/utils/index.js.map +0 -1
  302. package/references/acp-factory-ref/CHANGELOG.md +0 -33
  303. package/references/acp-factory-ref/LICENSE +0 -21
  304. package/references/acp-factory-ref/README.md +0 -341
  305. package/references/acp-factory-ref/package-lock.json +0 -3102
  306. package/references/acp-factory-ref/package.json +0 -96
  307. package/references/acp-factory-ref/python/CHANGELOG.md +0 -33
  308. package/references/acp-factory-ref/python/LICENSE +0 -21
  309. package/references/acp-factory-ref/python/Makefile +0 -57
  310. package/references/acp-factory-ref/python/README.md +0 -253
  311. package/references/acp-factory-ref/python/pyproject.toml +0 -73
  312. package/references/acp-factory-ref/python/tests/__init__.py +0 -0
  313. package/references/acp-factory-ref/python/tests/e2e/__init__.py +0 -1
  314. package/references/acp-factory-ref/python/tests/e2e/test_codex_e2e.py +0 -349
  315. package/references/acp-factory-ref/python/tests/e2e/test_gemini_e2e.py +0 -165
  316. package/references/acp-factory-ref/python/tests/e2e/test_opencode_e2e.py +0 -296
  317. package/references/acp-factory-ref/python/tests/test_client_handler.py +0 -543
  318. package/references/acp-factory-ref/python/tests/test_pushable.py +0 -199
  319. package/references/claude-code-acp/.github/workflows/ci.yml +0 -45
  320. package/references/claude-code-acp/.github/workflows/publish.yml +0 -34
  321. package/references/claude-code-acp/.prettierrc.json +0 -4
  322. package/references/claude-code-acp/CHANGELOG.md +0 -249
  323. package/references/claude-code-acp/LICENSE +0 -222
  324. package/references/claude-code-acp/README.md +0 -53
  325. package/references/claude-code-acp/docs/RELEASES.md +0 -24
  326. package/references/claude-code-acp/eslint.config.js +0 -48
  327. package/references/claude-code-acp/package-lock.json +0 -4570
  328. package/references/claude-code-acp/package.json +0 -88
  329. package/references/claude-code-acp/scripts/release.sh +0 -119
  330. package/references/claude-code-acp/src/acp-agent.ts +0 -2065
  331. package/references/claude-code-acp/src/index.ts +0 -26
  332. package/references/claude-code-acp/src/lib.ts +0 -38
  333. package/references/claude-code-acp/src/mcp-server.ts +0 -911
  334. package/references/claude-code-acp/src/settings.ts +0 -522
  335. package/references/claude-code-acp/src/tests/.claude/commands/quick-math.md +0 -5
  336. package/references/claude-code-acp/src/tests/.claude/commands/say-hello.md +0 -6
  337. package/references/claude-code-acp/src/tests/acp-agent-fork.test.ts +0 -479
  338. package/references/claude-code-acp/src/tests/acp-agent.test.ts +0 -1502
  339. package/references/claude-code-acp/src/tests/extract-lines.test.ts +0 -103
  340. package/references/claude-code-acp/src/tests/fork-session.test.ts +0 -335
  341. package/references/claude-code-acp/src/tests/replace-and-calculate-location.test.ts +0 -334
  342. package/references/claude-code-acp/src/tests/settings.test.ts +0 -617
  343. package/references/claude-code-acp/src/tests/skills-options.test.ts +0 -187
  344. package/references/claude-code-acp/src/tests/tools.test.ts +0 -318
  345. package/references/claude-code-acp/src/tests/typescript-declarations.test.ts +0 -558
  346. package/references/claude-code-acp/src/tools.ts +0 -819
  347. package/references/claude-code-acp/src/utils.ts +0 -171
  348. package/references/claude-code-acp/tsconfig.json +0 -18
  349. package/references/claude-code-acp/vitest.config.ts +0 -19
  350. package/references/multi-agent-protocol/.sudocode/issues.jsonl +0 -111
  351. package/references/multi-agent-protocol/.sudocode/specs.jsonl +0 -13
  352. package/references/multi-agent-protocol/LICENSE +0 -21
  353. package/references/multi-agent-protocol/README.md +0 -113
  354. package/references/multi-agent-protocol/docs/00-design-specification.md +0 -496
  355. package/references/multi-agent-protocol/docs/01-open-questions.md +0 -1050
  356. package/references/multi-agent-protocol/docs/02-wire-protocol.md +0 -296
  357. package/references/multi-agent-protocol/docs/03-streaming-semantics.md +0 -252
  358. package/references/multi-agent-protocol/docs/04-error-handling.md +0 -231
  359. package/references/multi-agent-protocol/docs/05-connection-model.md +0 -244
  360. package/references/multi-agent-protocol/docs/06-visibility-permissions.md +0 -243
  361. package/references/multi-agent-protocol/docs/07-federation.md +0 -259
  362. package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +0 -253
  363. package/references/multi-agent-protocol/docs/09-authentication.md +0 -680
  364. package/references/multi-agent-protocol/docs/10-mail-protocol.md +0 -553
  365. package/references/multi-agent-protocol/docs/agent-iam-integration.md +0 -877
  366. package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +0 -459
  367. package/references/multi-agent-protocol/docs/git-transport-draft.md +0 -251
  368. package/references/multi-agent-protocol/docs-site/Gemfile +0 -22
  369. package/references/multi-agent-protocol/docs-site/README.md +0 -82
  370. package/references/multi-agent-protocol/docs-site/_config.yml +0 -91
  371. package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +0 -20
  372. package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +0 -42
  373. package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +0 -34
  374. package/references/multi-agent-protocol/docs-site/examples/full-integration.md +0 -510
  375. package/references/multi-agent-protocol/docs-site/examples/index.md +0 -138
  376. package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +0 -282
  377. package/references/multi-agent-protocol/docs-site/examples/task-queue.md +0 -399
  378. package/references/multi-agent-protocol/docs-site/getting-started/index.md +0 -98
  379. package/references/multi-agent-protocol/docs-site/getting-started/installation.md +0 -219
  380. package/references/multi-agent-protocol/docs-site/getting-started/overview.md +0 -172
  381. package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +0 -237
  382. package/references/multi-agent-protocol/docs-site/index.md +0 -136
  383. package/references/multi-agent-protocol/docs-site/protocol/authentication.md +0 -391
  384. package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +0 -376
  385. package/references/multi-agent-protocol/docs-site/protocol/design.md +0 -284
  386. package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +0 -312
  387. package/references/multi-agent-protocol/docs-site/protocol/federation.md +0 -449
  388. package/references/multi-agent-protocol/docs-site/protocol/index.md +0 -129
  389. package/references/multi-agent-protocol/docs-site/protocol/permissions.md +0 -398
  390. package/references/multi-agent-protocol/docs-site/protocol/streaming.md +0 -353
  391. package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +0 -369
  392. package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +0 -357
  393. package/references/multi-agent-protocol/docs-site/sdk/api/client.md +0 -380
  394. package/references/multi-agent-protocol/docs-site/sdk/api/index.md +0 -62
  395. package/references/multi-agent-protocol/docs-site/sdk/api/server.md +0 -453
  396. package/references/multi-agent-protocol/docs-site/sdk/api/types.md +0 -468
  397. package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +0 -375
  398. package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +0 -405
  399. package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +0 -352
  400. package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +0 -89
  401. package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +0 -360
  402. package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +0 -446
  403. package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +0 -363
  404. package/references/multi-agent-protocol/docs-site/sdk/index.md +0 -206
  405. package/references/multi-agent-protocol/package-lock.json +0 -3886
  406. package/references/multi-agent-protocol/package.json +0 -56
  407. package/references/multi-agent-protocol/schema/meta.json +0 -467
  408. package/references/multi-agent-protocol/schema/schema.json +0 -2558
@@ -36,6 +36,7 @@ import type {
36
36
  SystemPromptContext,
37
37
  AgentLifecycleCallback,
38
38
  AgentConfig,
39
+ ContinueAgentOptions,
39
40
  } from "./types.js";
40
41
  import { AgentManagerError } from "./types.js";
41
42
  import type { RoleRegistry, Capability } from "../roles/types.js";
@@ -74,8 +75,10 @@ function getSpawnCapability(childRole: string): Capability {
74
75
  // or system-level agents can spawn coordinators
75
76
  return AGENT_CAPABILITIES.SPAWN_CUSTOM;
76
77
  default:
77
- // For custom roles, check against the custom spawn capability
78
- return AGENT_CAPABILITIES.SPAWN_CUSTOM;
78
+ // For team-defined roles (e.g., "grinder"), return the specific capability
79
+ // (e.g., "agent.spawn.grinder"). The spawn check also accepts
80
+ // "agent.spawn.custom" as a generic fallback.
81
+ return `agent.spawn.${childRole}` as Capability;
79
82
  }
80
83
  }
81
84
 
@@ -103,6 +106,20 @@ export interface AgentManager {
103
106
  */
104
107
  resume(agentId: AgentId): Promise<SpawnedAgent>;
105
108
 
109
+ /**
110
+ * Continue a terminated agent by spawning a new agent with the same
111
+ * role and task, injecting the prior conversation context as a
112
+ * resume prefix in the system prompt.
113
+ *
114
+ * @param agentId - ID of the agent to continue
115
+ * @param options - Continuation options
116
+ * @returns The newly spawned continuation agent
117
+ */
118
+ continueAgent(
119
+ agentId: AgentId,
120
+ options?: ContinueAgentOptions
121
+ ): Promise<SpawnedAgent>;
122
+
106
123
  // ── Queries ────────────────────────────────────────────────────
107
124
 
108
125
  /**
@@ -237,6 +254,21 @@ export interface AgentManager {
237
254
  */
238
255
  onLifecycleEvent(callback: AgentLifecycleCallback): () => void;
239
256
 
257
+ // ── Team Integration ─────────────────────────────────────────
258
+
259
+ /**
260
+ * Set a spawn interceptor that transforms SpawnAgentOptions before spawning.
261
+ * Used by TeamRuntime to inject team topics, prompts, MCP servers, and env vars.
262
+ */
263
+ setSpawnInterceptor(
264
+ interceptor: SpawnInterceptor | null
265
+ ): void;
266
+
267
+ /**
268
+ * Get the RoleRegistry used by this AgentManager.
269
+ */
270
+ getRoleRegistry(): RoleRegistry;
271
+
240
272
  // ── Mail Services (Late Binding) ─────────────────────────────
241
273
 
242
274
  /**
@@ -305,6 +337,18 @@ export interface AgentManagerConfig {
305
337
  conversationMap?: import("../mail/conversation-map.js").ConversationMap;
306
338
  }
307
339
 
340
+ // ─────────────────────────────────────────────────────────────────
341
+ // Spawn Interceptor
342
+ // ─────────────────────────────────────────────────────────────────
343
+
344
+ /**
345
+ * Function that transforms SpawnAgentOptions before an agent is spawned.
346
+ * Used by TeamRuntime to inject team-specific configuration.
347
+ */
348
+ export type SpawnInterceptor = (
349
+ options: SpawnAgentOptions
350
+ ) => SpawnAgentOptions | Promise<SpawnAgentOptions>;
351
+
308
352
  // ─────────────────────────────────────────────────────────────────
309
353
  // AgentManager Implementation
310
354
  // ─────────────────────────────────────────────────────────────────
@@ -329,6 +373,9 @@ export function createAgentManager(
329
373
  let mailService = initialMailService;
330
374
  let conversationMap = initialConversationMap;
331
375
 
376
+ // Mutable spawn interceptor (set by TeamRuntime)
377
+ let spawnInterceptor: SpawnInterceptor | null = null;
378
+
332
379
  // Active sessions tracked in memory
333
380
  const activeSessions = new Map<AgentId, ActiveSession>();
334
381
 
@@ -342,7 +389,12 @@ export function createAgentManager(
342
389
  // Lifecycle
343
390
  // ─────────────────────────────────────────────────────────────────
344
391
 
345
- async function spawn(options: SpawnAgentOptions): Promise<SpawnedAgent> {
392
+ async function spawn(rawOptions: SpawnAgentOptions): Promise<SpawnedAgent> {
393
+ // Apply spawn interceptor if set (used by TeamRuntime for team context injection)
394
+ const options = spawnInterceptor
395
+ ? await spawnInterceptor(rawOptions)
396
+ : rawOptions;
397
+
346
398
  const {
347
399
  task,
348
400
  task_id,
@@ -353,6 +405,8 @@ export function createAgentManager(
353
405
  topics = [],
354
406
  config: agentConfig,
355
407
  agentType = defaultAgentType,
408
+ customPrompt,
409
+ interactionPatterns,
356
410
  // Workspace-related fields (Phase 2)
357
411
  role,
358
412
  streamId,
@@ -381,7 +435,13 @@ export function createAgentManager(
381
435
  const requiredCapability = getSpawnCapability(childRole);
382
436
  const parentRole = parentAgent.role ?? "worker";
383
437
 
384
- if (!roleRegistry.hasCapability(parentRole, requiredCapability)) {
438
+ // Accept either the specific capability (e.g., agent.spawn.grinder)
439
+ // or the generic agent.spawn.custom as a fallback for non-built-in roles
440
+ const hasSpecific = roleRegistry.hasCapability(parentRole, requiredCapability);
441
+ const hasGeneric = requiredCapability !== AGENT_CAPABILITIES.SPAWN_CUSTOM &&
442
+ roleRegistry.hasCapability(parentRole, AGENT_CAPABILITIES.SPAWN_CUSTOM);
443
+
444
+ if (!hasSpecific && !hasGeneric) {
385
445
  throw new AgentManagerError(
386
446
  `Parent agent with role '${parentRole}' does not have capability to spawn '${childRole}' agents. ` +
387
447
  `Required capability: ${requiredCapability}`,
@@ -417,12 +477,21 @@ export function createAgentManager(
417
477
 
418
478
  let systemPrompt = generateSystemPrompt(promptContext);
419
479
 
420
- // Append role-specific system prompt if defined
480
+ // Append role prompt: team customPrompt takes precedence over resolvedRole.systemPrompt
421
481
  const resolvedRole = roleRegistry.resolveRole(role ?? "worker");
422
- if (resolvedRole.systemPrompt) {
482
+ if (customPrompt) {
483
+ systemPrompt += `\n\n# Role Instructions\n\n${customPrompt}`;
484
+ } else if (resolvedRole.systemPrompt) {
423
485
  systemPrompt += `\n\n# Role-Specific Instructions\n\n${resolvedRole.systemPrompt}`;
424
486
  }
425
487
 
488
+ // Append team interaction pattern sections (pull mode, trunk integration, etc.)
489
+ if (interactionPatterns && interactionPatterns.length > 0) {
490
+ for (const pattern of interactionPatterns) {
491
+ systemPrompt += `\n\n${pattern}`;
492
+ }
493
+ }
494
+
426
495
  eventStore.emit({
427
496
  type: "spawn",
428
497
  source: { agent_id: parent ?? "system" },
@@ -1308,10 +1377,91 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
1308
1377
  lifecycleListeners.clear();
1309
1378
  }
1310
1379
 
1380
+ function setSpawnInterceptor(interceptor: SpawnInterceptor | null): void {
1381
+ spawnInterceptor = interceptor;
1382
+ }
1383
+
1384
+ function getRoleRegistry(): RoleRegistry {
1385
+ return roleRegistry;
1386
+ }
1387
+
1388
+ /**
1389
+ * Continue a terminated agent by spawning a new agent with the same
1390
+ * role and task, injecting prior conversation context as a resume prefix.
1391
+ */
1392
+ async function continueAgent(
1393
+ agentId: AgentId,
1394
+ options?: ContinueAgentOptions
1395
+ ): Promise<SpawnedAgent> {
1396
+ const agent = eventStore.getAgent(agentId);
1397
+ if (!agent) {
1398
+ throw new AgentManagerError(
1399
+ `Agent not found: ${agentId}`,
1400
+ "AGENT_NOT_FOUND",
1401
+ agentId
1402
+ );
1403
+ }
1404
+
1405
+ // Build resume context from EventStore events
1406
+ const maxMessages = options?.maxMessages ?? 50;
1407
+ const events = eventStore.query({
1408
+ type: "status",
1409
+ source_agent_id: agentId,
1410
+ limit: maxMessages,
1411
+ });
1412
+
1413
+ // Format conversation turns as resume context
1414
+ const contextLines: string[] = [];
1415
+ if (options?.additionalContext) {
1416
+ contextLines.push(options.additionalContext);
1417
+ }
1418
+
1419
+ if (events.length > 0) {
1420
+ contextLines.push("## Prior Session Context");
1421
+ contextLines.push(`Continuing from agent ${agentId} (${events.length} events).`);
1422
+ for (const event of events.slice(-20)) {
1423
+ const summary = event.payload?.summary;
1424
+ if (summary && typeof summary === "string") {
1425
+ contextLines.push(`- ${summary}`);
1426
+ }
1427
+ }
1428
+ }
1429
+
1430
+ const resumeContext = contextLines.join("\n");
1431
+
1432
+ // Spawn a continuation agent with same role, task, and context
1433
+ const taskDescription =
1434
+ options?.task ??
1435
+ agent.task ??
1436
+ `Continue work from ${agentId}`;
1437
+
1438
+ const newAgent = await spawn({
1439
+ task: taskDescription,
1440
+ role: agent.role,
1441
+ parent: agent.parent ?? undefined,
1442
+ cwd: agent.cwd ?? defaultCwd,
1443
+ customPrompt: resumeContext || undefined,
1444
+ });
1445
+
1446
+ // Emit continuation event
1447
+ eventStore.emit({
1448
+ type: "status",
1449
+ source: { agent_id: newAgent.id },
1450
+ payload: {
1451
+ status_type: "started",
1452
+ summary: `Continuation of agent ${agentId}`,
1453
+ continuation_of: agentId,
1454
+ },
1455
+ });
1456
+
1457
+ return newAgent;
1458
+ }
1459
+
1311
1460
  return {
1312
1461
  spawn,
1313
1462
  terminate,
1314
1463
  resume,
1464
+ continueAgent,
1315
1465
  get,
1316
1466
  list,
1317
1467
  getChildren,
@@ -1328,6 +1478,8 @@ Call done() NOW with status "completed" if your work is finished, or "blocked" i
1328
1478
  respondToPermission,
1329
1479
  cancelPermission,
1330
1480
  onLifecycleEvent,
1481
+ setSpawnInterceptor,
1482
+ getRoleRegistry,
1331
1483
  setMailServices,
1332
1484
  close,
1333
1485
  };
@@ -51,6 +51,19 @@ export interface SpawnAgentOptions {
51
51
  /** Optional agent type (defaults to "claude-code") */
52
52
  agentType?: string;
53
53
 
54
+ /**
55
+ * Custom prompt content injected as the role instructions section.
56
+ * When set, replaces resolvedRole.systemPrompt in prompt assembly.
57
+ * Used by team templates to provide static role prompts.
58
+ */
59
+ customPrompt?: string;
60
+
61
+ /**
62
+ * Interaction pattern sections to append after the role prompt.
63
+ * Auto-generated by TeamRuntime based on team config (pull mode, etc.).
64
+ */
65
+ interactionPatterns?: string[];
66
+
54
67
  // ─────────────────────────────────────────────────────────────────
55
68
  // Workspace-related fields (Phase 2)
56
69
  // ─────────────────────────────────────────────────────────────────
@@ -80,6 +93,20 @@ export interface SpawnAgentOptions {
80
93
  dataplaneTaskId?: string;
81
94
  }
82
95
 
96
+ /**
97
+ * Options for continuing a terminated agent
98
+ */
99
+ export interface ContinueAgentOptions {
100
+ /** Maximum number of conversation turns to include in context (default: 50) */
101
+ maxMessages?: number;
102
+
103
+ /** Override the task description for the continuation */
104
+ task?: string;
105
+
106
+ /** Additional context to prepend to the continuation prompt */
107
+ additionalContext?: string;
108
+ }
109
+
83
110
  /**
84
111
  * Custom agent configuration
85
112
  */
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Command Builder Tests
3
+ */
4
+
5
+ import { describe, it, expect } from "vitest";
6
+
7
+ import { buildSpawnCommand, formatSpawnCommand } from "../command-builder.js";
8
+ import { BUILTIN_AGENTS } from "../registry.js";
9
+ import type { CLIAgentDefinition } from "../types.js";
10
+
11
+ // Helper to get a built-in agent definition by ID
12
+ function getAgent(id: string): CLIAgentDefinition {
13
+ const agent = BUILTIN_AGENTS.find((a) => a.id === id);
14
+ if (!agent) throw new Error(`Unknown agent: ${id}`);
15
+ return agent;
16
+ }
17
+
18
+ describe("buildSpawnCommand()", () => {
19
+ // ===========================================================================
20
+ // Claude Code
21
+ // ===========================================================================
22
+
23
+ describe("claude-code", () => {
24
+ const def = getAgent("claude-code");
25
+
26
+ it("builds basic command", () => {
27
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
28
+ expect(cmd.command).toBe("claude");
29
+ expect(cmd.args).toEqual([
30
+ "--output-format",
31
+ "stream-json",
32
+ "-p",
33
+ "Fix the auth bug",
34
+ ]);
35
+ });
36
+
37
+ it("builds command with model", () => {
38
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
39
+ model: "claude-sonnet-4-5",
40
+ });
41
+ expect(cmd.command).toBe("claude");
42
+ expect(cmd.args).toEqual([
43
+ "--output-format",
44
+ "stream-json",
45
+ "--model",
46
+ "claude-sonnet-4-5",
47
+ "-p",
48
+ "Fix the auth bug",
49
+ ]);
50
+ });
51
+
52
+ it("builds command with cwd", () => {
53
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
54
+ cwd: "/home/user/project",
55
+ });
56
+ expect(cmd.args).toContain("--cwd");
57
+ expect(cmd.args).toContain("/home/user/project");
58
+ });
59
+
60
+ it("builds command with model and cwd", () => {
61
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
62
+ model: "claude-sonnet-4-5",
63
+ cwd: "/home/user/project",
64
+ });
65
+ expect(cmd.command).toBe("claude");
66
+ expect(cmd.args).toEqual([
67
+ "--output-format",
68
+ "stream-json",
69
+ "--model",
70
+ "claude-sonnet-4-5",
71
+ "--cwd",
72
+ "/home/user/project",
73
+ "-p",
74
+ "Fix the auth bug",
75
+ ]);
76
+ });
77
+ });
78
+
79
+ // ===========================================================================
80
+ // Codex
81
+ // ===========================================================================
82
+
83
+ describe("codex", () => {
84
+ const def = getAgent("codex");
85
+
86
+ it("builds basic command with positional prompt", () => {
87
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
88
+ expect(cmd.command).toBe("codex");
89
+ expect(cmd.args).toEqual([
90
+ "exec",
91
+ "--full-auto",
92
+ "Fix the auth bug",
93
+ ]);
94
+ });
95
+
96
+ it("builds command with model and path", () => {
97
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
98
+ model: "o3",
99
+ cwd: "/home/user/project",
100
+ });
101
+ expect(cmd.command).toBe("codex");
102
+ expect(cmd.args).toEqual([
103
+ "exec",
104
+ "--full-auto",
105
+ "--model",
106
+ "o3",
107
+ "--path",
108
+ "/home/user/project",
109
+ "Fix the auth bug",
110
+ ]);
111
+ });
112
+ });
113
+
114
+ // ===========================================================================
115
+ // Gemini CLI
116
+ // ===========================================================================
117
+
118
+ describe("gemini-cli", () => {
119
+ const def = getAgent("gemini-cli");
120
+
121
+ it("builds basic command", () => {
122
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
123
+ expect(cmd.command).toBe("gemini");
124
+ expect(cmd.args).toEqual(["-p", "Fix the auth bug"]);
125
+ });
126
+
127
+ it("builds command with model (no cwd flag)", () => {
128
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
129
+ model: "gemini-2.5-pro",
130
+ cwd: "/home/user/project",
131
+ });
132
+ expect(cmd.command).toBe("gemini");
133
+ // Gemini has no cwdFlag, so cwd is ignored
134
+ expect(cmd.args).toEqual([
135
+ "--model",
136
+ "gemini-2.5-pro",
137
+ "-p",
138
+ "Fix the auth bug",
139
+ ]);
140
+ });
141
+ });
142
+
143
+ // ===========================================================================
144
+ // OpenCode
145
+ // ===========================================================================
146
+
147
+ describe("opencode", () => {
148
+ const def = getAgent("opencode");
149
+
150
+ it("builds basic command with positional prompt", () => {
151
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
152
+ expect(cmd.command).toBe("opencode");
153
+ expect(cmd.args).toEqual(["run", "Fix the auth bug"]);
154
+ });
155
+
156
+ it("builds command with model", () => {
157
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
158
+ model: "gpt-4",
159
+ });
160
+ expect(cmd.args).toEqual([
161
+ "run",
162
+ "--model",
163
+ "gpt-4",
164
+ "Fix the auth bug",
165
+ ]);
166
+ });
167
+ });
168
+
169
+ // ===========================================================================
170
+ // Aider
171
+ // ===========================================================================
172
+
173
+ describe("aider", () => {
174
+ const def = getAgent("aider");
175
+
176
+ it("builds basic command", () => {
177
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
178
+ expect(cmd.command).toBe("aider");
179
+ expect(cmd.args).toEqual([
180
+ "--yes",
181
+ "--message",
182
+ "Fix the auth bug",
183
+ ]);
184
+ });
185
+
186
+ it("builds command with model", () => {
187
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
188
+ model: "claude-3-opus",
189
+ });
190
+ expect(cmd.args).toEqual([
191
+ "--yes",
192
+ "--model",
193
+ "claude-3-opus",
194
+ "--message",
195
+ "Fix the auth bug",
196
+ ]);
197
+ });
198
+ });
199
+
200
+ // ===========================================================================
201
+ // Goose
202
+ // ===========================================================================
203
+
204
+ describe("goose", () => {
205
+ const def = getAgent("goose");
206
+
207
+ it("builds basic command", () => {
208
+ const cmd = buildSpawnCommand(def, "Fix the auth bug");
209
+ expect(cmd.command).toBe("goose");
210
+ expect(cmd.args).toEqual([
211
+ "run",
212
+ "--no-session",
213
+ "-t",
214
+ "Fix the auth bug",
215
+ ]);
216
+ });
217
+
218
+ it("builds command with model", () => {
219
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
220
+ model: "claude-4-sonnet",
221
+ });
222
+ expect(cmd.args).toEqual([
223
+ "run",
224
+ "--no-session",
225
+ "--model",
226
+ "claude-4-sonnet",
227
+ "-t",
228
+ "Fix the auth bug",
229
+ ]);
230
+ });
231
+ });
232
+
233
+ // ===========================================================================
234
+ // Edge Cases
235
+ // ===========================================================================
236
+
237
+ describe("edge cases", () => {
238
+ it("throws when task is empty", () => {
239
+ const def = getAgent("claude-code");
240
+ expect(() => buildSpawnCommand(def, "")).toThrow("Task prompt is required");
241
+ });
242
+
243
+ it("does not add model flag when modelFlag is undefined", () => {
244
+ const def: CLIAgentDefinition = {
245
+ id: "no-model",
246
+ name: "No Model",
247
+ description: "Agent without model flag",
248
+ binary: "no-model",
249
+ versionArgs: ["--version"],
250
+ headless: { promptFlag: "--prompt" },
251
+ vendor: "Test",
252
+ // modelFlag intentionally omitted
253
+ };
254
+ const cmd = buildSpawnCommand(def, "Do something", { model: "gpt-4" });
255
+ expect(cmd.args).not.toContain("--model");
256
+ expect(cmd.args).not.toContain("gpt-4");
257
+ });
258
+
259
+ it("does not add cwd flag when cwdFlag is undefined", () => {
260
+ const def: CLIAgentDefinition = {
261
+ id: "no-cwd",
262
+ name: "No CWD",
263
+ description: "Agent without cwd flag",
264
+ binary: "no-cwd",
265
+ versionArgs: ["--version"],
266
+ headless: { promptFlag: "--prompt" },
267
+ vendor: "Test",
268
+ // cwdFlag intentionally omitted
269
+ };
270
+ const cmd = buildSpawnCommand(def, "Do something", {
271
+ cwd: "/tmp",
272
+ });
273
+ expect(cmd.args).not.toContain("--cwd");
274
+ expect(cmd.args).not.toContain("/tmp");
275
+ });
276
+
277
+ it("handles definition with no subcommand or default flags", () => {
278
+ const def: CLIAgentDefinition = {
279
+ id: "minimal",
280
+ name: "Minimal",
281
+ description: "Minimal agent",
282
+ binary: "minimal",
283
+ versionArgs: ["--version"],
284
+ headless: { promptFlag: "--prompt" },
285
+ vendor: "Test",
286
+ };
287
+ const cmd = buildSpawnCommand(def, "Do something");
288
+ expect(cmd.command).toBe("minimal");
289
+ expect(cmd.args).toEqual(["--prompt", "Do something"]);
290
+ });
291
+ });
292
+ });
293
+
294
+ // =============================================================================
295
+ // formatSpawnCommand()
296
+ // =============================================================================
297
+
298
+ describe("formatSpawnCommand()", () => {
299
+ it("formats a command with no arguments", () => {
300
+ const formatted = formatSpawnCommand({
301
+ command: "my-agent",
302
+ args: [],
303
+ });
304
+ expect(formatted).toBe("my-agent");
305
+ });
306
+
307
+ it("formats a simple command", () => {
308
+ const formatted = formatSpawnCommand({
309
+ command: "claude",
310
+ args: ["-p", "hello"],
311
+ });
312
+ expect(formatted).toBe('claude -p hello');
313
+ });
314
+
315
+ it("quotes arguments with spaces", () => {
316
+ const formatted = formatSpawnCommand({
317
+ command: "claude",
318
+ args: ["-p", "Fix the auth bug", "--cwd", "/home/user/my project"],
319
+ });
320
+ expect(formatted).toBe(
321
+ 'claude -p "Fix the auth bug" --cwd "/home/user/my project"'
322
+ );
323
+ });
324
+
325
+ it("formats a full claude-code command", () => {
326
+ const def = getAgent("claude-code");
327
+ const cmd = buildSpawnCommand(def, "Fix the auth bug", {
328
+ model: "claude-sonnet-4-5",
329
+ cwd: "/home/user/project",
330
+ });
331
+ const formatted = formatSpawnCommand(cmd);
332
+ expect(formatted).toBe(
333
+ 'claude --output-format stream-json --model claude-sonnet-4-5 --cwd /home/user/project -p "Fix the auth bug"'
334
+ );
335
+ });
336
+ });