@clinebot/core 0.0.33 → 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 (412) 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/auth/client.d.ts +19 -0
  5. package/dist/auth/client.d.ts.map +1 -1
  6. package/dist/auth/cline.d.ts.map +1 -1
  7. package/dist/auth/oca.d.ts.map +1 -1
  8. package/dist/auth/server.d.ts +32 -0
  9. package/dist/auth/server.d.ts.map +1 -1
  10. package/dist/auth/types.d.ts +29 -0
  11. package/dist/auth/types.d.ts.map +1 -1
  12. package/dist/extensions/config/agent-config-loader.d.ts +2 -2
  13. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  14. package/dist/extensions/config/agent-config-parser.d.ts +1 -1
  15. package/dist/extensions/config/agent-config-parser.d.ts.map +1 -1
  16. package/dist/extensions/config/hooks-config-loader.d.ts +2 -2
  17. package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -1
  18. package/dist/extensions/config/index.d.ts +3 -3
  19. package/dist/extensions/config/index.d.ts.map +1 -1
  20. package/dist/extensions/config/user-instruction-config-loader.d.ts +2 -2
  21. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  22. package/dist/extensions/index.d.ts +2 -1
  23. package/dist/extensions/index.d.ts.map +1 -1
  24. package/dist/extensions/plugin/plugin-config-loader.d.ts +2 -1
  25. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  26. package/dist/extensions/plugin/plugin-load-report.d.ts +19 -0
  27. package/dist/extensions/plugin/plugin-load-report.d.ts.map +1 -0
  28. package/dist/extensions/plugin/plugin-loader.d.ts +6 -0
  29. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  30. package/dist/extensions/plugin/plugin-sandbox.d.ts +2 -1
  31. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  32. package/dist/extensions/plugin-sandbox-bootstrap.js +242 -242
  33. package/dist/extensions/tools/constants.d.ts.map +1 -0
  34. package/dist/extensions/tools/definitions.d.ts.map +1 -0
  35. package/dist/extensions/tools/executors/apply-patch-parser.d.ts.map +1 -0
  36. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -0
  37. package/dist/extensions/tools/executors/bash.d.ts.map +1 -0
  38. package/dist/extensions/tools/executors/editor.d.ts.map +1 -0
  39. package/dist/extensions/tools/executors/file-read.d.ts.map +1 -0
  40. package/dist/extensions/tools/executors/index.d.ts.map +1 -0
  41. package/dist/extensions/tools/executors/search.d.ts.map +1 -0
  42. package/dist/extensions/tools/executors/web-fetch.d.ts.map +1 -0
  43. package/dist/extensions/tools/helpers.d.ts.map +1 -0
  44. package/dist/extensions/tools/index.d.ts.map +1 -0
  45. package/dist/{tools → extensions/tools}/model-tool-routing.d.ts +1 -1
  46. package/dist/extensions/tools/model-tool-routing.d.ts.map +1 -0
  47. package/dist/{tools → extensions/tools}/presets.d.ts +1 -2
  48. package/dist/extensions/tools/presets.d.ts.map +1 -0
  49. package/dist/extensions/tools/schemas.d.ts.map +1 -0
  50. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -0
  51. package/dist/extensions/tools/team/index.d.ts.map +1 -0
  52. package/dist/{team → extensions/tools/team}/multi-agent.d.ts +1 -3
  53. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -0
  54. package/dist/extensions/tools/team/projections.d.ts.map +1 -0
  55. package/dist/extensions/tools/team/runtime.d.ts.map +1 -0
  56. package/dist/{team → extensions/tools/team}/spawn-agent-tool.d.ts +0 -1
  57. package/dist/extensions/tools/team/spawn-agent-tool.d.ts.map +1 -0
  58. package/dist/extensions/tools/team/subagent-prompts.d.ts.map +1 -0
  59. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -0
  60. package/dist/{tools → extensions/tools}/types.d.ts +4 -3
  61. package/dist/extensions/tools/types.d.ts.map +1 -0
  62. package/dist/{runtime → hooks}/checkpoint-hooks.d.ts +7 -0
  63. package/dist/hooks/checkpoint-hooks.d.ts.map +1 -0
  64. package/dist/{runtime → hooks}/hook-file-hooks.d.ts +0 -2
  65. package/dist/hooks/hook-file-hooks.d.ts.map +1 -0
  66. package/dist/hooks/subprocess.d.ts +3 -130
  67. package/dist/hooks/subprocess.d.ts.map +1 -1
  68. package/dist/index.d.ts +38 -35
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +386 -384
  71. package/dist/runtime/history.d.ts +4 -0
  72. package/dist/runtime/history.d.ts.map +1 -0
  73. package/dist/runtime/host.d.ts +9 -0
  74. package/dist/runtime/host.d.ts.map +1 -0
  75. package/dist/{session → runtime}/rpc-runtime-ensure.d.ts +13 -1
  76. package/dist/{session → runtime}/rpc-runtime-ensure.d.ts.map +1 -1
  77. package/dist/{session → runtime}/rpc-spawn-lease.d.ts.map +1 -1
  78. package/dist/runtime/runtime-builder.d.ts +1 -1
  79. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  80. package/dist/{session/session-manager.d.ts → runtime/runtime-host.d.ts} +55 -12
  81. package/dist/runtime/runtime-host.d.ts.map +1 -0
  82. package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts +1 -1
  83. package/dist/{session → runtime}/runtime-oauth-token-manager.d.ts.map +1 -1
  84. package/dist/runtime/session-runtime.d.ts +2 -2
  85. package/dist/runtime/session-runtime.d.ts.map +1 -1
  86. package/dist/runtime/subprocess-sandbox.d.ts +2 -0
  87. package/dist/runtime/subprocess-sandbox.d.ts.map +1 -1
  88. package/dist/runtime/tool-approval.d.ts.map +1 -1
  89. package/dist/{session/session-agent-events.d.ts → services/agent-events.d.ts} +4 -4
  90. package/dist/services/agent-events.d.ts.map +1 -0
  91. package/dist/services/config.d.ts +3 -0
  92. package/dist/services/config.d.ts.map +1 -0
  93. package/dist/services/local-runtime-bootstrap.d.ts +41 -0
  94. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -0
  95. package/dist/services/providers/local-provider-registry.d.ts.map +1 -0
  96. package/dist/services/providers/local-provider-service.d.ts.map +1 -0
  97. package/dist/{session → services}/session-artifacts.d.ts +2 -4
  98. package/dist/services/session-artifacts.d.ts.map +1 -0
  99. package/dist/{session/utils/helpers.d.ts → services/session-data.d.ts} +19 -27
  100. package/dist/services/session-data.d.ts.map +1 -0
  101. package/dist/{session → services}/session-telemetry.d.ts +2 -2
  102. package/dist/services/session-telemetry.d.ts.map +1 -0
  103. package/dist/{storage → services/storage}/file-team-store.d.ts +2 -2
  104. package/dist/services/storage/file-team-store.d.ts.map +1 -0
  105. package/dist/{storage → services/storage}/provider-settings-legacy-migration.d.ts +1 -1
  106. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -0
  107. package/dist/{storage → services/storage}/provider-settings-manager.d.ts +1 -1
  108. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -0
  109. package/dist/{storage → services/storage}/sqlite-session-store.d.ts +3 -3
  110. package/dist/services/storage/sqlite-session-store.d.ts.map +1 -0
  111. package/dist/{storage → services/storage}/sqlite-team-store.d.ts +2 -2
  112. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -0
  113. package/dist/{storage → services/storage}/team-store.d.ts +1 -1
  114. package/dist/services/storage/team-store.d.ts.map +1 -0
  115. package/dist/services/telemetry/ITelemetryAdapter.d.ts.map +1 -0
  116. package/dist/services/telemetry/OpenTelemetryAdapter.d.ts.map +1 -0
  117. package/dist/services/telemetry/OpenTelemetryProvider.d.ts.map +1 -0
  118. package/dist/services/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
  119. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -0
  120. package/dist/services/telemetry/core-events.d.ts.map +1 -0
  121. package/dist/services/telemetry/distinct-id.d.ts.map +1 -0
  122. package/dist/services/telemetry/index.d.ts.map +1 -0
  123. package/dist/{telemetry → services/telemetry}/index.js +6 -6
  124. package/dist/{session/utils → services}/usage.d.ts +1 -1
  125. package/dist/services/usage.d.ts.map +1 -0
  126. package/dist/services/workspace/file-indexer.d.ts.map +1 -0
  127. package/dist/services/workspace/index.d.ts.map +1 -0
  128. package/dist/services/workspace/mention-enricher.d.ts.map +1 -0
  129. package/dist/services/workspace-manifest.d.ts.map +1 -0
  130. package/dist/session/file-session-service.d.ts +4 -1
  131. package/dist/session/file-session-service.d.ts.map +1 -1
  132. package/dist/session/persistence-service.d.ts +8 -6
  133. package/dist/session/persistence-service.d.ts.map +1 -1
  134. package/dist/session/rpc-session-service.d.ts +3 -0
  135. package/dist/session/rpc-session-service.d.ts.map +1 -1
  136. package/dist/session/session-service.d.ts +8 -9
  137. package/dist/session/session-service.d.ts.map +1 -1
  138. package/dist/session/session-team-coordination.d.ts +4 -4
  139. package/dist/session/session-team-coordination.d.ts.map +1 -1
  140. package/dist/session/sqlite-rpc-session-backend.d.ts.map +1 -1
  141. package/dist/{session/default-session-manager.d.ts → transports/local.d.ts} +24 -14
  142. package/dist/transports/local.d.ts.map +1 -0
  143. package/dist/transports/rpc.d.ts +51 -0
  144. package/dist/transports/rpc.d.ts.map +1 -0
  145. package/dist/transports/runtime-host-support.d.ts +21 -0
  146. package/dist/transports/runtime-host-support.d.ts.map +1 -0
  147. package/dist/types/chat-schema.d.ts.map +1 -0
  148. package/dist/types/config.d.ts +3 -2
  149. package/dist/types/config.d.ts.map +1 -1
  150. package/dist/{session/utils/types.d.ts → types/session.d.ts} +15 -6
  151. package/dist/types/session.d.ts.map +1 -0
  152. package/dist/types/sessions.d.ts +19 -0
  153. package/dist/types/sessions.d.ts.map +1 -1
  154. package/dist/types/storage.d.ts +1 -3
  155. package/dist/types/storage.d.ts.map +1 -1
  156. package/dist/types.d.ts +7 -6
  157. package/dist/types.d.ts.map +1 -1
  158. package/package.json +7 -12
  159. package/src/ClineCore.test.ts +95 -19
  160. package/src/ClineCore.ts +120 -50
  161. package/src/auth/client.test.ts +29 -0
  162. package/src/auth/client.ts +21 -0
  163. package/src/auth/cline.ts +3 -1
  164. package/src/auth/codex.ts +1 -1
  165. package/src/auth/oca.ts +3 -1
  166. package/src/auth/server.test.ts +287 -0
  167. package/src/auth/server.ts +50 -1
  168. package/src/auth/types.ts +29 -0
  169. package/src/extensions/config/agent-config-loader.test.ts +3 -3
  170. package/src/extensions/config/agent-config-loader.ts +1 -5
  171. package/src/extensions/config/agent-config-parser.ts +1 -1
  172. package/src/extensions/config/hooks-config-loader.ts +1 -2
  173. package/src/extensions/config/index.ts +0 -4
  174. package/src/extensions/config/user-instruction-config-loader.ts +0 -4
  175. package/src/extensions/index.ts +6 -0
  176. package/src/extensions/plugin/plugin-config-loader.test.ts +39 -0
  177. package/src/extensions/plugin/plugin-config-loader.ts +18 -10
  178. package/src/extensions/plugin/plugin-load-report.ts +20 -0
  179. package/src/extensions/plugin/plugin-loader.test.ts +45 -0
  180. package/src/extensions/plugin/plugin-loader.ts +57 -3
  181. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +158 -86
  182. package/src/extensions/plugin/plugin-sandbox.test.ts +70 -0
  183. package/src/extensions/plugin/plugin-sandbox.ts +17 -6
  184. package/src/{tools → extensions/tools}/definitions.ts +1 -1
  185. package/src/extensions/tools/executors/file-read.test.ts +125 -0
  186. package/src/{tools → extensions/tools}/executors/file-read.ts +29 -4
  187. package/src/{tools → extensions/tools}/executors/search.ts +1 -1
  188. package/src/{tools → extensions/tools}/model-tool-routing.ts +1 -1
  189. package/src/{tools → extensions/tools}/presets.ts +2 -3
  190. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +455 -0
  191. package/src/{team → extensions/tools/team}/multi-agent.ts +80 -17
  192. package/src/{team → extensions/tools/team}/spawn-agent-tool.test.ts +0 -6
  193. package/src/{team → extensions/tools/team}/spawn-agent-tool.ts +1 -7
  194. package/src/{team → extensions/tools/team}/subagent-prompts.ts +2 -2
  195. package/src/{team → extensions/tools/team}/team-tools.test.ts +146 -30
  196. package/src/{team → extensions/tools/team}/team-tools.ts +98 -69
  197. package/src/{tools → extensions/tools}/types.ts +5 -3
  198. package/src/{runtime → hooks}/checkpoint-hooks.ts +27 -0
  199. package/src/{runtime → hooks}/hook-file-hooks.test.ts +42 -7
  200. package/src/{runtime → hooks}/hook-file-hooks.ts +6 -11
  201. package/src/hooks/subprocess.ts +48 -257
  202. package/src/index.ts +178 -158
  203. package/src/runtime/history.test.ts +114 -0
  204. package/src/runtime/history.ts +237 -0
  205. package/src/runtime/host.test.ts +230 -0
  206. package/src/runtime/host.ts +362 -0
  207. package/src/runtime/rpc-runtime-ensure.test.ts +123 -0
  208. package/src/{session → runtime}/rpc-runtime-ensure.ts +165 -27
  209. package/src/{session → runtime}/rpc-spawn-lease.test.ts +33 -1
  210. package/src/{session → runtime}/rpc-spawn-lease.ts +54 -20
  211. package/src/runtime/runtime-builder.team-persistence.test.ts +6 -3
  212. package/src/runtime/runtime-builder.test.ts +101 -4
  213. package/src/runtime/runtime-builder.ts +125 -86
  214. package/src/runtime/runtime-host.ts +178 -0
  215. package/src/{session → runtime}/runtime-oauth-token-manager.ts +1 -1
  216. package/src/runtime/runtime-parity.test.ts +1 -1
  217. package/src/runtime/session-runtime.ts +2 -2
  218. package/src/runtime/subprocess-sandbox.ts +26 -23
  219. package/src/runtime/tool-approval.ts +13 -15
  220. package/src/{session/session-agent-events.ts → services/agent-events.ts} +7 -7
  221. package/src/services/config.ts +5 -0
  222. package/src/services/local-runtime-bootstrap.ts +280 -0
  223. package/src/{providers → services/providers}/local-provider-service.ts +4 -4
  224. package/src/{session → services}/session-artifacts.ts +23 -19
  225. package/src/{session/utils/helpers.test.ts → services/session-data.test.ts} +1 -1
  226. package/src/{session/utils/helpers.ts → services/session-data.ts} +76 -72
  227. package/src/{session → services}/session-telemetry.ts +7 -9
  228. package/src/services/storage/artifact-store.ts +1 -0
  229. package/src/{storage → services/storage}/file-team-store.ts +2 -2
  230. package/src/{storage → services/storage}/provider-settings-legacy-migration.test.ts +1 -1
  231. package/src/{storage → services/storage}/provider-settings-legacy-migration.ts +2 -2
  232. package/src/{storage → services/storage}/provider-settings-manager.ts +2 -2
  233. package/src/services/storage/session-store.ts +1 -0
  234. package/src/{storage → services/storage}/sqlite-session-store.ts +7 -12
  235. package/src/{storage → services/storage}/sqlite-team-store.ts +4 -4
  236. package/src/{storage → services/storage}/team-store.ts +1 -1
  237. package/src/{session/utils → services}/usage.ts +1 -1
  238. package/src/{input → services/workspace}/file-indexer.test.ts +30 -1
  239. package/src/{input → services/workspace}/file-indexer.ts +26 -2
  240. package/src/{input → services/workspace}/mention-enricher.test.ts +21 -0
  241. package/src/{input → services/workspace}/mention-enricher.ts +1 -1
  242. package/src/session/file-session-service.ts +9 -7
  243. package/src/session/index.ts +25 -17
  244. package/src/session/persistence-service.test.ts +121 -24
  245. package/src/session/persistence-service.ts +118 -102
  246. package/src/session/rpc-session-service.ts +9 -2
  247. package/src/session/session-service.team-persistence.test.ts +1 -1
  248. package/src/session/session-service.ts +32 -19
  249. package/src/session/session-team-coordination.ts +13 -6
  250. package/src/session/sqlite-rpc-session-backend.ts +4 -6
  251. package/src/session/workspace-manager.ts +1 -1
  252. package/src/{session/default-session-manager.e2e.test.ts → transports/local.e2e.test.ts} +13 -17
  253. package/src/{session/default-session-manager.test.ts → transports/local.test.ts} +316 -230
  254. package/src/{session/default-session-manager.ts → transports/local.ts} +138 -172
  255. package/src/transports/rpc.test.ts +82 -0
  256. package/src/transports/rpc.ts +665 -0
  257. package/src/transports/runtime-host-support.ts +86 -0
  258. package/src/types/config.ts +3 -2
  259. package/src/{session/utils/types.ts → types/session.ts} +18 -5
  260. package/src/types/sessions.ts +21 -0
  261. package/src/types/storage.ts +1 -6
  262. package/src/types.ts +25 -18
  263. package/dist/chat/chat-schema.d.ts.map +0 -1
  264. package/dist/input/file-indexer.d.ts.map +0 -1
  265. package/dist/input/index.d.ts.map +0 -1
  266. package/dist/input/mention-enricher.d.ts.map +0 -1
  267. package/dist/prompt/default-system.d.ts +0 -2
  268. package/dist/prompt/default-system.d.ts.map +0 -1
  269. package/dist/providers/local-provider-registry.d.ts.map +0 -1
  270. package/dist/providers/local-provider-service.d.ts.map +0 -1
  271. package/dist/runtime/checkpoint-hooks.d.ts.map +0 -1
  272. package/dist/runtime/hook-file-hooks.d.ts.map +0 -1
  273. package/dist/runtime/team-runtime-registry.d.ts +0 -13
  274. package/dist/runtime/team-runtime-registry.d.ts.map +0 -1
  275. package/dist/session/default-session-manager.d.ts.map +0 -1
  276. package/dist/session/session-agent-events.d.ts.map +0 -1
  277. package/dist/session/session-artifacts.d.ts.map +0 -1
  278. package/dist/session/session-config-builder.d.ts +0 -16
  279. package/dist/session/session-config-builder.d.ts.map +0 -1
  280. package/dist/session/session-host.d.ts +0 -15
  281. package/dist/session/session-host.d.ts.map +0 -1
  282. package/dist/session/session-manager.d.ts.map +0 -1
  283. package/dist/session/session-telemetry.d.ts.map +0 -1
  284. package/dist/session/utils/helpers.d.ts.map +0 -1
  285. package/dist/session/utils/types.d.ts.map +0 -1
  286. package/dist/session/utils/usage.d.ts.map +0 -1
  287. package/dist/session/workspace-manifest.d.ts.map +0 -1
  288. package/dist/storage/file-team-store.d.ts.map +0 -1
  289. package/dist/storage/provider-settings-legacy-migration.d.ts.map +0 -1
  290. package/dist/storage/provider-settings-manager.d.ts.map +0 -1
  291. package/dist/storage/sqlite-session-store.d.ts.map +0 -1
  292. package/dist/storage/sqlite-team-store.d.ts.map +0 -1
  293. package/dist/storage/team-store.d.ts.map +0 -1
  294. package/dist/team/delegated-agent.d.ts.map +0 -1
  295. package/dist/team/index.d.ts.map +0 -1
  296. package/dist/team/multi-agent.d.ts.map +0 -1
  297. package/dist/team/projections.d.ts.map +0 -1
  298. package/dist/team/runtime.d.ts.map +0 -1
  299. package/dist/team/spawn-agent-tool.d.ts.map +0 -1
  300. package/dist/team/subagent-prompts.d.ts.map +0 -1
  301. package/dist/team/team-tools.d.ts.map +0 -1
  302. package/dist/telemetry/ITelemetryAdapter.d.ts.map +0 -1
  303. package/dist/telemetry/OpenTelemetryAdapter.d.ts.map +0 -1
  304. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +0 -1
  305. package/dist/telemetry/TelemetryLoggerSink.d.ts.map +0 -1
  306. package/dist/telemetry/TelemetryService.d.ts.map +0 -1
  307. package/dist/telemetry/core-events.d.ts.map +0 -1
  308. package/dist/telemetry/distinct-id.d.ts.map +0 -1
  309. package/dist/telemetry/index.d.ts.map +0 -1
  310. package/dist/tools/constants.d.ts.map +0 -1
  311. package/dist/tools/definitions.d.ts.map +0 -1
  312. package/dist/tools/executors/apply-patch-parser.d.ts.map +0 -1
  313. package/dist/tools/executors/apply-patch.d.ts.map +0 -1
  314. package/dist/tools/executors/bash.d.ts.map +0 -1
  315. package/dist/tools/executors/editor.d.ts.map +0 -1
  316. package/dist/tools/executors/file-read.d.ts.map +0 -1
  317. package/dist/tools/executors/index.d.ts.map +0 -1
  318. package/dist/tools/executors/search.d.ts.map +0 -1
  319. package/dist/tools/executors/web-fetch.d.ts.map +0 -1
  320. package/dist/tools/helpers.d.ts.map +0 -1
  321. package/dist/tools/index.d.ts.map +0 -1
  322. package/dist/tools/model-tool-routing.d.ts.map +0 -1
  323. package/dist/tools/presets.d.ts.map +0 -1
  324. package/dist/tools/schemas.d.ts.map +0 -1
  325. package/dist/tools/types.d.ts.map +0 -1
  326. package/src/prompt/default-system.ts +0 -21
  327. package/src/runtime/team-runtime-registry.ts +0 -43
  328. package/src/session/session-config-builder.ts +0 -126
  329. package/src/session/session-host.test.ts +0 -89
  330. package/src/session/session-host.ts +0 -213
  331. package/src/session/session-manager.ts +0 -74
  332. package/src/storage/artifact-store.ts +0 -1
  333. package/src/storage/session-store.ts +0 -1
  334. package/src/team/multi-agent.lifecycle.test.ts +0 -201
  335. package/src/tools/executors/file-read.test.ts +0 -49
  336. /package/dist/{tools → extensions/tools}/constants.d.ts +0 -0
  337. /package/dist/{tools → extensions/tools}/definitions.d.ts +0 -0
  338. /package/dist/{tools → extensions/tools}/executors/apply-patch-parser.d.ts +0 -0
  339. /package/dist/{tools → extensions/tools}/executors/apply-patch.d.ts +0 -0
  340. /package/dist/{tools → extensions/tools}/executors/bash.d.ts +0 -0
  341. /package/dist/{tools → extensions/tools}/executors/editor.d.ts +0 -0
  342. /package/dist/{tools → extensions/tools}/executors/file-read.d.ts +0 -0
  343. /package/dist/{tools → extensions/tools}/executors/index.d.ts +0 -0
  344. /package/dist/{tools → extensions/tools}/executors/search.d.ts +0 -0
  345. /package/dist/{tools → extensions/tools}/executors/web-fetch.d.ts +0 -0
  346. /package/dist/{tools → extensions/tools}/helpers.d.ts +0 -0
  347. /package/dist/{tools → extensions/tools}/index.d.ts +0 -0
  348. /package/dist/{tools → extensions/tools}/schemas.d.ts +0 -0
  349. /package/dist/{team → extensions/tools/team}/delegated-agent.d.ts +0 -0
  350. /package/dist/{team → extensions/tools/team}/index.d.ts +0 -0
  351. /package/dist/{team → extensions/tools/team}/projections.d.ts +0 -0
  352. /package/dist/{team → extensions/tools/team}/runtime.d.ts +0 -0
  353. /package/dist/{team → extensions/tools/team}/subagent-prompts.d.ts +0 -0
  354. /package/dist/{team → extensions/tools/team}/team-tools.d.ts +0 -0
  355. /package/dist/{session → runtime}/rpc-spawn-lease.d.ts +0 -0
  356. /package/dist/{providers → services/providers}/local-provider-registry.d.ts +0 -0
  357. /package/dist/{providers → services/providers}/local-provider-service.d.ts +0 -0
  358. /package/dist/{telemetry → services/telemetry}/ITelemetryAdapter.d.ts +0 -0
  359. /package/dist/{telemetry → services/telemetry}/OpenTelemetryAdapter.d.ts +0 -0
  360. /package/dist/{telemetry → services/telemetry}/OpenTelemetryProvider.d.ts +0 -0
  361. /package/dist/{telemetry → services/telemetry}/TelemetryLoggerSink.d.ts +0 -0
  362. /package/dist/{telemetry → services/telemetry}/TelemetryService.d.ts +0 -0
  363. /package/dist/{telemetry → services/telemetry}/core-events.d.ts +0 -0
  364. /package/dist/{telemetry → services/telemetry}/distinct-id.d.ts +0 -0
  365. /package/dist/{telemetry → services/telemetry}/index.d.ts +0 -0
  366. /package/dist/{input → services/workspace}/file-indexer.d.ts +0 -0
  367. /package/dist/{input → services/workspace}/index.d.ts +0 -0
  368. /package/dist/{input → services/workspace}/mention-enricher.d.ts +0 -0
  369. /package/dist/{session → services}/workspace-manifest.d.ts +0 -0
  370. /package/dist/{chat → types}/chat-schema.d.ts +0 -0
  371. /package/src/{tools → extensions/tools}/constants.ts +0 -0
  372. /package/src/{tools → extensions/tools}/definitions.test.ts +0 -0
  373. /package/src/{tools → extensions/tools}/executors/apply-patch-parser.ts +0 -0
  374. /package/src/{tools → extensions/tools}/executors/apply-patch.ts +0 -0
  375. /package/src/{tools → extensions/tools}/executors/bash.test.ts +0 -0
  376. /package/src/{tools → extensions/tools}/executors/bash.ts +0 -0
  377. /package/src/{tools → extensions/tools}/executors/editor.test.ts +0 -0
  378. /package/src/{tools → extensions/tools}/executors/editor.ts +0 -0
  379. /package/src/{tools → extensions/tools}/executors/index.ts +0 -0
  380. /package/src/{tools → extensions/tools}/executors/web-fetch.ts +0 -0
  381. /package/src/{tools → extensions/tools}/helpers.ts +0 -0
  382. /package/src/{tools → extensions/tools}/index.ts +0 -0
  383. /package/src/{tools → extensions/tools}/model-tool-routing.test.ts +0 -0
  384. /package/src/{tools → extensions/tools}/presets.test.ts +0 -0
  385. /package/src/{tools → extensions/tools}/schemas.ts +0 -0
  386. /package/src/{team → extensions/tools/team}/delegated-agent.ts +0 -0
  387. /package/src/{team → extensions/tools/team}/index.ts +0 -0
  388. /package/src/{team → extensions/tools/team}/projections.ts +0 -0
  389. /package/src/{team → extensions/tools/team}/runtime.ts +0 -0
  390. /package/src/{runtime → hooks}/checkpoint-hooks.test.ts +0 -0
  391. /package/src/{session → runtime}/runtime-oauth-token-manager.test.ts +0 -0
  392. /package/src/{providers → services/providers}/local-provider-registry.ts +0 -0
  393. /package/src/{providers → services/providers}/local-provider-service.test.ts +0 -0
  394. /package/src/{storage → services/storage}/index.ts +0 -0
  395. /package/src/{storage → services/storage}/provider-settings-manager.test.ts +0 -0
  396. /package/src/{telemetry → services/telemetry}/ITelemetryAdapter.ts +0 -0
  397. /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.test.ts +0 -0
  398. /package/src/{telemetry → services/telemetry}/OpenTelemetryAdapter.ts +0 -0
  399. /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.test.ts +0 -0
  400. /package/src/{telemetry → services/telemetry}/OpenTelemetryProvider.ts +0 -0
  401. /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.test.ts +0 -0
  402. /package/src/{telemetry → services/telemetry}/TelemetryLoggerSink.ts +0 -0
  403. /package/src/{telemetry → services/telemetry}/TelemetryService.test.ts +0 -0
  404. /package/src/{telemetry → services/telemetry}/TelemetryService.ts +0 -0
  405. /package/src/{telemetry → services/telemetry}/core-events.ts +0 -0
  406. /package/src/{telemetry → services/telemetry}/distinct-id.test.ts +0 -0
  407. /package/src/{telemetry → services/telemetry}/distinct-id.ts +0 -0
  408. /package/src/{telemetry → services/telemetry}/index.ts +0 -0
  409. /package/src/{input → services/workspace}/file-indexer.d.ts +0 -0
  410. /package/src/{input → services/workspace}/index.ts +0 -0
  411. /package/src/{session → services}/workspace-manifest.ts +0 -0
  412. /package/src/{chat → types}/chat-schema.ts +0 -0
@@ -24,6 +24,10 @@ type RpcStartupLockRecord = {
24
24
  pid: number;
25
25
  address: string;
26
26
  acquiredAt: string;
27
+ updatedAt: string;
28
+ status: "starting" | "running";
29
+ resolvedAddress?: string;
30
+ serverId?: string;
27
31
  };
28
32
 
29
33
  export type RpcDiscoveryRecord = {
@@ -233,22 +237,54 @@ function isProbeBlocked(error: unknown): boolean {
233
237
  return isUnimplementedError(error) || isAuthenticationError(error);
234
238
  }
235
239
 
236
- async function hasRuntimeMethods(address: string): Promise<boolean> {
240
+ function formatProbeError(error: unknown): string {
241
+ if (error instanceof Error && error.message.trim()) {
242
+ return error.message.trim();
243
+ }
244
+ return String(error);
245
+ }
246
+
247
+ type RuntimeMethodsProbeResult = {
248
+ available: boolean;
249
+ reason?: string;
250
+ };
251
+
252
+ async function probeRuntimeMethods(
253
+ address: string,
254
+ ): Promise<RuntimeMethodsProbeResult> {
237
255
  const client = new RpcSessionClient({ address });
238
256
  try {
239
257
  try {
240
258
  await client.stopRuntimeSession("__rpc_probe__");
241
259
  } catch (error) {
242
- if (isProbeBlocked(error)) return false;
260
+ if (isProbeBlocked(error)) {
261
+ return {
262
+ available: false,
263
+ reason: `runtime probe blocked (${formatProbeError(error)})`,
264
+ };
265
+ }
243
266
  }
244
- return true;
267
+ return { available: true };
245
268
  } catch (error) {
246
- return !isProbeBlocked(error);
269
+ if (isProbeBlocked(error)) {
270
+ return {
271
+ available: false,
272
+ reason: `runtime probe blocked (${formatProbeError(error)})`,
273
+ };
274
+ }
275
+ return {
276
+ available: false,
277
+ reason: `runtime probe failed (${formatProbeError(error)})`,
278
+ };
247
279
  } finally {
248
280
  client.close();
249
281
  }
250
282
  }
251
283
 
284
+ async function hasRuntimeMethods(address: string): Promise<boolean> {
285
+ return (await probeRuntimeMethods(address)).available;
286
+ }
287
+
252
288
  export async function isCompatibleRuntime(address: string): Promise<boolean> {
253
289
  const health = await getRpcServerHealth(address);
254
290
  return (
@@ -258,6 +294,32 @@ export async function isCompatibleRuntime(address: string): Promise<boolean> {
258
294
  );
259
295
  }
260
296
 
297
+ async function describeRpcRuntimeReadinessFailure(
298
+ address: string,
299
+ ): Promise<string> {
300
+ let health: Awaited<ReturnType<typeof getRpcServerHealth>> | undefined;
301
+ try {
302
+ health = await getRpcServerHealth(address);
303
+ } catch (error) {
304
+ return `health probe failed (${formatProbeError(error)})`;
305
+ }
306
+ if (!health?.running) {
307
+ return "health probe reported no running server";
308
+ }
309
+ if (!isHealthCompatible(health)) {
310
+ const actualVersion =
311
+ typeof health.rpcVersion === "string" && health.rpcVersion.trim()
312
+ ? health.rpcVersion.trim()
313
+ : "unknown";
314
+ return `protocol mismatch (expected=${RPC_PROTOCOL_VERSION}, actual=${actualVersion})`;
315
+ }
316
+ const runtimeProbe = await probeRuntimeMethods(address);
317
+ if (!runtimeProbe.available) {
318
+ return runtimeProbe.reason ?? "runtime methods unavailable";
319
+ }
320
+ return "runtime did not become compatible before readiness deadline";
321
+ }
322
+
261
323
  async function isPortFree(host: string, port: number): Promise<boolean> {
262
324
  return new Promise<boolean>((resolve) => {
263
325
  const server = createServer();
@@ -294,13 +356,8 @@ function isPidAlive(pid: number | undefined): boolean {
294
356
 
295
357
  async function writeRpcStartupLockRecord(
296
358
  lockDir: string,
297
- address: string,
359
+ record: RpcStartupLockRecord,
298
360
  ): Promise<void> {
299
- const record: RpcStartupLockRecord = {
300
- pid: process.pid,
301
- address,
302
- acquiredAt: new Date().toISOString(),
303
- };
304
361
  await writeFile(
305
362
  join(lockDir, "owner.json"),
306
363
  JSON.stringify(record, null, 2),
@@ -318,7 +375,9 @@ async function readRpcStartupLockRecord(
318
375
  if (
319
376
  typeof parsed.pid !== "number" ||
320
377
  typeof parsed.address !== "string" ||
321
- typeof parsed.acquiredAt !== "string"
378
+ typeof parsed.acquiredAt !== "string" ||
379
+ typeof parsed.updatedAt !== "string" ||
380
+ (parsed.status !== "starting" && parsed.status !== "running")
322
381
  ) {
323
382
  return undefined;
324
383
  }
@@ -326,6 +385,14 @@ async function readRpcStartupLockRecord(
326
385
  pid: parsed.pid,
327
386
  address: parsed.address,
328
387
  acquiredAt: parsed.acquiredAt,
388
+ updatedAt: parsed.updatedAt,
389
+ status: parsed.status,
390
+ resolvedAddress:
391
+ typeof parsed.resolvedAddress === "string"
392
+ ? parsed.resolvedAddress
393
+ : undefined,
394
+ serverId:
395
+ typeof parsed.serverId === "string" ? parsed.serverId : undefined,
329
396
  };
330
397
  } catch {
331
398
  return undefined;
@@ -336,12 +403,59 @@ async function removeRpcStartupLockDir(lockDir: string): Promise<void> {
336
403
  await rm(lockDir, { recursive: true, force: true }).catch(() => {});
337
404
  }
338
405
 
406
+ async function updateRpcStartupLockRecord(
407
+ lockDir: string,
408
+ patch: Partial<Omit<RpcStartupLockRecord, "pid" | "address" | "acquiredAt">>,
409
+ ): Promise<void> {
410
+ const current = await readRpcStartupLockRecord(lockDir);
411
+ if (!current) {
412
+ return;
413
+ }
414
+ await writeRpcStartupLockRecord(lockDir, {
415
+ ...current,
416
+ ...patch,
417
+ updatedAt: new Date().toISOString(),
418
+ });
419
+ }
420
+
421
+ async function isRpcStartupLockStale(
422
+ existing: RpcStartupLockRecord | undefined,
423
+ ): Promise<boolean> {
424
+ const acquiredAtMs = existing ? new Date(existing.acquiredAt).getTime() : NaN;
425
+ if (
426
+ !existing ||
427
+ !Number.isFinite(acquiredAtMs) ||
428
+ Date.now() - acquiredAtMs > RPC_STARTUP_LOCK_MAX_AGE_MS ||
429
+ !isPidAlive(existing.pid)
430
+ ) {
431
+ return true;
432
+ }
433
+ if (existing.status !== "running") {
434
+ return false;
435
+ }
436
+ const targetAddress = existing.resolvedAddress?.trim() || existing.address;
437
+ try {
438
+ return !(await getRpcServerHealth(targetAddress))?.running;
439
+ } catch {
440
+ return true;
441
+ }
442
+ }
443
+
444
+ export type RpcStartupLockHandle = {
445
+ markRunning: (details?: {
446
+ resolvedAddress?: string;
447
+ serverId?: string;
448
+ }) => Promise<void>;
449
+ };
450
+
339
451
  export async function withRpcStartupLock<T>(
340
452
  address: string,
341
- action: () => Promise<T>,
453
+ action: (lock: RpcStartupLockHandle) => Promise<T>,
342
454
  ): Promise<T> {
343
455
  if (process.env[RPC_STARTUP_LOCK_BYPASS_ENV] === "1") {
344
- return await action();
456
+ return await action({
457
+ markRunning: async () => undefined,
458
+ });
345
459
  }
346
460
 
347
461
  const lockDir = getRpcStartupLockDir(address);
@@ -351,9 +465,23 @@ export async function withRpcStartupLock<T>(
351
465
  while (true) {
352
466
  try {
353
467
  await mkdir(lockDir, { recursive: false });
354
- await writeRpcStartupLockRecord(lockDir, address);
468
+ await writeRpcStartupLockRecord(lockDir, {
469
+ pid: process.pid,
470
+ address,
471
+ acquiredAt: new Date().toISOString(),
472
+ updatedAt: new Date().toISOString(),
473
+ status: "starting",
474
+ });
355
475
  try {
356
- return await action();
476
+ return await action({
477
+ markRunning: async (details) => {
478
+ await updateRpcStartupLockRecord(lockDir, {
479
+ status: "running",
480
+ resolvedAddress: details?.resolvedAddress?.trim() || undefined,
481
+ serverId: details?.serverId?.trim() || undefined,
482
+ });
483
+ },
484
+ });
357
485
  } finally {
358
486
  await removeRpcStartupLockDir(lockDir);
359
487
  }
@@ -361,22 +489,17 @@ export async function withRpcStartupLock<T>(
361
489
  if (errorCode(error) !== "EEXIST") throw error;
362
490
 
363
491
  const existing = await readRpcStartupLockRecord(lockDir);
364
- const acquiredAtMs = existing
365
- ? new Date(existing.acquiredAt).getTime()
366
- : Number.NaN;
367
- const isStale =
368
- !existing ||
369
- !Number.isFinite(acquiredAtMs) ||
370
- Date.now() - acquiredAtMs > RPC_STARTUP_LOCK_MAX_AGE_MS ||
371
- !isPidAlive(existing.pid);
492
+ const isStale = await isRpcStartupLockStale(existing);
372
493
  if (isStale) {
373
494
  await removeRpcStartupLockDir(lockDir);
374
495
  continue;
375
496
  }
376
497
 
377
498
  if (Date.now() - startedAt >= RPC_STARTUP_LOCK_WAIT_MS) {
499
+ const ownerPid =
500
+ typeof existing?.pid === "number" ? existing.pid : "unknown";
378
501
  throw new Error(
379
- `timed out waiting for rpc startup lock at ${address} (owner pid=${existing.pid})`,
502
+ `timed out waiting for rpc startup lock at ${address} (owner pid=${ownerPid})`,
380
503
  );
381
504
  }
382
505
  await sleep(RPC_STARTUP_LOCK_POLL_MS);
@@ -415,11 +538,18 @@ export async function resolveEnsuredRpcRuntime(
415
538
  options: {
416
539
  owner?: RpcOwnerContext;
417
540
  resolveOwner?: () => RpcOwnerContext;
541
+ /**
542
+ * When true, skip startup lock acquisition. Use this when the caller
543
+ * already holds the lock via {@link withRpcStartupLock} to avoid a
544
+ * deadlock from nested lock acquisition on the same address.
545
+ */
546
+ lockAlreadyHeld?: boolean;
418
547
  } = {},
419
548
  ): Promise<ResolveRpcRuntimeResult> {
420
549
  const owner =
421
550
  options.owner ?? options.resolveOwner?.() ?? resolveRpcOwnerContext();
422
- return await withRpcStartupLock(requestedAddress, async () => {
551
+
552
+ const core = async (): Promise<ResolveRpcRuntimeResult> => {
423
553
  const discovery = await readRpcDiscovery(owner);
424
554
  if (discovery?.address) {
425
555
  const discoveredHealth = await getRpcServerHealth(discovery.address);
@@ -475,7 +605,12 @@ export async function resolveEnsuredRpcRuntime(
475
605
  action: "new-port",
476
606
  owner,
477
607
  } satisfies ResolveRpcRuntimeResult;
478
- });
608
+ };
609
+
610
+ if (options.lockAlreadyHeld) {
611
+ return await core();
612
+ }
613
+ return await withRpcStartupLock(requestedAddress, core);
479
614
  }
480
615
 
481
616
  export async function waitForCompatibleRpcRuntime(
@@ -506,7 +641,10 @@ export async function ensureRpcRuntimeAddress(
506
641
  options.readinessCheck,
507
642
  ))
508
643
  ) {
509
- throw new Error(`failed to ensure rpc runtime at ${resolved.address}`);
644
+ const reason = await describeRpcRuntimeReadinessFailure(resolved.address);
645
+ throw new Error(
646
+ `failed to ensure rpc runtime at ${resolved.address}: ${reason}`,
647
+ );
510
648
  }
511
649
  const health = await getRpcServerHealth(resolved.address);
512
650
  await recordRpcDiscovery(resolved.owner, {
@@ -1,4 +1,5 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
1
+ import assert from "node:assert/strict";
2
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
3
  import os from "node:os";
3
4
  import path from "node:path";
4
5
  import { afterEach, describe, expect, it } from "vitest";
@@ -46,4 +47,35 @@ describe("tryAcquireRpcSpawnLease", () => {
46
47
  first?.release();
47
48
  second?.release();
48
49
  });
50
+
51
+ it("reclaims a leftover lease owned by the current process", () => {
52
+ const dataDir = mkdtempSync(path.join(os.tmpdir(), "rpc-spawn-lease-"));
53
+ tempDirs.push(dataDir);
54
+ process.env.CLINE_DATA_DIR = dataDir;
55
+
56
+ const first = tryAcquireRpcSpawnLease("127.0.0.1:4317");
57
+ expect(first).toBeDefined();
58
+ const leasePath = first?.path;
59
+ expect(leasePath).toBeTruthy();
60
+ first?.release();
61
+
62
+ writeFileSync(
63
+ leasePath!,
64
+ JSON.stringify({
65
+ address: "127.0.0.1:4317",
66
+ pid: process.pid,
67
+ createdAt: Date.now(),
68
+ }),
69
+ "utf8",
70
+ );
71
+
72
+ const second = tryAcquireRpcSpawnLease("127.0.0.1:4317");
73
+ assert(second);
74
+ expect(
75
+ JSON.parse(readFileSync(second.path, "utf8")) as { pid: number },
76
+ ).toMatchObject({
77
+ pid: process.pid,
78
+ });
79
+ second.release();
80
+ });
49
81
  });
@@ -10,7 +10,7 @@ import {
10
10
  import { dirname, resolve } from "node:path";
11
11
  import { resolveSessionDataDir } from "@clinebot/shared/storage";
12
12
 
13
- const DEFAULT_LEASE_TTL_MS = 15_000;
13
+ const DEFAULT_LEASE_TTL_MS = 5_000;
14
14
 
15
15
  interface RpcSpawnLeaseRecord {
16
16
  address: string;
@@ -23,6 +23,10 @@ export interface RpcSpawnLease {
23
23
  release: () => void;
24
24
  }
25
25
 
26
+ const ACTIVE_LEASE_RELEASES = new Set<() => void>();
27
+ const ACTIVE_LEASE_PATHS = new Set<string>();
28
+ let EXIT_CLEANUP_REGISTERED = false;
29
+
26
30
  function encodeAddress(address: string): string {
27
31
  return Buffer.from(address).toString("base64url");
28
32
  }
@@ -52,19 +56,43 @@ function shouldClearLease(path: string, ttlMs: number): boolean {
52
56
  try {
53
57
  const raw = readFileSync(path, "utf8");
54
58
  const parsed = JSON.parse(raw) as Partial<RpcSpawnLeaseRecord>;
59
+ const pid = Number(parsed.pid ?? 0);
55
60
  const createdAt = Number(parsed.createdAt ?? 0);
61
+ if (pid === process.pid && !ACTIVE_LEASE_PATHS.has(path)) {
62
+ return true;
63
+ }
56
64
  if (!Number.isFinite(createdAt) || createdAt <= 0) {
57
65
  return true;
58
66
  }
59
67
  if (Date.now() - createdAt > ttlMs) {
60
68
  return true;
61
69
  }
62
- return !isProcessAlive(Number(parsed.pid ?? 0));
70
+ return !isProcessAlive(pid);
63
71
  } catch {
64
72
  return true;
65
73
  }
66
74
  }
67
75
 
76
+ function cleanupActiveLeases(): void {
77
+ for (const release of [...ACTIVE_LEASE_RELEASES]) {
78
+ try {
79
+ release();
80
+ } catch {
81
+ // Best effort.
82
+ }
83
+ }
84
+ }
85
+
86
+ function registerExitCleanupOnce(): void {
87
+ if (EXIT_CLEANUP_REGISTERED) {
88
+ return;
89
+ }
90
+ EXIT_CLEANUP_REGISTERED = true;
91
+ process.once("exit", cleanupActiveLeases);
92
+ process.once("SIGINT", cleanupActiveLeases);
93
+ process.once("SIGTERM", cleanupActiveLeases);
94
+ }
95
+
68
96
  export function tryAcquireRpcSpawnLease(
69
97
  address: string,
70
98
  options?: { ttlMs?: number },
@@ -98,25 +126,31 @@ export function tryAcquireRpcSpawnLease(
98
126
  }
99
127
 
100
128
  let released = false;
129
+ const release = () => {
130
+ if (released) {
131
+ return;
132
+ }
133
+ released = true;
134
+ ACTIVE_LEASE_RELEASES.delete(release);
135
+ ACTIVE_LEASE_PATHS.delete(path);
136
+ try {
137
+ if (typeof fd === "number") {
138
+ closeSync(fd);
139
+ }
140
+ } catch {
141
+ // Best effort.
142
+ }
143
+ try {
144
+ rmSync(path, { force: true });
145
+ } catch {
146
+ // Best effort.
147
+ }
148
+ };
149
+ registerExitCleanupOnce();
150
+ ACTIVE_LEASE_RELEASES.add(release);
151
+ ACTIVE_LEASE_PATHS.add(path);
101
152
  return {
102
153
  path,
103
- release: () => {
104
- if (released) {
105
- return;
106
- }
107
- released = true;
108
- try {
109
- if (typeof fd === "number") {
110
- closeSync(fd);
111
- }
112
- } catch {
113
- // Best effort.
114
- }
115
- try {
116
- rmSync(path, { force: true });
117
- } catch {
118
- // Best effort.
119
- }
120
- },
154
+ release,
121
155
  };
122
156
  }
@@ -35,7 +35,7 @@ class MockAgentTeamsRuntime {
35
35
  shutdownTeammate = vi.fn();
36
36
  }
37
37
 
38
- vi.mock("../team", () => ({
38
+ vi.mock("../extensions/tools/team", () => ({
39
39
  AgentTeamsRuntime: MockAgentTeamsRuntime,
40
40
  bootstrapAgentTeams: bootstrapAgentTeamsMock,
41
41
  createDelegatedAgentConfigProvider: (config: Record<string, unknown>) => {
@@ -59,13 +59,16 @@ vi.mock("../team", () => ({
59
59
  },
60
60
  }));
61
61
 
62
- vi.mock("../default-tools", () => ({
62
+ vi.mock("../extensions/tools", () => ({
63
63
  ALL_DEFAULT_TOOL_NAMES: [],
64
64
  createBuiltinTools: createBuiltinToolsMock,
65
65
  ToolPresets: {
66
66
  development: {},
67
67
  readonly: {},
68
68
  },
69
+ resolveToolPresetName: () => "development",
70
+ resolveToolRoutingConfig: () => [],
71
+ DEFAULT_MODEL_TOOL_ROUTING_RULES: [],
69
72
  }));
70
73
 
71
74
  let teamStoreInstance: MockTeamStore | undefined;
@@ -100,7 +103,7 @@ class MockTeamStore {
100
103
  persistRuntime = vi.fn();
101
104
  }
102
105
 
103
- vi.mock("../storage/team-store", () => ({
106
+ vi.mock("../services/storage/team-store", () => ({
104
107
  createLocalTeamStore: () => new MockTeamStore(),
105
108
  }));
106
109
 
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import type { Tool } from "@clinebot/shared";
5
5
  import { describe, expect, it } from "vitest";
6
- import { TelemetryService } from "../telemetry/TelemetryService";
6
+ import { TelemetryService } from "../services/telemetry/TelemetryService";
7
7
  import type { CoreSessionConfig } from "../types/config";
8
8
  import { DefaultRuntimeBuilder } from "./runtime-builder";
9
9
 
@@ -83,8 +83,7 @@ describe("DefaultRuntimeBuilder", () => {
83
83
  it("uses yolo preset only when yolo mode is explicit", async () => {
84
84
  const runtime = await new DefaultRuntimeBuilder().build({
85
85
  config: makeBaseConfig({
86
- mode: "act",
87
- yolo: true,
86
+ mode: "yolo",
88
87
  }),
89
88
  defaultToolExecutors: {
90
89
  submit: async () => "submitted",
@@ -120,7 +119,7 @@ describe("DefaultRuntimeBuilder", () => {
120
119
  config: {
121
120
  ...makeBaseConfig({
122
121
  enableTools: false,
123
- yolo: true,
122
+ mode: "yolo",
124
123
  }),
125
124
  } as CoreSessionConfig,
126
125
  createSpawnTool: makeSpawnTool,
@@ -186,6 +185,22 @@ describe("DefaultRuntimeBuilder", () => {
186
185
  expect(runtime.tools).toEqual([]);
187
186
  });
188
187
 
188
+ it("omits tools disabled by policy from the advertised runtime tool list", async () => {
189
+ const runtime = await new DefaultRuntimeBuilder().build({
190
+ config: makeBaseConfig({
191
+ toolPolicies: {
192
+ run_commands: { enabled: false },
193
+ read_files: { enabled: false },
194
+ },
195
+ }),
196
+ });
197
+
198
+ const names = runtime.tools.map((tool) => tool.name);
199
+ expect(names).not.toContain("run_commands");
200
+ expect(names).not.toContain("read_files");
201
+ expect(names).toContain("search_codebase");
202
+ });
203
+
189
204
  it("adds spawn tool when enabled", async () => {
190
205
  const runtime = await new DefaultRuntimeBuilder().build({
191
206
  config: makeBaseConfig({
@@ -284,6 +299,88 @@ process.stdin.on("data", (chunk) => {
284
299
  }
285
300
  });
286
301
 
302
+ it("skips MCP settings tools when disableMcpSettingsTools is true", async () => {
303
+ const tempRoot = mkdtempSync(
304
+ join(tmpdir(), "runtime-builder-mcp-disabled-"),
305
+ );
306
+ const serverPath = join(tempRoot, "mock-mcp-server.js");
307
+ const settingsPath = join(tempRoot, "cline_mcp_settings.json");
308
+ const previousSettingsPath = process.env.CLINE_MCP_SETTINGS_PATH;
309
+
310
+ writeFileSync(
311
+ serverPath,
312
+ `let buffer = "";
313
+ function write(payload) {
314
+ const body = JSON.stringify(payload);
315
+ process.stdout.write("Content-Length: " + Buffer.byteLength(body, "utf8") + "\\r\\n\\r\\n" + body);
316
+ }
317
+ function handle(message) {
318
+ if (message.method === "initialize") {
319
+ write({ jsonrpc: "2.0", id: message.id, result: { protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: { name: "mock", version: "1.0.0" } } });
320
+ return;
321
+ }
322
+ if (message.method === "tools/list") {
323
+ write({ jsonrpc: "2.0", id: message.id, result: { tools: [{ name: "echo", description: "Echo tool", inputSchema: { type: "object", properties: { value: { type: "string" } }, required: [] } }] } });
324
+ return;
325
+ }
326
+ if (message.method === "tools/call") {
327
+ write({ jsonrpc: "2.0", id: message.id, result: { echoed: message.params?.arguments?.value ?? null } });
328
+ }
329
+ }
330
+ process.stdin.on("data", (chunk) => {
331
+ buffer += chunk.toString("utf8");
332
+ while (true) {
333
+ const separator = buffer.indexOf("\\r\\n\\r\\n");
334
+ if (separator < 0) break;
335
+ const header = buffer.slice(0, separator);
336
+ const match = header.match(/Content-Length:\\s*(\\d+)/i);
337
+ if (!match) throw new Error("missing content length");
338
+ const length = Number(match[1]);
339
+ const start = separator + 4;
340
+ const end = start + length;
341
+ if (buffer.length < end) break;
342
+ const body = buffer.slice(start, end);
343
+ buffer = buffer.slice(end);
344
+ const message = JSON.parse(body);
345
+ if (message.method === "notifications/initialized") continue;
346
+ handle(message);
347
+ }
348
+ });`,
349
+ "utf8",
350
+ );
351
+ writeFileSync(
352
+ settingsPath,
353
+ JSON.stringify(
354
+ {
355
+ mcpServers: {
356
+ mock: {
357
+ command: process.execPath,
358
+ args: [serverPath],
359
+ },
360
+ },
361
+ },
362
+ null,
363
+ 2,
364
+ ),
365
+ "utf8",
366
+ );
367
+
368
+ process.env.CLINE_MCP_SETTINGS_PATH = settingsPath;
369
+ try {
370
+ const runtime = await new DefaultRuntimeBuilder().build({
371
+ config: makeBaseConfig({
372
+ disableMcpSettingsTools: true,
373
+ }),
374
+ });
375
+ expect(runtime.tools.map((tool) => tool.name)).not.toContain(
376
+ "mock__echo",
377
+ );
378
+ await runtime.shutdown("test");
379
+ } finally {
380
+ process.env.CLINE_MCP_SETTINGS_PATH = previousSettingsPath;
381
+ }
382
+ });
383
+
287
384
  it("skips broken MCP servers without crashing", async () => {
288
385
  const tempRoot = mkdtempSync(join(tmpdir(), "runtime-builder-mcp-bad-"));
289
386
  const serverPath = join(tempRoot, "malformed-mcp-server.js");