@clinebot/core 0.0.34 → 0.0.35

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 (372) hide show
  1. package/README.md +12 -8
  2. package/dist/ClineCore.d.ts +48 -29
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/extensions/config/agent-config-loader.d.ts +2 -2
  5. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  6. package/dist/extensions/config/agent-config-parser.d.ts +1 -1
  7. package/dist/extensions/config/agent-config-parser.d.ts.map +1 -1
  8. package/dist/extensions/config/hooks-config-loader.d.ts +2 -2
  9. package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -1
  10. package/dist/extensions/config/index.d.ts +3 -3
  11. package/dist/extensions/config/index.d.ts.map +1 -1
  12. package/dist/extensions/config/user-instruction-config-loader.d.ts +2 -2
  13. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  14. package/dist/extensions/plugin-sandbox-bootstrap.js +248 -248
  15. package/dist/extensions/tools/constants.d.ts.map +1 -0
  16. package/dist/extensions/tools/definitions.d.ts.map +1 -0
  17. package/dist/extensions/tools/executors/apply-patch-parser.d.ts.map +1 -0
  18. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -0
  19. package/dist/extensions/tools/executors/bash.d.ts.map +1 -0
  20. package/dist/extensions/tools/executors/editor.d.ts.map +1 -0
  21. package/dist/extensions/tools/executors/file-read.d.ts.map +1 -0
  22. package/dist/extensions/tools/executors/index.d.ts.map +1 -0
  23. package/dist/extensions/tools/executors/search.d.ts.map +1 -0
  24. package/dist/extensions/tools/executors/web-fetch.d.ts.map +1 -0
  25. package/dist/extensions/tools/helpers.d.ts.map +1 -0
  26. package/dist/extensions/tools/index.d.ts.map +1 -0
  27. package/dist/{tools → extensions/tools}/model-tool-routing.d.ts +1 -1
  28. package/dist/extensions/tools/model-tool-routing.d.ts.map +1 -0
  29. package/dist/{tools → extensions/tools}/presets.d.ts +1 -2
  30. package/dist/extensions/tools/presets.d.ts.map +1 -0
  31. package/dist/extensions/tools/schemas.d.ts.map +1 -0
  32. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -0
  33. package/dist/extensions/tools/team/index.d.ts.map +1 -0
  34. package/dist/{team → extensions/tools/team}/multi-agent.d.ts +1 -3
  35. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -0
  36. package/dist/extensions/tools/team/projections.d.ts.map +1 -0
  37. package/dist/extensions/tools/team/runtime.d.ts.map +1 -0
  38. package/dist/{team → extensions/tools/team}/spawn-agent-tool.d.ts +0 -1
  39. package/dist/extensions/tools/team/spawn-agent-tool.d.ts.map +1 -0
  40. package/dist/extensions/tools/team/subagent-prompts.d.ts.map +1 -0
  41. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -0
  42. package/dist/{tools → extensions/tools}/types.d.ts +4 -3
  43. package/dist/extensions/tools/types.d.ts.map +1 -0
  44. package/dist/{runtime → hooks}/checkpoint-hooks.d.ts +7 -0
  45. package/dist/hooks/checkpoint-hooks.d.ts.map +1 -0
  46. package/dist/{runtime → hooks}/hook-file-hooks.d.ts +0 -2
  47. package/dist/hooks/hook-file-hooks.d.ts.map +1 -0
  48. package/dist/hooks/subprocess.d.ts +3 -130
  49. package/dist/hooks/subprocess.d.ts.map +1 -1
  50. package/dist/index.d.ts +35 -33
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +381 -379
  53. package/dist/runtime/history.d.ts +4 -0
  54. package/dist/runtime/history.d.ts.map +1 -0
  55. package/dist/runtime/host.d.ts +9 -0
  56. package/dist/runtime/host.d.ts.map +1 -0
  57. package/dist/{session → runtime}/rpc-runtime-ensure.d.ts +13 -1
  58. package/dist/{session → runtime}/rpc-runtime-ensure.d.ts.map +1 -1
  59. package/dist/{session → runtime}/rpc-spawn-lease.d.ts.map +1 -1
  60. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  61. package/dist/{session/session-manager.d.ts → runtime/runtime-host.d.ts} +55 -12
  62. package/dist/runtime/runtime-host.d.ts.map +1 -0
  63. package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts +1 -1
  64. package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts.map +1 -1
  65. package/dist/runtime/session-runtime.d.ts +2 -2
  66. package/dist/runtime/session-runtime.d.ts.map +1 -1
  67. package/dist/{session/session-agent-events.d.ts → services/agent-events.d.ts} +4 -4
  68. package/dist/services/agent-events.d.ts.map +1 -0
  69. package/dist/services/config.d.ts +3 -0
  70. package/dist/services/config.d.ts.map +1 -0
  71. package/dist/services/local-runtime-bootstrap.d.ts +41 -0
  72. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -0
  73. package/dist/services/providers/local-provider-registry.d.ts.map +1 -0
  74. package/dist/services/providers/local-provider-service.d.ts.map +1 -0
  75. package/dist/{session → services}/session-artifacts.d.ts +0 -4
  76. package/dist/services/session-artifacts.d.ts.map +1 -0
  77. package/dist/{session/utils/helpers.d.ts → services/session-data.d.ts} +19 -27
  78. package/dist/services/session-data.d.ts.map +1 -0
  79. package/dist/{session → services}/session-telemetry.d.ts +2 -2
  80. package/dist/services/session-telemetry.d.ts.map +1 -0
  81. package/dist/{storage → services/storage}/file-team-store.d.ts +2 -2
  82. package/dist/services/storage/file-team-store.d.ts.map +1 -0
  83. package/dist/{storage → services/storage}/provider-settings-legacy-migration.d.ts +1 -1
  84. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -0
  85. package/dist/{storage → services/storage}/provider-settings-manager.d.ts +1 -1
  86. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -0
  87. package/dist/{storage → services/storage}/sqlite-session-store.d.ts +3 -3
  88. package/dist/services/storage/sqlite-session-store.d.ts.map +1 -0
  89. package/dist/{storage → services/storage}/sqlite-team-store.d.ts +2 -2
  90. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -0
  91. package/dist/{storage → services/storage}/team-store.d.ts +1 -1
  92. package/dist/services/storage/team-store.d.ts.map +1 -0
  93. package/dist/services/telemetry/ITelemetryAdapter.d.ts.map +1 -0
  94. package/dist/services/telemetry/OpenTelemetryAdapter.d.ts.map +1 -0
  95. package/dist/services/telemetry/OpenTelemetryProvider.d.ts.map +1 -0
  96. package/dist/services/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
  97. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -0
  98. package/dist/services/telemetry/core-events.d.ts.map +1 -0
  99. package/dist/services/telemetry/distinct-id.d.ts.map +1 -0
  100. package/dist/services/telemetry/index.d.ts.map +1 -0
  101. package/dist/{telemetry → services/telemetry}/index.js +6 -6
  102. package/dist/{session/utils → services}/usage.d.ts +1 -1
  103. package/dist/services/usage.d.ts.map +1 -0
  104. package/dist/services/workspace/file-indexer.d.ts.map +1 -0
  105. package/dist/services/workspace/index.d.ts.map +1 -0
  106. package/dist/services/workspace/mention-enricher.d.ts.map +1 -0
  107. package/dist/services/workspace-manifest.d.ts.map +1 -0
  108. package/dist/session/file-session-service.d.ts +4 -1
  109. package/dist/session/file-session-service.d.ts.map +1 -1
  110. package/dist/session/persistence-service.d.ts +8 -6
  111. package/dist/session/persistence-service.d.ts.map +1 -1
  112. package/dist/session/rpc-session-service.d.ts +3 -0
  113. package/dist/session/rpc-session-service.d.ts.map +1 -1
  114. package/dist/session/session-service.d.ts +8 -9
  115. package/dist/session/session-service.d.ts.map +1 -1
  116. package/dist/session/session-team-coordination.d.ts +4 -4
  117. package/dist/session/session-team-coordination.d.ts.map +1 -1
  118. package/dist/session/sqlite-rpc-session-backend.d.ts.map +1 -1
  119. package/dist/{session/default-session-manager.d.ts → transports/local.d.ts} +24 -14
  120. package/dist/transports/local.d.ts.map +1 -0
  121. package/dist/transports/rpc.d.ts +51 -0
  122. package/dist/transports/rpc.d.ts.map +1 -0
  123. package/dist/transports/runtime-host-support.d.ts +21 -0
  124. package/dist/transports/runtime-host-support.d.ts.map +1 -0
  125. package/dist/types/chat-schema.d.ts.map +1 -0
  126. package/dist/types/config.d.ts +2 -2
  127. package/dist/types/config.d.ts.map +1 -1
  128. package/dist/{session/utils/types.d.ts → types/session.d.ts} +15 -6
  129. package/dist/types/session.d.ts.map +1 -0
  130. package/dist/types/sessions.d.ts +19 -0
  131. package/dist/types/sessions.d.ts.map +1 -1
  132. package/dist/types/storage.d.ts +1 -3
  133. package/dist/types/storage.d.ts.map +1 -1
  134. package/dist/types.d.ts +7 -6
  135. package/dist/types.d.ts.map +1 -1
  136. package/package.json +7 -12
  137. package/src/ClineCore.test.ts +95 -19
  138. package/src/ClineCore.ts +120 -50
  139. package/src/auth/cline.ts +1 -1
  140. package/src/auth/codex.ts +1 -1
  141. package/src/auth/oca.ts +1 -1
  142. package/src/extensions/config/agent-config-loader.test.ts +3 -3
  143. package/src/extensions/config/agent-config-loader.ts +1 -5
  144. package/src/extensions/config/agent-config-parser.ts +1 -1
  145. package/src/extensions/config/hooks-config-loader.ts +1 -2
  146. package/src/extensions/config/index.ts +0 -4
  147. package/src/extensions/config/user-instruction-config-loader.ts +0 -4
  148. package/src/extensions/plugin/plugin-config-loader.test.ts +6 -4
  149. package/src/{tools → extensions/tools}/definitions.ts +1 -1
  150. package/src/extensions/tools/executors/file-read.test.ts +125 -0
  151. package/src/{tools → extensions/tools}/executors/file-read.ts +29 -4
  152. package/src/{tools → extensions/tools}/executors/search.ts +1 -1
  153. package/src/{tools → extensions/tools}/model-tool-routing.ts +1 -1
  154. package/src/{tools → extensions/tools}/presets.ts +2 -3
  155. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +455 -0
  156. package/src/{team → extensions/tools/team}/multi-agent.ts +80 -17
  157. package/src/{team → extensions/tools/team}/spawn-agent-tool.test.ts +0 -6
  158. package/src/{team → extensions/tools/team}/spawn-agent-tool.ts +1 -7
  159. package/src/{team → extensions/tools/team}/subagent-prompts.ts +2 -2
  160. package/src/{team → extensions/tools/team}/team-tools.test.ts +43 -31
  161. package/src/{team → extensions/tools/team}/team-tools.ts +63 -53
  162. package/src/{tools → extensions/tools}/types.ts +5 -3
  163. package/src/{runtime → hooks}/checkpoint-hooks.ts +27 -0
  164. package/src/{runtime → hooks}/hook-file-hooks.ts +6 -11
  165. package/src/hooks/subprocess.ts +48 -257
  166. package/src/index.ts +167 -158
  167. package/src/runtime/history.test.ts +114 -0
  168. package/src/runtime/history.ts +237 -0
  169. package/src/runtime/host.test.ts +230 -0
  170. package/src/runtime/host.ts +362 -0
  171. package/src/runtime/rpc-runtime-ensure.test.ts +123 -0
  172. package/src/{session → runtime}/rpc-runtime-ensure.ts +165 -27
  173. package/src/{session → runtime}/rpc-spawn-lease.test.ts +33 -1
  174. package/src/{session → runtime}/rpc-spawn-lease.ts +54 -20
  175. package/src/runtime/runtime-builder.team-persistence.test.ts +6 -3
  176. package/src/runtime/runtime-builder.test.ts +3 -4
  177. package/src/runtime/runtime-builder.ts +13 -21
  178. package/src/runtime/runtime-host.ts +178 -0
  179. package/src/{session → runtime}/runtime-oauth-token-manager.ts +1 -1
  180. package/src/runtime/runtime-parity.test.ts +1 -1
  181. package/src/runtime/session-runtime.ts +2 -2
  182. package/src/{session/session-agent-events.ts → services/agent-events.ts} +7 -7
  183. package/src/services/config.ts +5 -0
  184. package/src/services/local-runtime-bootstrap.ts +280 -0
  185. package/src/{providers → services/providers}/local-provider-service.ts +4 -4
  186. package/src/{session → services}/session-artifacts.ts +7 -19
  187. package/src/{session/utils/helpers.test.ts → services/session-data.test.ts} +1 -1
  188. package/src/{session/utils/helpers.ts → services/session-data.ts} +76 -72
  189. package/src/{session → services}/session-telemetry.ts +7 -9
  190. package/src/services/storage/artifact-store.ts +1 -0
  191. package/src/{storage → services/storage}/file-team-store.ts +2 -2
  192. package/src/{storage → services/storage}/provider-settings-legacy-migration.test.ts +1 -1
  193. package/src/{storage → services/storage}/provider-settings-legacy-migration.ts +2 -2
  194. package/src/{storage → services/storage}/provider-settings-manager.ts +2 -2
  195. package/src/services/storage/session-store.ts +1 -0
  196. package/src/{storage → services/storage}/sqlite-session-store.ts +7 -12
  197. package/src/{storage → services/storage}/sqlite-team-store.ts +4 -4
  198. package/src/{storage → services/storage}/team-store.ts +1 -1
  199. package/src/{session/utils → services}/usage.ts +1 -1
  200. package/src/{input → services/workspace}/file-indexer.test.ts +30 -1
  201. package/src/{input → services/workspace}/file-indexer.ts +26 -2
  202. package/src/{input → services/workspace}/mention-enricher.test.ts +21 -0
  203. package/src/{input → services/workspace}/mention-enricher.ts +1 -1
  204. package/src/session/file-session-service.ts +9 -7
  205. package/src/session/index.ts +25 -17
  206. package/src/session/persistence-service.test.ts +86 -27
  207. package/src/session/persistence-service.ts +104 -103
  208. package/src/session/rpc-session-service.ts +9 -2
  209. package/src/session/session-service.team-persistence.test.ts +1 -1
  210. package/src/session/session-service.ts +32 -19
  211. package/src/session/session-team-coordination.ts +13 -6
  212. package/src/session/sqlite-rpc-session-backend.ts +4 -6
  213. package/src/session/workspace-manager.ts +1 -1
  214. package/src/{session/default-session-manager.e2e.test.ts → transports/local.e2e.test.ts} +13 -17
  215. package/src/{session/default-session-manager.test.ts → transports/local.test.ts} +316 -230
  216. package/src/{session/default-session-manager.ts → transports/local.ts} +137 -169
  217. package/src/transports/rpc.test.ts +82 -0
  218. package/src/transports/rpc.ts +665 -0
  219. package/src/transports/runtime-host-support.ts +86 -0
  220. package/src/types/config.ts +2 -2
  221. package/src/{session/utils/types.ts → types/session.ts} +18 -5
  222. package/src/types/sessions.ts +21 -0
  223. package/src/types/storage.ts +1 -6
  224. package/src/types.ts +25 -18
  225. package/dist/chat/chat-schema.d.ts.map +0 -1
  226. package/dist/input/file-indexer.d.ts.map +0 -1
  227. package/dist/input/index.d.ts.map +0 -1
  228. package/dist/input/mention-enricher.d.ts.map +0 -1
  229. package/dist/prompt/default-system.d.ts +0 -2
  230. package/dist/prompt/default-system.d.ts.map +0 -1
  231. package/dist/providers/local-provider-registry.d.ts.map +0 -1
  232. package/dist/providers/local-provider-service.d.ts.map +0 -1
  233. package/dist/runtime/checkpoint-hooks.d.ts.map +0 -1
  234. package/dist/runtime/hook-file-hooks.d.ts.map +0 -1
  235. package/dist/session/default-session-manager.d.ts.map +0 -1
  236. package/dist/session/session-agent-events.d.ts.map +0 -1
  237. package/dist/session/session-artifacts.d.ts.map +0 -1
  238. package/dist/session/session-config-builder.d.ts +0 -16
  239. package/dist/session/session-config-builder.d.ts.map +0 -1
  240. package/dist/session/session-host.d.ts +0 -15
  241. package/dist/session/session-host.d.ts.map +0 -1
  242. package/dist/session/session-manager.d.ts.map +0 -1
  243. package/dist/session/session-telemetry.d.ts.map +0 -1
  244. package/dist/session/utils/helpers.d.ts.map +0 -1
  245. package/dist/session/utils/types.d.ts.map +0 -1
  246. package/dist/session/utils/usage.d.ts.map +0 -1
  247. package/dist/session/workspace-manifest.d.ts.map +0 -1
  248. package/dist/storage/file-team-store.d.ts.map +0 -1
  249. package/dist/storage/provider-settings-legacy-migration.d.ts.map +0 -1
  250. package/dist/storage/provider-settings-manager.d.ts.map +0 -1
  251. package/dist/storage/sqlite-session-store.d.ts.map +0 -1
  252. package/dist/storage/sqlite-team-store.d.ts.map +0 -1
  253. package/dist/storage/team-store.d.ts.map +0 -1
  254. package/dist/team/delegated-agent.d.ts.map +0 -1
  255. package/dist/team/index.d.ts.map +0 -1
  256. package/dist/team/multi-agent.d.ts.map +0 -1
  257. package/dist/team/projections.d.ts.map +0 -1
  258. package/dist/team/runtime.d.ts.map +0 -1
  259. package/dist/team/spawn-agent-tool.d.ts.map +0 -1
  260. package/dist/team/subagent-prompts.d.ts.map +0 -1
  261. package/dist/team/team-tools.d.ts.map +0 -1
  262. package/dist/telemetry/ITelemetryAdapter.d.ts.map +0 -1
  263. package/dist/telemetry/OpenTelemetryAdapter.d.ts.map +0 -1
  264. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +0 -1
  265. package/dist/telemetry/TelemetryLoggerSink.d.ts.map +0 -1
  266. package/dist/telemetry/TelemetryService.d.ts.map +0 -1
  267. package/dist/telemetry/core-events.d.ts.map +0 -1
  268. package/dist/telemetry/distinct-id.d.ts.map +0 -1
  269. package/dist/telemetry/index.d.ts.map +0 -1
  270. package/dist/tools/constants.d.ts.map +0 -1
  271. package/dist/tools/definitions.d.ts.map +0 -1
  272. package/dist/tools/executors/apply-patch-parser.d.ts.map +0 -1
  273. package/dist/tools/executors/apply-patch.d.ts.map +0 -1
  274. package/dist/tools/executors/bash.d.ts.map +0 -1
  275. package/dist/tools/executors/editor.d.ts.map +0 -1
  276. package/dist/tools/executors/file-read.d.ts.map +0 -1
  277. package/dist/tools/executors/index.d.ts.map +0 -1
  278. package/dist/tools/executors/search.d.ts.map +0 -1
  279. package/dist/tools/executors/web-fetch.d.ts.map +0 -1
  280. package/dist/tools/helpers.d.ts.map +0 -1
  281. package/dist/tools/index.d.ts.map +0 -1
  282. package/dist/tools/model-tool-routing.d.ts.map +0 -1
  283. package/dist/tools/presets.d.ts.map +0 -1
  284. package/dist/tools/schemas.d.ts.map +0 -1
  285. package/dist/tools/types.d.ts.map +0 -1
  286. package/src/prompt/default-system.ts +0 -21
  287. package/src/session/session-config-builder.ts +0 -172
  288. package/src/session/session-host.test.ts +0 -89
  289. package/src/session/session-host.ts +0 -213
  290. package/src/session/session-manager.ts +0 -74
  291. package/src/storage/artifact-store.ts +0 -1
  292. package/src/storage/session-store.ts +0 -1
  293. package/src/team/multi-agent.lifecycle.test.ts +0 -201
  294. package/src/tools/executors/file-read.test.ts +0 -49
  295. /package/dist/{tools → extensions/tools}/constants.d.ts +0 -0
  296. /package/dist/{tools → extensions/tools}/definitions.d.ts +0 -0
  297. /package/dist/{tools → extensions/tools}/executors/apply-patch-parser.d.ts +0 -0
  298. /package/dist/{tools → extensions/tools}/executors/apply-patch.d.ts +0 -0
  299. /package/dist/{tools → extensions/tools}/executors/bash.d.ts +0 -0
  300. /package/dist/{tools → extensions/tools}/executors/editor.d.ts +0 -0
  301. /package/dist/{tools → extensions/tools}/executors/file-read.d.ts +0 -0
  302. /package/dist/{tools → extensions/tools}/executors/index.d.ts +0 -0
  303. /package/dist/{tools → extensions/tools}/executors/search.d.ts +0 -0
  304. /package/dist/{tools → extensions/tools}/executors/web-fetch.d.ts +0 -0
  305. /package/dist/{tools → extensions/tools}/helpers.d.ts +0 -0
  306. /package/dist/{tools → extensions/tools}/index.d.ts +0 -0
  307. /package/dist/{tools → extensions/tools}/schemas.d.ts +0 -0
  308. /package/dist/{team → extensions/tools/team}/delegated-agent.d.ts +0 -0
  309. /package/dist/{team → extensions/tools/team}/index.d.ts +0 -0
  310. /package/dist/{team → extensions/tools/team}/projections.d.ts +0 -0
  311. /package/dist/{team → extensions/tools/team}/runtime.d.ts +0 -0
  312. /package/dist/{team → extensions/tools/team}/subagent-prompts.d.ts +0 -0
  313. /package/dist/{team → extensions/tools/team}/team-tools.d.ts +0 -0
  314. /package/dist/{session → runtime}/rpc-spawn-lease.d.ts +0 -0
  315. /package/dist/{providers → services/providers}/local-provider-registry.d.ts +0 -0
  316. /package/dist/{providers → services/providers}/local-provider-service.d.ts +0 -0
  317. /package/dist/{telemetry → services/telemetry}/ITelemetryAdapter.d.ts +0 -0
  318. /package/dist/{telemetry → services/telemetry}/OpenTelemetryAdapter.d.ts +0 -0
  319. /package/dist/{telemetry → services/telemetry}/OpenTelemetryProvider.d.ts +0 -0
  320. /package/dist/{telemetry → services/telemetry}/TelemetryLoggerSink.d.ts +0 -0
  321. /package/dist/{telemetry → services/telemetry}/TelemetryService.d.ts +0 -0
  322. /package/dist/{telemetry → services/telemetry}/core-events.d.ts +0 -0
  323. /package/dist/{telemetry → services/telemetry}/distinct-id.d.ts +0 -0
  324. /package/dist/{telemetry → services/telemetry}/index.d.ts +0 -0
  325. /package/dist/{input → services/workspace}/file-indexer.d.ts +0 -0
  326. /package/dist/{input → services/workspace}/index.d.ts +0 -0
  327. /package/dist/{input → services/workspace}/mention-enricher.d.ts +0 -0
  328. /package/dist/{session → services}/workspace-manifest.d.ts +0 -0
  329. /package/dist/{chat → types}/chat-schema.d.ts +0 -0
  330. /package/src/{tools → extensions/tools}/constants.ts +0 -0
  331. /package/src/{tools → extensions/tools}/definitions.test.ts +0 -0
  332. /package/src/{tools → extensions/tools}/executors/apply-patch-parser.ts +0 -0
  333. /package/src/{tools → extensions/tools}/executors/apply-patch.ts +0 -0
  334. /package/src/{tools → extensions/tools}/executors/bash.test.ts +0 -0
  335. /package/src/{tools → extensions/tools}/executors/bash.ts +0 -0
  336. /package/src/{tools → extensions/tools}/executors/editor.test.ts +0 -0
  337. /package/src/{tools → extensions/tools}/executors/editor.ts +0 -0
  338. /package/src/{tools → extensions/tools}/executors/index.ts +0 -0
  339. /package/src/{tools → extensions/tools}/executors/web-fetch.ts +0 -0
  340. /package/src/{tools → extensions/tools}/helpers.ts +0 -0
  341. /package/src/{tools → extensions/tools}/index.ts +0 -0
  342. /package/src/{tools → extensions/tools}/model-tool-routing.test.ts +0 -0
  343. /package/src/{tools → extensions/tools}/presets.test.ts +0 -0
  344. /package/src/{tools → extensions/tools}/schemas.ts +0 -0
  345. /package/src/{team → extensions/tools/team}/delegated-agent.ts +0 -0
  346. /package/src/{team → extensions/tools/team}/index.ts +0 -0
  347. /package/src/{team → extensions/tools/team}/projections.ts +0 -0
  348. /package/src/{team → extensions/tools/team}/runtime.ts +0 -0
  349. /package/src/{runtime → hooks}/checkpoint-hooks.test.ts +0 -0
  350. /package/src/{runtime → hooks}/hook-file-hooks.test.ts +0 -0
  351. /package/src/{session → runtime}/runtime-oauth-token-manager.test.ts +0 -0
  352. /package/src/{providers → services/providers}/local-provider-registry.ts +0 -0
  353. /package/src/{providers → services/providers}/local-provider-service.test.ts +0 -0
  354. /package/src/{storage → services/storage}/index.ts +0 -0
  355. /package/src/{storage → services/storage}/provider-settings-manager.test.ts +0 -0
  356. /package/src/{telemetry → services/telemetry}/ITelemetryAdapter.ts +0 -0
  357. /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.test.ts +0 -0
  358. /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.ts +0 -0
  359. /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.test.ts +0 -0
  360. /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.ts +0 -0
  361. /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.test.ts +0 -0
  362. /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.ts +0 -0
  363. /package/src/{telemetry → services/telemetry}/TelemetryService.test.ts +0 -0
  364. /package/src/{telemetry → services/telemetry}/TelemetryService.ts +0 -0
  365. /package/src/{telemetry → services/telemetry}/core-events.ts +0 -0
  366. /package/src/{telemetry → services/telemetry}/distinct-id.test.ts +0 -0
  367. /package/src/{telemetry → services/telemetry}/distinct-id.ts +0 -0
  368. /package/src/{telemetry → services/telemetry}/index.ts +0 -0
  369. /package/src/{input → services/workspace}/file-indexer.d.ts +0 -0
  370. /package/src/{input → services/workspace}/index.ts +0 -0
  371. /package/src/{session → services}/workspace-manifest.ts +0 -0
  372. /package/src/{chat → types}/chat-schema.ts +0 -0
@@ -0,0 +1,455 @@
1
+ import type { AgentEvent } from "@clinebot/shared";
2
+ import { describe, expect, it, vi } from "vitest";
3
+ import {
4
+ AgentTeamsRuntime,
5
+ type TeamEvent,
6
+ TeamMessageType,
7
+ } from "./multi-agent";
8
+
9
+ const { createAgentMock } = vi.hoisted(() => ({
10
+ createAgentMock: vi.fn(),
11
+ }));
12
+
13
+ vi.mock("@clinebot/agents", async () => {
14
+ const actual =
15
+ await vi.importActual<typeof import("@clinebot/agents")>(
16
+ "@clinebot/agents",
17
+ );
18
+
19
+ return {
20
+ ...actual,
21
+ createAgent: createAgentMock,
22
+ };
23
+ });
24
+
25
+ describe("AgentTeamsRuntime teammate lifecycle events", () => {
26
+ it("spawns teammates with a 10 minute API timeout", () => {
27
+ createAgentMock.mockReturnValueOnce({
28
+ abort: vi.fn(),
29
+ run: vi.fn(),
30
+ continue: vi.fn(),
31
+ canStartRun: vi.fn(() => true),
32
+ getAgentId: vi.fn(() => "teammate-1"),
33
+ getConversationId: vi.fn(() => "conv-1"),
34
+ getMessages: vi.fn(() => []),
35
+ });
36
+ const runtime = new AgentTeamsRuntime({
37
+ teamName: "test-team",
38
+ });
39
+
40
+ runtime.spawnTeammate({
41
+ agentId: "python-poet",
42
+ config: {
43
+ providerId: "anthropic",
44
+ modelId: "claude-sonnet-4-5-20250929",
45
+ systemPrompt: "Write concise Python-focused haiku",
46
+ tools: [],
47
+ },
48
+ });
49
+
50
+ expect(createAgentMock).toHaveBeenCalledWith(
51
+ expect.objectContaining({
52
+ apiTimeoutMs: 10 * 60 * 1000,
53
+ }),
54
+ );
55
+ });
56
+
57
+ it("does not emit task_start when teammate is already busy", async () => {
58
+ const events: TeamEvent[] = [];
59
+ createAgentMock.mockReturnValueOnce({
60
+ abort: vi.fn(),
61
+ run: vi.fn(),
62
+ continue: vi.fn(),
63
+ canStartRun: vi.fn(() => false),
64
+ getAgentId: vi.fn(() => "teammate-1"),
65
+ getConversationId: vi.fn(() => "conv-1"),
66
+ getMessages: vi.fn(() => []),
67
+ });
68
+ const runtime = new AgentTeamsRuntime({
69
+ teamName: "test-team",
70
+ onTeamEvent: (event) => events.push(event),
71
+ });
72
+
73
+ runtime.spawnTeammate({
74
+ agentId: "python-poet",
75
+ config: {
76
+ providerId: "anthropic",
77
+ modelId: "claude-sonnet-4-5-20250929",
78
+ systemPrompt: "Write concise Python-focused haiku",
79
+ maxIterations: 7,
80
+ tools: [],
81
+ },
82
+ });
83
+
84
+ await expect(
85
+ runtime.routeToTeammate("python-poet", "write something"),
86
+ ).rejects.toThrow(
87
+ "Cannot start a new run while another run is already in progress",
88
+ );
89
+ expect(
90
+ events.some((event) => event.type === TeamMessageType.TaskStart),
91
+ ).toBe(false);
92
+ });
93
+
94
+ it("emits teammate_spawned with lifecycle payload", () => {
95
+ const events: TeamEvent[] = [];
96
+ createAgentMock.mockReturnValueOnce({
97
+ abort: vi.fn(),
98
+ run: vi.fn(),
99
+ continue: vi.fn(),
100
+ canStartRun: vi.fn(() => true),
101
+ getAgentId: vi.fn(() => "teammate-1"),
102
+ getConversationId: vi.fn(() => "conv-1"),
103
+ getMessages: vi.fn(() => []),
104
+ });
105
+ const runtime = new AgentTeamsRuntime({
106
+ teamName: "test-team",
107
+ onTeamEvent: (event) => events.push(event),
108
+ });
109
+
110
+ runtime.spawnTeammate({
111
+ agentId: "python-poet",
112
+ config: {
113
+ providerId: "anthropic",
114
+ modelId: "claude-sonnet-4-5-20250929",
115
+ systemPrompt: "Write concise Python-focused haiku",
116
+ maxIterations: 7,
117
+ tools: [],
118
+ },
119
+ });
120
+
121
+ expect(events).toContainEqual({
122
+ type: TeamMessageType.TeammateSpawned,
123
+ agentId: "python-poet",
124
+ role: undefined,
125
+ teammate: {
126
+ rolePrompt: "Write concise Python-focused haiku",
127
+ modelId: "claude-sonnet-4-5-20250929",
128
+ maxIterations: 7,
129
+ runtimeAgentId: "teammate-1",
130
+ conversationId: "conv-1",
131
+ parentAgentId: null,
132
+ },
133
+ });
134
+ });
135
+
136
+ it("swallows abort-like shutdown errors from teammates", () => {
137
+ const events: TeamEvent[] = [];
138
+ createAgentMock.mockReturnValueOnce({
139
+ abort: vi.fn(() => {
140
+ throw new DOMException("This operation was aborted", "AbortError");
141
+ }),
142
+ run: vi.fn(),
143
+ continue: vi.fn(),
144
+ canStartRun: vi.fn(() => true),
145
+ getAgentId: vi.fn(() => "teammate-1"),
146
+ getConversationId: vi.fn(() => "conv-1"),
147
+ getMessages: vi.fn(() => []),
148
+ });
149
+ const runtime = new AgentTeamsRuntime({
150
+ teamName: "test-team",
151
+ onTeamEvent: (event) => events.push(event),
152
+ });
153
+
154
+ runtime.spawnTeammate({
155
+ agentId: "python-poet",
156
+ config: {
157
+ providerId: "anthropic",
158
+ modelId: "claude-sonnet-4-5-20250929",
159
+ systemPrompt: "Write concise Python-focused haiku",
160
+ tools: [],
161
+ },
162
+ });
163
+
164
+ expect(() =>
165
+ runtime.shutdownTeammate("python-poet", "manual_restart"),
166
+ ).not.toThrow();
167
+ expect(runtime.getSnapshot().members).toContainEqual(
168
+ expect.objectContaining({
169
+ agentId: "python-poet",
170
+ status: "stopped",
171
+ }),
172
+ );
173
+ expect(events).toContainEqual({
174
+ type: TeamMessageType.TeammateShutdown,
175
+ agentId: "python-poet",
176
+ reason: "manual_restart",
177
+ });
178
+ });
179
+
180
+ it("prepends unread mailbox notification to teammate message", async () => {
181
+ let routedMessage: string | undefined;
182
+ createAgentMock.mockReturnValueOnce({
183
+ abort: vi.fn(),
184
+ run: vi.fn(async (message) => {
185
+ routedMessage = message;
186
+ return {
187
+ text: "Task completed",
188
+ iterations: 1,
189
+ finishReason: "end_turn",
190
+ durationMs: 100,
191
+ usage: {
192
+ inputTokens: 10,
193
+ outputTokens: 20,
194
+ cacheReadTokens: 0,
195
+ cacheWriteTokens: 0,
196
+ totalCost: 0,
197
+ },
198
+ messages: [],
199
+ };
200
+ }),
201
+ continue: vi.fn(),
202
+ canStartRun: vi.fn(() => true),
203
+ getAgentId: vi.fn(() => "teammate-1"),
204
+ getConversationId: vi.fn(() => "conv-1"),
205
+ getMessages: vi.fn(() => []),
206
+ });
207
+ const runtime = new AgentTeamsRuntime({
208
+ teamName: "test-team",
209
+ });
210
+
211
+ runtime.spawnTeammate({
212
+ agentId: "alice",
213
+ config: {
214
+ providerId: "anthropic",
215
+ modelId: "claude-sonnet-4-5-20250929",
216
+ systemPrompt: "Helper teammate",
217
+ tools: [],
218
+ },
219
+ });
220
+
221
+ // Send message from lead to alice
222
+ runtime.sendMessage(
223
+ "lead",
224
+ "alice",
225
+ "Status check",
226
+ "How is your work going?",
227
+ );
228
+
229
+ // Route task to alice
230
+ await runtime.routeToTeammate("alice", "Complete your task");
231
+
232
+ // Verify the routed message includes mailbox notification
233
+ expect(routedMessage).toBeDefined();
234
+ expect(routedMessage).toContain("[MAILBOX]");
235
+ expect(routedMessage).toContain("You have 1 unread message(s)");
236
+ expect(routedMessage).toContain(
237
+ "Message from lead | subject: Status check",
238
+ );
239
+ expect(routedMessage).toContain("How is your work going?");
240
+ expect(routedMessage).toContain("Complete your task");
241
+
242
+ // Verify message is marked as read
243
+ const unreadAfter = runtime.listMailbox("alice", { unreadOnly: true });
244
+ expect(unreadAfter).toHaveLength(0);
245
+ });
246
+
247
+ it("does not prepend notification when no unread mail", async () => {
248
+ let routedMessage: string | undefined;
249
+ createAgentMock.mockReturnValueOnce({
250
+ abort: vi.fn(),
251
+ run: vi.fn(async (message) => {
252
+ routedMessage = message;
253
+ return {
254
+ text: "Task completed",
255
+ iterations: 1,
256
+ finishReason: "end_turn",
257
+ durationMs: 100,
258
+ usage: {
259
+ inputTokens: 10,
260
+ outputTokens: 20,
261
+ cacheReadTokens: 0,
262
+ cacheWriteTokens: 0,
263
+ totalCost: 0,
264
+ },
265
+ messages: [],
266
+ };
267
+ }),
268
+ continue: vi.fn(),
269
+ canStartRun: vi.fn(() => true),
270
+ getAgentId: vi.fn(() => "teammate-1"),
271
+ getConversationId: vi.fn(() => "conv-1"),
272
+ getMessages: vi.fn(() => []),
273
+ });
274
+ const runtime = new AgentTeamsRuntime({
275
+ teamName: "test-team",
276
+ });
277
+
278
+ runtime.spawnTeammate({
279
+ agentId: "bob",
280
+ config: {
281
+ providerId: "anthropic",
282
+ modelId: "claude-sonnet-4-5-20250929",
283
+ systemPrompt: "Helper teammate",
284
+ tools: [],
285
+ },
286
+ });
287
+
288
+ // Route task to bob with no prior messages
289
+ await runtime.routeToTeammate("bob", "Complete your task");
290
+
291
+ // Verify the routed message does not contain mailbox notification
292
+ expect(routedMessage).toBeDefined();
293
+ expect(routedMessage).toBe("Complete your task");
294
+ expect(routedMessage).not.toContain("[MAILBOX]");
295
+ });
296
+
297
+ it("queues steer message notification when recipient is running", () => {
298
+ let consumePendingMessage: (() => string | undefined) | undefined;
299
+ createAgentMock.mockImplementationOnce((config) => {
300
+ consumePendingMessage = config.consumePendingUserMessage;
301
+ return {
302
+ abort: vi.fn(),
303
+ run: vi.fn(),
304
+ continue: vi.fn(),
305
+ canStartRun: vi.fn(() => true),
306
+ getAgentId: vi.fn(() => "teammate-1"),
307
+ getConversationId: vi.fn(() => "conv-1"),
308
+ getMessages: vi.fn(() => []),
309
+ };
310
+ });
311
+ const runtime = new AgentTeamsRuntime({
312
+ teamName: "test-team",
313
+ });
314
+
315
+ runtime.spawnTeammate({
316
+ agentId: "charlie",
317
+ config: {
318
+ providerId: "anthropic",
319
+ modelId: "claude-sonnet-4-5-20250929",
320
+ systemPrompt: "Helper teammate",
321
+ tools: [],
322
+ },
323
+ });
324
+
325
+ // Simulate teammate is running by incrementing runningCount
326
+ const runtimeMembers = (
327
+ runtime as unknown as { members: Map<string, { runningCount: number }> }
328
+ ).members;
329
+ const member = runtimeMembers.get("charlie");
330
+ if (member) {
331
+ member.runningCount = 1;
332
+ }
333
+
334
+ // Send message from lead while charlie is running
335
+ runtime.sendMessage("lead", "charlie", "urgent update", "Fix the bug now!");
336
+
337
+ // Verify steer message is queued
338
+ expect(consumePendingMessage).toBeDefined();
339
+ const steerMsg = consumePendingMessage?.();
340
+ expect(steerMsg).toBeDefined();
341
+ expect(steerMsg).toContain("[MAILBOX]");
342
+ expect(steerMsg).toContain("lead");
343
+ expect(steerMsg).toContain("urgent update");
344
+ expect(steerMsg).toContain("team_read_mailbox");
345
+
346
+ // Verify consuming again returns undefined
347
+ expect(consumePendingMessage?.()).toBeUndefined();
348
+ });
349
+
350
+ it("does not queue steer message when recipient is idle", () => {
351
+ let consumePendingMessage: (() => string | undefined) | undefined;
352
+ createAgentMock.mockImplementationOnce((config) => {
353
+ consumePendingMessage = config.consumePendingUserMessage;
354
+ return {
355
+ abort: vi.fn(),
356
+ run: vi.fn(),
357
+ continue: vi.fn(),
358
+ canStartRun: vi.fn(() => true),
359
+ getAgentId: vi.fn(() => "teammate-1"),
360
+ getConversationId: vi.fn(() => "conv-1"),
361
+ getMessages: vi.fn(() => []),
362
+ };
363
+ });
364
+ const runtime = new AgentTeamsRuntime({
365
+ teamName: "test-team",
366
+ });
367
+
368
+ runtime.spawnTeammate({
369
+ agentId: "diana",
370
+ config: {
371
+ providerId: "anthropic",
372
+ modelId: "claude-sonnet-4-5-20250929",
373
+ systemPrompt: "Helper teammate",
374
+ tools: [],
375
+ },
376
+ });
377
+
378
+ // Send message from lead while diana is idle (runningCount = 0)
379
+ runtime.sendMessage("lead", "diana", "hello", "Hi there");
380
+
381
+ // Verify no steer message is queued
382
+ expect(consumePendingMessage?.()).toBeUndefined();
383
+
384
+ // Message should still be in mailbox for next route
385
+ const mailbox = runtime.listMailbox("diana", { unreadOnly: true });
386
+ expect(mailbox).toHaveLength(1);
387
+ expect(mailbox[0].subject).toBe("hello");
388
+ });
389
+
390
+ it("includes tool and run error details in run_progress activity", async () => {
391
+ const events: TeamEvent[] = [];
392
+ let wrappedOnEvent: ((event: AgentEvent) => void) | undefined;
393
+ createAgentMock.mockImplementationOnce((config) => {
394
+ wrappedOnEvent = config.onEvent;
395
+ return {
396
+ abort: vi.fn(),
397
+ run: vi.fn(async () => {
398
+ wrappedOnEvent?.({
399
+ type: "content_end",
400
+ contentType: "tool",
401
+ toolName: "team_mission_log",
402
+ error: "RPC backend returned 500 while appending mission log",
403
+ });
404
+ wrappedOnEvent?.({
405
+ type: "error",
406
+ error: new Error("API request timed out after 120000ms"),
407
+ recoverable: false,
408
+ iteration: 11,
409
+ });
410
+ throw new Error("API request timed out after 120000ms");
411
+ }),
412
+ continue: vi.fn(),
413
+ canStartRun: vi.fn(() => true),
414
+ getAgentId: vi.fn(() => "teammate-1"),
415
+ getConversationId: vi.fn(() => "conv-1"),
416
+ getMessages: vi.fn(() => []),
417
+ };
418
+ });
419
+ const runtime = new AgentTeamsRuntime({
420
+ teamName: "test-team",
421
+ onTeamEvent: (event) => events.push(event),
422
+ });
423
+
424
+ runtime.spawnTeammate({
425
+ agentId: "providers-investigator",
426
+ config: {
427
+ providerId: "anthropic",
428
+ modelId: "claude-sonnet-4-5-20250929",
429
+ systemPrompt: "Investigate providers thoroughly",
430
+ tools: [],
431
+ },
432
+ });
433
+
434
+ const run = runtime.startTeammateRun(
435
+ "providers-investigator",
436
+ "Investigate providers",
437
+ );
438
+ const settled = await runtime.awaitRun(run.id);
439
+
440
+ expect(settled.status).toBe("failed");
441
+ expect(events).toContainEqual(
442
+ expect.objectContaining({
443
+ type: TeamMessageType.RunProgress,
444
+ message:
445
+ "tool_team_mission_log_error: RPC backend returned 500 while appending mission log",
446
+ }),
447
+ );
448
+ expect(events).toContainEqual(
449
+ expect.objectContaining({
450
+ type: TeamMessageType.RunProgress,
451
+ message: "run_error: API request timed out after 120000ms",
452
+ }),
453
+ );
454
+ });
455
+ });
@@ -138,6 +138,23 @@ export interface SpawnTeammateOptions {
138
138
  config: TeamMemberConfig;
139
139
  }
140
140
 
141
+ function isAbortLikeError(error: unknown): boolean {
142
+ if (
143
+ typeof DOMException !== "undefined" &&
144
+ error instanceof DOMException &&
145
+ error.name === "AbortError"
146
+ ) {
147
+ return true;
148
+ }
149
+ if (!(error instanceof Error)) {
150
+ return false;
151
+ }
152
+ return (
153
+ error.name === "AbortError" ||
154
+ error.message.toLowerCase().includes("aborted")
155
+ );
156
+ }
157
+
141
158
  // =============================================================================
142
159
  // AgentTeam
143
160
  // =============================================================================
@@ -484,6 +501,7 @@ interface TeamMemberState extends TeamMemberSnapshot {
484
501
  runningCount: number;
485
502
  lastMissionStep: number;
486
503
  lastMissionAt: number;
504
+ pendingSteerMessage?: string;
487
505
  }
488
506
 
489
507
  export class AgentTeamsRuntime {
@@ -568,8 +586,6 @@ export class AgentTeamsRuntime {
568
586
  listTaskItems(options?: {
569
587
  status?: TeamTaskStatus;
570
588
  assignee?: string;
571
- unassignedOnly?: boolean;
572
- readyOnly?: boolean;
573
589
  }): TeamTaskListItem[] {
574
590
  return Array.from(this.tasks.values())
575
591
  .map((task) => {
@@ -590,12 +606,6 @@ export class AgentTeamsRuntime {
590
606
  if (options?.assignee && task.assignee !== options.assignee) {
591
607
  return false;
592
608
  }
593
- if (options?.unassignedOnly && !!task.assignee) {
594
- return false;
595
- }
596
- if (options?.readyOnly && !task.isReady) {
597
- return false;
598
- }
599
609
  return true;
600
610
  });
601
611
  }
@@ -825,6 +835,15 @@ export class AgentTeamsRuntime {
825
835
  const wrappedConfig: TeamMemberConfig = {
826
836
  ...config,
827
837
  apiTimeoutMs: TEAMMATE_API_TIMEOUT_MS,
838
+ consumePendingUserMessage: () => {
839
+ const member = this.members.get(agentId);
840
+ if (!member || !member.pendingSteerMessage) {
841
+ return undefined;
842
+ }
843
+ const message = member.pendingSteerMessage;
844
+ member.pendingSteerMessage = undefined;
845
+ return message;
846
+ },
828
847
  onEvent: (event: AgentEvent) => {
829
848
  config.onEvent?.(event);
830
849
  this.emitEvent({ type: TeamMessageType.AgentEvent, agentId, event });
@@ -870,7 +889,13 @@ export class AgentTeamsRuntime {
870
889
  if (!member || member.role !== "teammate") {
871
890
  throw new Error(`Teammate "${agentId}" was not found`);
872
891
  }
873
- member.agent?.abort();
892
+ try {
893
+ member.agent?.abort();
894
+ } catch (error) {
895
+ if (!isAbortLikeError(error)) {
896
+ throw error;
897
+ }
898
+ }
874
899
  member.status = "stopped";
875
900
  this.emitEvent({ type: TeamMessageType.TeammateShutdown, agentId, reason });
876
901
  }
@@ -986,9 +1011,17 @@ export class AgentTeamsRuntime {
986
1011
  this.emitEvent({ type: TeamMessageType.TaskStart, agentId, message });
987
1012
 
988
1013
  try {
1014
+ const unreadMail = this.listMailbox(agentId, {
1015
+ unreadOnly: true,
1016
+ markRead: true,
1017
+ });
1018
+ const enrichedMessage =
1019
+ unreadMail.length > 0
1020
+ ? `${this.buildMailboxNotification(unreadMail)}\n\n${message}`
1021
+ : message;
989
1022
  const result = options?.continueConversation
990
- ? await member.agent.continue(message)
991
- : await member.agent.run(message);
1023
+ ? await member.agent.continue(enrichedMessage)
1024
+ : await member.agent.run(enrichedMessage);
992
1025
  this.emitEvent({ type: TeamMessageType.TaskEnd, agentId, result });
993
1026
  this.recordProgressStep(
994
1027
  agentId,
@@ -1254,7 +1287,8 @@ export class AgentTeamsRuntime {
1254
1287
  if (!this.members.has(fromAgentId)) {
1255
1288
  throw new Error(`Unknown sender "${fromAgentId}"`);
1256
1289
  }
1257
- if (!this.members.has(toAgentId)) {
1290
+ const recipient = this.members.get(toAgentId);
1291
+ if (!recipient) {
1258
1292
  throw new Error(`Unknown recipient "${toAgentId}"`);
1259
1293
  }
1260
1294
  const message: TeamMailboxMessage = {
@@ -1272,6 +1306,13 @@ export class AgentTeamsRuntime {
1272
1306
  type: TeamMessageType.TeamMessage,
1273
1307
  message: { ...message },
1274
1308
  });
1309
+ if (
1310
+ recipient.role === "teammate" &&
1311
+ recipient.runningCount > 0 &&
1312
+ recipient.agent
1313
+ ) {
1314
+ recipient.pendingSteerMessage = `[MAILBOX] You got a message from ${fromAgentId}. Subject: "${subject}". Use the team_read_mailbox tool to read it at your convenience.`;
1315
+ }
1275
1316
  return { ...message };
1276
1317
  }
1277
1318
 
@@ -1279,15 +1320,14 @@ export class AgentTeamsRuntime {
1279
1320
  fromAgentId: string,
1280
1321
  subject: string,
1281
1322
  body: string,
1282
- options?: { includeLead?: boolean; taskId?: string },
1323
+ options?: { taskId?: string },
1283
1324
  ): TeamMailboxMessage[] {
1284
- const includeLead = options?.includeLead ?? false;
1285
1325
  const messages: TeamMailboxMessage[] = [];
1286
1326
  for (const member of this.members.values()) {
1287
1327
  if (member.agentId === fromAgentId) {
1288
1328
  continue;
1289
1329
  }
1290
- if (!includeLead && member.role === "lead") {
1330
+ if (member.role === "lead") {
1291
1331
  continue;
1292
1332
  }
1293
1333
  messages.push(
@@ -1458,7 +1498,13 @@ export class AgentTeamsRuntime {
1458
1498
 
1459
1499
  for (const member of this.members.values()) {
1460
1500
  if (member.role === "teammate") {
1461
- member.agent?.abort();
1501
+ try {
1502
+ member.agent?.abort();
1503
+ } catch (error) {
1504
+ if (!isAbortLikeError(error)) {
1505
+ throw error;
1506
+ }
1507
+ }
1462
1508
  }
1463
1509
  }
1464
1510
 
@@ -1526,7 +1572,7 @@ export class AgentTeamsRuntime {
1526
1572
  this.appendMissionLog({
1527
1573
  agentId,
1528
1574
  kind: "done",
1529
- summary: `Run completed after ${event.iterations} iteration(s)`,
1575
+ summary: `Completed a delegated run (${event.iterations} iterations)`,
1530
1576
  });
1531
1577
  return;
1532
1578
  }
@@ -1638,6 +1684,23 @@ export class AgentTeamsRuntime {
1638
1684
  });
1639
1685
  }
1640
1686
 
1687
+ private buildMailboxNotification(messages: TeamMailboxMessage[]): string {
1688
+ if (messages.length === 0) {
1689
+ return "";
1690
+ }
1691
+ const lines: string[] = [
1692
+ `[MAILBOX] You have ${messages.length} unread message(s):`,
1693
+ ];
1694
+ for (const msg of messages) {
1695
+ lines.push(
1696
+ `--- Message from ${msg.fromAgentId} | subject: ${msg.subject} ---`,
1697
+ );
1698
+ lines.push(msg.body);
1699
+ }
1700
+ lines.push("---");
1701
+ return lines.join("\n");
1702
+ }
1703
+
1641
1704
  private emitEvent(event: TeamEvent): void {
1642
1705
  try {
1643
1706
  this.onTeamEvent?.(event);
@@ -180,7 +180,6 @@ describe("createSpawnAgentTool", () => {
180
180
  {
181
181
  systemPrompt: "System",
182
182
  task: "Fail task",
183
- maxIterations: 6,
184
183
  },
185
184
  {
186
185
  agentId: "parent-2",
@@ -197,11 +196,6 @@ describe("createSpawnAgentTool", () => {
197
196
  error: expect.any(Error),
198
197
  }),
199
198
  );
200
- expect(agentConstructorSpy).toHaveBeenCalledWith(
201
- expect.objectContaining({
202
- maxIterations: 6,
203
- }),
204
- );
205
199
  });
206
200
 
207
201
  it("leaves maxIterations unset when neither input nor default is provided", async () => {
@@ -32,12 +32,6 @@ export const SpawnAgentInputSchema = z.object({
32
32
  .string()
33
33
  .describe("System prompt defining the sub-agent's behavior"),
34
34
  task: z.string().describe("Task for the sub-agent to complete"),
35
- maxIterations: z
36
- .number()
37
- .int()
38
- .min(1)
39
- .optional()
40
- .describe("Max iterations for the sub-agent"),
41
35
  });
42
36
 
43
37
  export type SpawnAgentInput = z.infer<typeof SpawnAgentInputSchema>;
@@ -136,7 +130,7 @@ export function createSpawnAgentTool(
136
130
  prompt: input.systemPrompt,
137
131
  configProvider: config.configProvider,
138
132
  tools,
139
- maxIterations: input.maxIterations ?? config.defaultMaxIterations,
133
+ maxIterations: config.defaultMaxIterations,
140
134
  parentAgentId: context.agentId,
141
135
  abortSignal: context.abortSignal,
142
136
  onEvent: config.onSubAgentEvent,
@@ -11,7 +11,7 @@ export function buildTeammateSystemPrompt(
11
11
  }
12
12
 
13
13
  return buildClineSystemPrompt({
14
- ide: config.clineIdeName?.trim() || "Terminal Shell",
14
+ ide: config.clineIdeName?.trim() || "Terminal",
15
15
  workspaceRoot: config.cwd?.trim() || "/",
16
16
  providerId: config.providerId,
17
17
  rules: `# Team Teammate Role\n${trimmedPrompt}`,
@@ -31,7 +31,7 @@ export function buildSubAgentSystemPrompt(
31
31
  }
32
32
 
33
33
  return buildClineSystemPrompt({
34
- ide: "Terminal Shell",
34
+ ide: config.clineIdeName || "Terminal",
35
35
  workspaceRoot: config.cwd?.trim() || "/",
36
36
  providerId: config.providerId,
37
37
  overridePrompt: trimmedPrompt,