@clinebot/core 0.0.28 → 0.0.30

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 (340) hide show
  1. package/README.md +7 -0
  2. package/dist/ClineCore.d.ts +28 -2
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts +1 -1
  5. package/dist/account/cline-account-service.d.ts.map +1 -1
  6. package/dist/account/index.d.ts +1 -1
  7. package/dist/account/index.d.ts.map +1 -1
  8. package/dist/account/types.d.ts +5 -0
  9. package/dist/account/types.d.ts.map +1 -1
  10. package/dist/auth/bounded-ttl-cache.d.ts +14 -0
  11. package/dist/auth/bounded-ttl-cache.d.ts.map +1 -0
  12. package/dist/auth/cline.d.ts +27 -2
  13. package/dist/auth/cline.d.ts.map +1 -1
  14. package/dist/auth/oca.d.ts.map +1 -1
  15. package/dist/chat/chat-schema.d.ts +11 -11
  16. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -0
  17. package/dist/{agents → extensions/config}/agent-config-parser.d.ts +2 -2
  18. package/dist/extensions/config/agent-config-parser.d.ts.map +1 -0
  19. package/dist/{agents → extensions/config}/hooks-config-loader.d.ts +1 -1
  20. package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -0
  21. package/dist/{agents → extensions/config}/index.d.ts +2 -4
  22. package/dist/extensions/config/index.d.ts.map +1 -0
  23. package/dist/{runtime/commands.d.ts → extensions/config/runtime-commands.d.ts} +2 -3
  24. package/dist/extensions/config/runtime-commands.d.ts.map +1 -0
  25. package/dist/extensions/config/unified-config-file-watcher.d.ts.map +1 -0
  26. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -0
  27. package/dist/extensions/context/agentic-compaction.d.ts +13 -0
  28. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -0
  29. package/dist/extensions/context/basic-compaction.d.ts +9 -0
  30. package/dist/extensions/context/basic-compaction.d.ts.map +1 -0
  31. package/dist/extensions/context/compaction-shared.d.ts +60 -0
  32. package/dist/extensions/context/compaction-shared.d.ts.map +1 -0
  33. package/dist/extensions/context/compaction.d.ts +20 -0
  34. package/dist/extensions/context/compaction.d.ts.map +1 -0
  35. package/dist/extensions/index.d.ts +5 -0
  36. package/dist/extensions/index.d.ts.map +1 -0
  37. package/dist/extensions/mcp/client.d.ts +3 -0
  38. package/dist/extensions/mcp/client.d.ts.map +1 -0
  39. package/dist/extensions/mcp/config-loader.d.ts.map +1 -0
  40. package/dist/extensions/mcp/index.d.ts +9 -0
  41. package/dist/extensions/mcp/index.d.ts.map +1 -0
  42. package/dist/{mcp → extensions/mcp}/manager.d.ts +1 -2
  43. package/dist/extensions/mcp/manager.d.ts.map +1 -0
  44. package/dist/extensions/mcp/name-transform.d.ts +3 -0
  45. package/dist/extensions/mcp/name-transform.d.ts.map +1 -0
  46. package/dist/extensions/mcp/policies.d.ts +15 -0
  47. package/dist/extensions/mcp/policies.d.ts.map +1 -0
  48. package/dist/extensions/mcp/tools.d.ts +4 -0
  49. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  50. package/dist/{mcp → extensions/mcp}/types.d.ts +29 -1
  51. package/dist/extensions/mcp/types.d.ts.map +1 -0
  52. package/dist/{agents → extensions/plugin}/plugin-config-loader.d.ts +1 -1
  53. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -0
  54. package/dist/{agents → extensions/plugin}/plugin-loader.d.ts +1 -1
  55. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -0
  56. package/dist/extensions/plugin/plugin-module-import.d.ts +5 -0
  57. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -0
  58. package/dist/{agents → extensions/plugin}/plugin-sandbox.d.ts +1 -1
  59. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -0
  60. package/dist/extensions/plugin-sandbox-bootstrap.js +485 -0
  61. package/dist/hooks/index.d.ts +4 -0
  62. package/dist/hooks/index.d.ts.map +1 -0
  63. package/dist/hooks/persistent.d.ts +64 -0
  64. package/dist/hooks/persistent.d.ts.map +1 -0
  65. package/dist/hooks/subprocess-runner.d.ts +22 -0
  66. package/dist/hooks/subprocess-runner.d.ts.map +1 -0
  67. package/dist/hooks/subprocess.d.ts +189 -0
  68. package/dist/hooks/subprocess.d.ts.map +1 -0
  69. package/dist/index.d.ts +22 -25
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +560 -447
  72. package/dist/prompt/default-system.d.ts +2 -0
  73. package/dist/prompt/default-system.d.ts.map +1 -0
  74. package/dist/providers/local-provider-service.d.ts +1 -1
  75. package/dist/providers/local-provider-service.d.ts.map +1 -1
  76. package/dist/runtime/checkpoint-hooks.d.ts +21 -0
  77. package/dist/runtime/checkpoint-hooks.d.ts.map +1 -0
  78. package/dist/runtime/hook-file-hooks.d.ts +1 -1
  79. package/dist/runtime/hook-file-hooks.d.ts.map +1 -1
  80. package/dist/runtime/rules.d.ts +1 -1
  81. package/dist/runtime/rules.d.ts.map +1 -1
  82. package/dist/runtime/runtime-builder.d.ts +1 -1
  83. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  84. package/dist/runtime/session-runtime.d.ts +25 -5
  85. package/dist/runtime/session-runtime.d.ts.map +1 -1
  86. package/dist/runtime/subprocess-sandbox.d.ts.map +1 -0
  87. package/dist/runtime/team-runtime-registry.d.ts +1 -1
  88. package/dist/runtime/team-runtime-registry.d.ts.map +1 -1
  89. package/dist/runtime/tool-approval.d.ts +1 -1
  90. package/dist/session/default-session-manager.d.ts +9 -3
  91. package/dist/session/default-session-manager.d.ts.map +1 -1
  92. package/dist/session/file-session-service.d.ts +1 -1
  93. package/dist/session/file-session-service.d.ts.map +1 -1
  94. package/dist/session/{unified-session-persistence-service.d.ts → persistence-service.d.ts} +11 -42
  95. package/dist/session/persistence-service.d.ts.map +1 -0
  96. package/dist/session/rpc-session-service.d.ts +1 -1
  97. package/dist/session/rpc-session-service.d.ts.map +1 -1
  98. package/dist/session/session-agent-events.d.ts +1 -1
  99. package/dist/session/session-artifacts.d.ts.map +1 -1
  100. package/dist/session/session-config-builder.d.ts.map +1 -1
  101. package/dist/session/session-graph.d.ts +1 -1
  102. package/dist/session/session-graph.d.ts.map +1 -1
  103. package/dist/session/session-host.d.ts.map +1 -1
  104. package/dist/session/session-manager.d.ts +6 -5
  105. package/dist/session/session-manager.d.ts.map +1 -1
  106. package/dist/session/session-manifest.d.ts +1 -1
  107. package/dist/session/session-service.d.ts +3 -2
  108. package/dist/session/session-service.d.ts.map +1 -1
  109. package/dist/session/session-team-coordination.d.ts +2 -1
  110. package/dist/session/session-team-coordination.d.ts.map +1 -1
  111. package/dist/session/utils/helpers.d.ts +51 -3
  112. package/dist/session/utils/helpers.d.ts.map +1 -1
  113. package/dist/session/utils/types.d.ts +41 -7
  114. package/dist/session/utils/types.d.ts.map +1 -1
  115. package/dist/session/workspace-manager.d.ts +1 -2
  116. package/dist/session/workspace-manager.d.ts.map +1 -1
  117. package/dist/session/workspace-manifest.d.ts +1 -22
  118. package/dist/session/workspace-manifest.d.ts.map +1 -1
  119. package/dist/storage/file-team-store.d.ts +2 -1
  120. package/dist/storage/file-team-store.d.ts.map +1 -1
  121. package/dist/storage/sqlite-team-store.d.ts +4 -1
  122. package/dist/storage/sqlite-team-store.d.ts.map +1 -1
  123. package/dist/storage/team-store.d.ts.map +1 -1
  124. package/dist/team/delegated-agent.d.ts +44 -0
  125. package/dist/team/delegated-agent.d.ts.map +1 -0
  126. package/dist/team/index.d.ts +1 -0
  127. package/dist/team/index.d.ts.map +1 -1
  128. package/dist/team/multi-agent.d.ts +229 -0
  129. package/dist/team/multi-agent.d.ts.map +1 -0
  130. package/dist/team/projections.d.ts +2 -2
  131. package/dist/team/projections.d.ts.map +1 -1
  132. package/dist/team/runtime.d.ts +5 -0
  133. package/dist/team/runtime.d.ts.map +1 -0
  134. package/dist/team/spawn-agent-tool.d.ts +85 -0
  135. package/dist/team/spawn-agent-tool.d.ts.map +1 -0
  136. package/dist/team/subagent-prompts.d.ts +4 -0
  137. package/dist/team/subagent-prompts.d.ts.map +1 -0
  138. package/dist/team/team-tools.d.ts +35 -0
  139. package/dist/team/team-tools.d.ts.map +1 -0
  140. package/dist/telemetry/OpenTelemetryProvider.d.ts +11 -1
  141. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
  142. package/dist/telemetry/{LoggerTelemetryAdapter.d.ts → TelemetryLoggerSink.d.ts} +10 -4
  143. package/dist/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
  144. package/dist/telemetry/TelemetryService.d.ts.map +1 -1
  145. package/dist/telemetry/index.js +15 -28
  146. package/dist/tools/definitions.d.ts +4 -3
  147. package/dist/tools/definitions.d.ts.map +1 -1
  148. package/dist/tools/index.d.ts +5 -5
  149. package/dist/tools/index.d.ts.map +1 -1
  150. package/dist/tools/model-tool-routing.d.ts.map +1 -1
  151. package/dist/tools/presets.d.ts +26 -0
  152. package/dist/tools/presets.d.ts.map +1 -1
  153. package/dist/tools/schemas.d.ts +8 -0
  154. package/dist/tools/schemas.d.ts.map +1 -1
  155. package/dist/tools/types.d.ts +23 -2
  156. package/dist/tools/types.d.ts.map +1 -1
  157. package/dist/types/config.d.ts +47 -3
  158. package/dist/types/config.d.ts.map +1 -1
  159. package/dist/types/events.d.ts +1 -1
  160. package/dist/types/provider-settings.d.ts +1 -1
  161. package/dist/types/provider-settings.d.ts.map +1 -1
  162. package/dist/types/storage.d.ts +2 -1
  163. package/dist/types/storage.d.ts.map +1 -1
  164. package/dist/types.d.ts +7 -16
  165. package/dist/types.d.ts.map +1 -1
  166. package/package.json +15 -12
  167. package/src/ClineCore.test.ts +150 -0
  168. package/src/ClineCore.ts +114 -8
  169. package/src/account/cline-account-service.test.ts +84 -0
  170. package/src/account/cline-account-service.ts +2 -2
  171. package/src/account/index.ts +1 -0
  172. package/src/account/types.ts +6 -0
  173. package/src/auth/bounded-ttl-cache.test.ts +38 -0
  174. package/src/auth/bounded-ttl-cache.ts +53 -0
  175. package/src/auth/cline.test.ts +173 -36
  176. package/src/auth/cline.ts +395 -93
  177. package/src/auth/oca.test.ts +125 -0
  178. package/src/auth/oca.ts +17 -4
  179. package/src/{agents → extensions/config}/agent-config-loader.test.ts +1 -1
  180. package/src/{agents → extensions/config}/agent-config-parser.ts +2 -2
  181. package/src/{agents → extensions/config}/hooks-config-loader.ts +1 -1
  182. package/src/{agents → extensions/config}/index.ts +7 -11
  183. package/src/{runtime/commands.test.ts → extensions/config/runtime-commands.test.ts} +20 -3
  184. package/src/{runtime/commands.ts → extensions/config/runtime-commands.ts} +1 -8
  185. package/src/{agents → extensions/config}/unified-config-file-watcher.ts +15 -2
  186. package/src/{agents → extensions/config}/user-instruction-config-loader.test.ts +90 -2
  187. package/src/{agents → extensions/config}/user-instruction-config-loader.ts +126 -12
  188. package/src/extensions/context/agentic-compaction.ts +119 -0
  189. package/src/extensions/context/basic-compaction.ts +275 -0
  190. package/src/extensions/context/compaction-shared.ts +458 -0
  191. package/src/extensions/context/compaction.test.ts +477 -0
  192. package/src/extensions/context/compaction.ts +203 -0
  193. package/src/extensions/index.ts +12 -0
  194. package/src/extensions/mcp/client.ts +420 -0
  195. package/src/{mcp → extensions/mcp}/index.ts +16 -0
  196. package/src/{mcp → extensions/mcp}/manager.test.ts +1 -2
  197. package/src/{mcp → extensions/mcp}/manager.ts +3 -5
  198. package/src/extensions/mcp/name-transform.ts +33 -0
  199. package/src/extensions/mcp/policies.ts +47 -0
  200. package/src/extensions/mcp/tools.ts +47 -0
  201. package/src/{mcp → extensions/mcp}/types.ts +35 -7
  202. package/src/{agents → extensions/plugin}/plugin-config-loader.test.ts +18 -13
  203. package/src/{agents → extensions/plugin}/plugin-config-loader.ts +1 -1
  204. package/src/{agents → extensions/plugin}/plugin-loader.test.ts +41 -4
  205. package/src/extensions/plugin/plugin-loader.ts +106 -0
  206. package/src/extensions/plugin/plugin-module-import.ts +278 -0
  207. package/src/{agents → extensions/plugin}/plugin-sandbox-bootstrap.ts +30 -92
  208. package/src/{agents → extensions/plugin}/plugin-sandbox.test.ts +60 -3
  209. package/src/{agents → extensions/plugin}/plugin-sandbox.ts +146 -56
  210. package/src/hooks/index.ts +25 -0
  211. package/src/hooks/persistent.ts +661 -0
  212. package/src/hooks/subprocess-runner.ts +196 -0
  213. package/src/hooks/subprocess.ts +669 -0
  214. package/src/index.ts +200 -118
  215. package/src/prompt/default-system.ts +21 -0
  216. package/src/providers/local-provider-registry.ts +1 -1
  217. package/src/providers/local-provider-service.test.ts +23 -2
  218. package/src/providers/local-provider-service.ts +2 -2
  219. package/src/runtime/checkpoint-hooks.test.ts +168 -0
  220. package/src/runtime/checkpoint-hooks.ts +186 -0
  221. package/src/runtime/hook-file-hooks.test.ts +40 -1
  222. package/src/runtime/hook-file-hooks.ts +35 -16
  223. package/src/runtime/index.ts +4 -19
  224. package/src/runtime/rules.ts +4 -1
  225. package/src/runtime/runtime-builder.team-persistence.test.ts +3 -6
  226. package/src/runtime/runtime-builder.test.ts +266 -160
  227. package/src/runtime/runtime-builder.ts +120 -47
  228. package/src/runtime/runtime-parity.test.ts +22 -22
  229. package/src/runtime/session-runtime.ts +36 -6
  230. package/src/runtime/{sandbox/subprocess-sandbox.ts → subprocess-sandbox.ts} +24 -3
  231. package/src/runtime/team-runtime-registry.ts +1 -4
  232. package/src/runtime/tool-approval.ts +1 -1
  233. package/src/session/default-session-manager.e2e.test.ts +2 -2
  234. package/src/session/default-session-manager.test.ts +553 -9
  235. package/src/session/default-session-manager.ts +162 -46
  236. package/src/session/file-session-service.ts +3 -3
  237. package/src/session/index.ts +6 -6
  238. package/src/session/persistence-service.test.ts +212 -0
  239. package/src/session/{unified-session-persistence-service.ts → persistence-service.ts} +106 -172
  240. package/src/session/rpc-session-service.ts +3 -3
  241. package/src/session/runtime-oauth-token-manager.ts +1 -1
  242. package/src/session/session-agent-events.ts +1 -1
  243. package/src/session/session-artifacts.ts +32 -4
  244. package/src/session/session-config-builder.ts +22 -9
  245. package/src/session/session-graph.ts +1 -1
  246. package/src/session/session-host.ts +19 -11
  247. package/src/session/session-manager.ts +11 -6
  248. package/src/session/session-service.team-persistence.test.ts +1 -1
  249. package/src/session/session-service.ts +6 -9
  250. package/src/session/session-team-coordination.ts +7 -3
  251. package/src/session/session-telemetry.ts +1 -1
  252. package/src/session/utils/helpers.test.ts +160 -0
  253. package/src/session/utils/helpers.ts +289 -42
  254. package/src/session/utils/types.ts +47 -7
  255. package/src/session/workspace-manager.ts +5 -3
  256. package/src/session/workspace-manifest.ts +3 -49
  257. package/src/storage/file-team-store.ts +2 -5
  258. package/src/storage/provider-settings-legacy-migration.ts +2 -2
  259. package/src/storage/provider-settings-manager.test.ts +1 -1
  260. package/src/storage/sqlite-team-store.ts +212 -125
  261. package/src/storage/team-store.ts +1 -5
  262. package/src/team/delegated-agent.ts +131 -0
  263. package/src/team/index.ts +1 -0
  264. package/src/team/multi-agent.lifecycle.test.ts +201 -0
  265. package/src/team/multi-agent.ts +1666 -0
  266. package/src/team/projections.ts +2 -4
  267. package/src/team/runtime.ts +54 -0
  268. package/src/team/spawn-agent-tool.test.ts +387 -0
  269. package/src/team/spawn-agent-tool.ts +207 -0
  270. package/src/team/subagent-prompts.ts +41 -0
  271. package/src/team/team-tools.test.ts +802 -0
  272. package/src/team/team-tools.ts +792 -0
  273. package/src/telemetry/OpenTelemetryAdapter.ts +1 -1
  274. package/src/telemetry/OpenTelemetryProvider.test.ts +216 -3
  275. package/src/telemetry/OpenTelemetryProvider.ts +110 -20
  276. package/src/telemetry/TelemetryLoggerSink.test.ts +42 -0
  277. package/src/telemetry/{LoggerTelemetryAdapter.ts → TelemetryLoggerSink.ts} +21 -14
  278. package/src/telemetry/TelemetryService.test.ts +7 -7
  279. package/src/telemetry/TelemetryService.ts +2 -4
  280. package/src/tools/definitions.test.ts +76 -0
  281. package/src/tools/definitions.ts +41 -2
  282. package/src/tools/executors/apply-patch.ts +1 -1
  283. package/src/tools/executors/editor.ts +1 -1
  284. package/src/tools/executors/file-read.ts +1 -1
  285. package/src/tools/executors/search.ts +1 -1
  286. package/src/tools/executors/web-fetch.ts +1 -1
  287. package/src/tools/index.ts +6 -1
  288. package/src/tools/model-tool-routing.ts +2 -0
  289. package/src/tools/presets.test.ts +8 -0
  290. package/src/tools/presets.ts +40 -2
  291. package/src/tools/schemas.ts +19 -0
  292. package/src/tools/types.ts +31 -2
  293. package/src/types/config.ts +61 -7
  294. package/src/types/events.ts +1 -1
  295. package/src/types/index.ts +0 -1
  296. package/src/types/provider-settings.ts +1 -1
  297. package/src/types/storage.ts +2 -5
  298. package/src/types.ts +32 -44
  299. package/dist/agents/agent-config-loader.d.ts.map +0 -1
  300. package/dist/agents/agent-config-parser.d.ts.map +0 -1
  301. package/dist/agents/hooks-config-loader.d.ts.map +0 -1
  302. package/dist/agents/index.d.ts.map +0 -1
  303. package/dist/agents/plugin-config-loader.d.ts.map +0 -1
  304. package/dist/agents/plugin-loader.d.ts.map +0 -1
  305. package/dist/agents/plugin-sandbox-bootstrap.js +0 -446
  306. package/dist/agents/plugin-sandbox.d.ts.map +0 -1
  307. package/dist/agents/unified-config-file-watcher.d.ts.map +0 -1
  308. package/dist/agents/user-instruction-config-loader.d.ts.map +0 -1
  309. package/dist/mcp/config-loader.d.ts.map +0 -1
  310. package/dist/mcp/index.d.ts +0 -5
  311. package/dist/mcp/index.d.ts.map +0 -1
  312. package/dist/mcp/manager.d.ts.map +0 -1
  313. package/dist/mcp/types.d.ts.map +0 -1
  314. package/dist/runtime/commands.d.ts.map +0 -1
  315. package/dist/runtime/sandbox/subprocess-sandbox.d.ts.map +0 -1
  316. package/dist/runtime/skills.d.ts +0 -14
  317. package/dist/runtime/skills.d.ts.map +0 -1
  318. package/dist/runtime/workflows.d.ts +0 -14
  319. package/dist/runtime/workflows.d.ts.map +0 -1
  320. package/dist/session/unified-session-persistence-service.d.ts.map +0 -1
  321. package/dist/telemetry/LoggerTelemetryAdapter.d.ts.map +0 -1
  322. package/dist/types/workspace.d.ts +0 -8
  323. package/dist/types/workspace.d.ts.map +0 -1
  324. package/src/agents/plugin-loader.ts +0 -175
  325. package/src/runtime/skills.ts +0 -44
  326. package/src/runtime/workflows.test.ts +0 -119
  327. package/src/runtime/workflows.ts +0 -45
  328. package/src/session/unified-session-persistence-service.test.ts +0 -85
  329. package/src/telemetry/LoggerTelemetryAdapter.test.ts +0 -42
  330. package/src/types/workspace.ts +0 -7
  331. /package/dist/{agents → extensions/config}/agent-config-loader.d.ts +0 -0
  332. /package/dist/{agents → extensions/config}/unified-config-file-watcher.d.ts +0 -0
  333. /package/dist/{agents → extensions/config}/user-instruction-config-loader.d.ts +0 -0
  334. /package/dist/{mcp → extensions/mcp}/config-loader.d.ts +0 -0
  335. /package/dist/runtime/{sandbox/subprocess-sandbox.d.ts → subprocess-sandbox.d.ts} +0 -0
  336. /package/src/{agents → extensions/config}/agent-config-loader.ts +0 -0
  337. /package/src/{agents → extensions/config}/hooks-config-loader.test.ts +0 -0
  338. /package/src/{agents → extensions/config}/unified-config-file-watcher.test.ts +0 -0
  339. /package/src/{mcp → extensions/mcp}/config-loader.test.ts +0 -0
  340. /package/src/{mcp → extensions/mcp}/config-loader.ts +0 -0
@@ -1,9 +1,10 @@
1
1
  import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
- import type { Tool } from "@clinebot/agents";
4
+ import type { Tool } from "@clinebot/shared";
5
5
  import { describe, expect, it } from "vitest";
6
6
  import { TelemetryService } from "../telemetry/TelemetryService";
7
+ import type { CoreSessionConfig } from "../types/config";
7
8
  import { DefaultRuntimeBuilder } from "./runtime-builder";
8
9
 
9
10
  function makeSpawnTool(): Tool {
@@ -15,19 +16,26 @@ function makeSpawnTool(): Tool {
15
16
  };
16
17
  }
17
18
 
19
+ function makeBaseConfig(
20
+ overrides: Partial<CoreSessionConfig> = {},
21
+ ): CoreSessionConfig {
22
+ return {
23
+ providerId: "anthropic",
24
+ modelId: "claude-sonnet-4-6",
25
+ apiKey: "key",
26
+ systemPrompt: "test",
27
+ cwd: process.cwd(),
28
+ enableTools: true,
29
+ enableSpawnAgent: false,
30
+ enableAgentTeams: false,
31
+ ...overrides,
32
+ };
33
+ }
34
+
18
35
  describe("DefaultRuntimeBuilder", () => {
19
- it("includes builtin tools when enabled", () => {
20
- const runtime = new DefaultRuntimeBuilder().build({
21
- config: {
22
- providerId: "anthropic",
23
- modelId: "claude-sonnet-4-6",
24
- apiKey: "key",
25
- systemPrompt: "test",
26
- cwd: process.cwd(),
27
- enableTools: true,
28
- enableSpawnAgent: false,
29
- enableAgentTeams: false,
30
- },
36
+ it("includes builtin tools when enabled", async () => {
37
+ const runtime = await new DefaultRuntimeBuilder().build({
38
+ config: makeBaseConfig(),
31
39
  });
32
40
 
33
41
  const names = runtime.tools.map((tool) => tool.name);
@@ -35,78 +43,99 @@ describe("DefaultRuntimeBuilder", () => {
35
43
  expect(names).not.toContain("spawn_agent");
36
44
  });
37
45
 
38
- it("forwards runtime logger for downstream agent creation", () => {
46
+ it("forwards runtime logger for downstream agent creation", async () => {
39
47
  const logger = {
40
- info: () => {},
48
+ debug: () => {},
49
+ log: () => {},
41
50
  };
42
- const runtime = new DefaultRuntimeBuilder().build({
43
- config: {
44
- providerId: "anthropic",
45
- modelId: "claude-sonnet-4-6",
46
- apiKey: "key",
47
- systemPrompt: "test",
48
- cwd: process.cwd(),
51
+ const runtime = await new DefaultRuntimeBuilder().build({
52
+ config: makeBaseConfig({
49
53
  enableTools: false,
50
- enableSpawnAgent: false,
51
- enableAgentTeams: false,
52
54
  logger,
53
- },
55
+ }),
54
56
  });
55
57
 
56
58
  expect(runtime.logger).toBe(logger);
57
59
  });
58
60
 
59
- it("forwards telemetry for downstream runtime consumers", () => {
61
+ it("forwards telemetry for downstream runtime consumers", async () => {
60
62
  const telemetry = new TelemetryService();
61
- const runtime = new DefaultRuntimeBuilder().build({
62
- config: {
63
- providerId: "anthropic",
64
- modelId: "claude-sonnet-4-6",
65
- apiKey: "key",
66
- systemPrompt: "test",
67
- cwd: process.cwd(),
63
+ const runtime = await new DefaultRuntimeBuilder().build({
64
+ config: makeBaseConfig({
68
65
  enableTools: false,
69
- enableSpawnAgent: false,
70
- enableAgentTeams: false,
71
66
  telemetry,
72
- },
67
+ }),
73
68
  });
74
69
 
75
70
  expect(runtime.telemetry).toBe(telemetry);
76
71
  });
77
72
 
78
- it("uses readonly preset in plan mode", () => {
79
- const runtime = new DefaultRuntimeBuilder().build({
80
- config: {
81
- providerId: "anthropic",
82
- modelId: "claude-sonnet-4-6",
83
- apiKey: "key",
84
- systemPrompt: "test",
85
- cwd: process.cwd(),
73
+ it("uses readonly preset in plan mode", async () => {
74
+ const runtime = await new DefaultRuntimeBuilder().build({
75
+ config: makeBaseConfig({
86
76
  mode: "plan",
87
- enableTools: true,
88
- enableSpawnAgent: false,
89
- enableAgentTeams: false,
77
+ }),
78
+ });
79
+
80
+ expect(runtime.tools.map((tool) => tool.name)).not.toContain("editor");
81
+ });
82
+
83
+ it("uses yolo preset only when yolo mode is explicit", async () => {
84
+ const runtime = await new DefaultRuntimeBuilder().build({
85
+ config: makeBaseConfig({
86
+ mode: "act",
87
+ yolo: true,
88
+ }),
89
+ defaultToolExecutors: {
90
+ submit: async () => "submitted",
90
91
  },
91
92
  });
92
93
 
93
94
  const names = runtime.tools.map((tool) => tool.name);
94
- expect(names).not.toContain("editor");
95
+ expect(names).not.toContain("ask_question");
96
+ expect(names).toContain("submit_and_exit");
97
+ });
98
+
99
+ it("does not infer yolo preset from auto-approval alone", async () => {
100
+ const runtime = await new DefaultRuntimeBuilder().build({
101
+ config: makeBaseConfig({
102
+ mode: "act",
103
+ toolPolicies: {
104
+ "*": { autoApprove: true },
105
+ },
106
+ }),
107
+ defaultToolExecutors: {
108
+ submit: async () => "submitted",
109
+ askQuestion: async () => "question",
110
+ },
111
+ });
112
+
113
+ const names = runtime.tools.map((tool) => tool.name);
114
+ expect(names).toContain("ask_question");
115
+ expect(names).not.toContain("submit_and_exit");
95
116
  });
96
117
 
97
- it("uses apply_patch instead of editor for codex/gpt model IDs in act mode", () => {
98
- const runtime = new DefaultRuntimeBuilder().build({
118
+ it("uses yolo preset runtime defaults for spawn and teams", async () => {
119
+ const runtime = await new DefaultRuntimeBuilder().build({
99
120
  config: {
121
+ ...makeBaseConfig({
122
+ enableTools: false,
123
+ yolo: true,
124
+ }),
125
+ } as CoreSessionConfig,
126
+ createSpawnTool: makeSpawnTool,
127
+ });
128
+
129
+ expect(runtime.tools.map((tool) => tool.name)).not.toContain("spawn_agent");
130
+ });
131
+
132
+ it("uses apply_patch instead of editor for codex/gpt model IDs in act mode", async () => {
133
+ const runtime = await new DefaultRuntimeBuilder().build({
134
+ config: makeBaseConfig({
100
135
  providerId: "openai",
101
136
  modelId: "openai/gpt-5.4",
102
- apiKey: "key",
103
- systemPrompt: "test",
104
- cwd: process.cwd(),
105
137
  mode: "act",
106
- enableTools: true,
107
- enableSpawnAgent: false,
108
- enableAgentTeams: false,
109
- },
138
+ }),
110
139
  });
111
140
 
112
141
  const names = runtime.tools.map((tool) => tool.name);
@@ -114,19 +143,11 @@ describe("DefaultRuntimeBuilder", () => {
114
143
  expect(names).not.toContain("editor");
115
144
  });
116
145
 
117
- it("keeps editor for non-codex/non-gpt model IDs in act mode", () => {
118
- const runtime = new DefaultRuntimeBuilder().build({
119
- config: {
120
- providerId: "anthropic",
121
- modelId: "claude-sonnet-4-6",
122
- apiKey: "key",
123
- systemPrompt: "test",
124
- cwd: process.cwd(),
146
+ it("keeps editor for non-codex/non-gpt model IDs in act mode", async () => {
147
+ const runtime = await new DefaultRuntimeBuilder().build({
148
+ config: makeBaseConfig({
125
149
  mode: "act",
126
- enableTools: true,
127
- enableSpawnAgent: false,
128
- enableAgentTeams: false,
129
- },
150
+ }),
130
151
  });
131
152
 
132
153
  const names = runtime.tools.map((tool) => tool.name);
@@ -134,18 +155,10 @@ describe("DefaultRuntimeBuilder", () => {
134
155
  expect(names).not.toContain("apply_patch");
135
156
  });
136
157
 
137
- it("applies custom tool routing rules from session config", () => {
138
- const runtime = new DefaultRuntimeBuilder().build({
139
- config: {
140
- providerId: "anthropic",
141
- modelId: "claude-sonnet-4-6",
142
- apiKey: "key",
143
- systemPrompt: "test",
144
- cwd: process.cwd(),
158
+ it("applies custom tool routing rules from session config", async () => {
159
+ const runtime = await new DefaultRuntimeBuilder().build({
160
+ config: makeBaseConfig({
145
161
  mode: "act",
146
- enableTools: true,
147
- enableSpawnAgent: false,
148
- enableAgentTeams: false,
149
162
  toolRoutingRules: [
150
163
  {
151
164
  mode: "act",
@@ -155,7 +168,7 @@ describe("DefaultRuntimeBuilder", () => {
155
168
  disableTools: ["editor"],
156
169
  },
157
170
  ],
158
- },
171
+ }),
159
172
  });
160
173
 
161
174
  const names = runtime.tools.map((tool) => tool.name);
@@ -163,59 +176,182 @@ describe("DefaultRuntimeBuilder", () => {
163
176
  expect(names).not.toContain("editor");
164
177
  });
165
178
 
166
- it("omits builtin tools when disabled", () => {
167
- const runtime = new DefaultRuntimeBuilder().build({
168
- config: {
169
- providerId: "anthropic",
170
- modelId: "claude-sonnet-4-6",
171
- apiKey: "key",
172
- systemPrompt: "test",
173
- cwd: process.cwd(),
179
+ it("omits builtin tools when disabled", async () => {
180
+ const runtime = await new DefaultRuntimeBuilder().build({
181
+ config: makeBaseConfig({
174
182
  enableTools: false,
175
- enableSpawnAgent: false,
176
- enableAgentTeams: false,
177
- },
183
+ }),
178
184
  });
179
185
 
180
186
  expect(runtime.tools).toEqual([]);
181
187
  });
182
188
 
183
- it("adds spawn tool when enabled", () => {
184
- const runtime = new DefaultRuntimeBuilder().build({
185
- config: {
186
- providerId: "anthropic",
187
- modelId: "claude-sonnet-4-6",
188
- apiKey: "key",
189
- systemPrompt: "test",
190
- cwd: process.cwd(),
189
+ it("adds spawn tool when enabled", async () => {
190
+ const runtime = await new DefaultRuntimeBuilder().build({
191
+ config: makeBaseConfig({
191
192
  enableTools: false,
192
193
  enableSpawnAgent: true,
193
- enableAgentTeams: false,
194
- },
194
+ }),
195
195
  createSpawnTool: makeSpawnTool,
196
196
  });
197
197
 
198
198
  expect(runtime.tools.map((tool) => tool.name)).toContain("spawn_agent");
199
199
  });
200
200
 
201
- it("provides a shutdown helper", () => {
202
- const runtime = new DefaultRuntimeBuilder().build({
203
- config: {
204
- providerId: "anthropic",
205
- modelId: "claude-sonnet-4-6",
206
- apiKey: "key",
207
- systemPrompt: "test",
208
- cwd: process.cwd(),
201
+ it("provides a shutdown helper", async () => {
202
+ const runtime = await new DefaultRuntimeBuilder().build({
203
+ config: makeBaseConfig({
209
204
  enableTools: false,
210
- enableSpawnAgent: false,
211
- enableAgentTeams: false,
212
- },
205
+ }),
213
206
  });
214
207
 
215
- expect(() => runtime.shutdown("test")).not.toThrow();
208
+ await expect(runtime.shutdown("test")).resolves.toBeUndefined();
216
209
  });
217
210
 
218
- it("includes skills tool when workspace skills are available", () => {
211
+ it("includes MCP tools from configured servers", async () => {
212
+ const tempRoot = mkdtempSync(join(tmpdir(), "runtime-builder-mcp-"));
213
+ const serverPath = join(tempRoot, "mock-mcp-server.js");
214
+ const settingsPath = join(tempRoot, "cline_mcp_settings.json");
215
+ const previousSettingsPath = process.env.CLINE_MCP_SETTINGS_PATH;
216
+
217
+ writeFileSync(
218
+ serverPath,
219
+ `let buffer = "";
220
+ function write(payload) {
221
+ const body = JSON.stringify(payload);
222
+ process.stdout.write("Content-Length: " + Buffer.byteLength(body, "utf8") + "\\r\\n\\r\\n" + body);
223
+ }
224
+ function handle(message) {
225
+ if (message.method === "initialize") {
226
+ write({ jsonrpc: "2.0", id: message.id, result: { protocolVersion: "2024-11-05", capabilities: { tools: {} }, serverInfo: { name: "mock", version: "1.0.0" } } });
227
+ return;
228
+ }
229
+ if (message.method === "tools/list") {
230
+ write({ jsonrpc: "2.0", id: message.id, result: { tools: [{ name: "echo", description: "Echo tool", inputSchema: { type: "object", properties: { value: { type: "string" } }, required: [] } }] } });
231
+ return;
232
+ }
233
+ if (message.method === "tools/call") {
234
+ write({ jsonrpc: "2.0", id: message.id, result: { echoed: message.params?.arguments?.value ?? null } });
235
+ }
236
+ }
237
+ process.stdin.on("data", (chunk) => {
238
+ buffer += chunk.toString("utf8");
239
+ while (true) {
240
+ const separator = buffer.indexOf("\\r\\n\\r\\n");
241
+ if (separator < 0) break;
242
+ const header = buffer.slice(0, separator);
243
+ const match = header.match(/Content-Length:\\s*(\\d+)/i);
244
+ if (!match) throw new Error("missing content length");
245
+ const length = Number(match[1]);
246
+ const start = separator + 4;
247
+ const end = start + length;
248
+ if (buffer.length < end) break;
249
+ const body = buffer.slice(start, end);
250
+ buffer = buffer.slice(end);
251
+ const message = JSON.parse(body);
252
+ if (message.method === "notifications/initialized") continue;
253
+ handle(message);
254
+ }
255
+ });`,
256
+ "utf8",
257
+ );
258
+ writeFileSync(
259
+ settingsPath,
260
+ JSON.stringify(
261
+ {
262
+ mcpServers: {
263
+ mock: {
264
+ command: process.execPath,
265
+ args: [serverPath],
266
+ },
267
+ },
268
+ },
269
+ null,
270
+ 2,
271
+ ),
272
+ "utf8",
273
+ );
274
+
275
+ process.env.CLINE_MCP_SETTINGS_PATH = settingsPath;
276
+ try {
277
+ const runtime = await new DefaultRuntimeBuilder().build({
278
+ config: makeBaseConfig(),
279
+ });
280
+ expect(runtime.tools.map((tool) => tool.name)).toContain("mock__echo");
281
+ await runtime.shutdown("test");
282
+ } finally {
283
+ process.env.CLINE_MCP_SETTINGS_PATH = previousSettingsPath;
284
+ }
285
+ });
286
+
287
+ it("skips broken MCP servers without crashing", async () => {
288
+ const tempRoot = mkdtempSync(join(tmpdir(), "runtime-builder-mcp-bad-"));
289
+ const serverPath = join(tempRoot, "malformed-mcp-server.js");
290
+ const settingsPath = join(tempRoot, "cline_mcp_settings.json");
291
+ const previousSettingsPath = process.env.CLINE_MCP_SETTINGS_PATH;
292
+
293
+ writeFileSync(
294
+ serverPath,
295
+ `process.stdin.once("data", () => {
296
+ process.stdout.write("Content-Length: 2\\r\\n\\r\\n{]");
297
+ });`,
298
+ "utf8",
299
+ );
300
+ writeFileSync(
301
+ settingsPath,
302
+ JSON.stringify(
303
+ {
304
+ mcpServers: {
305
+ broken: {
306
+ command: process.execPath,
307
+ args: [serverPath],
308
+ },
309
+ },
310
+ },
311
+ null,
312
+ 2,
313
+ ),
314
+ "utf8",
315
+ );
316
+
317
+ process.env.CLINE_MCP_SETTINGS_PATH = settingsPath;
318
+ try {
319
+ const runtime = await new DefaultRuntimeBuilder().build({
320
+ config: makeBaseConfig(),
321
+ });
322
+ const mcpTools = runtime.tools.filter((t) =>
323
+ t.name.startsWith("broken__"),
324
+ );
325
+ expect(mcpTools).toEqual([]);
326
+ await runtime.shutdown("test");
327
+ } finally {
328
+ process.env.CLINE_MCP_SETTINGS_PATH = previousSettingsPath;
329
+ }
330
+ });
331
+
332
+ it("skips invalid MCP settings file without crashing", async () => {
333
+ const tempRoot = mkdtempSync(
334
+ join(tmpdir(), "runtime-builder-mcp-invalid-"),
335
+ );
336
+ const settingsPath = join(tempRoot, "cline_mcp_settings.json");
337
+ const previousSettingsPath = process.env.CLINE_MCP_SETTINGS_PATH;
338
+
339
+ writeFileSync(settingsPath, "{ not valid json !!!", "utf8");
340
+
341
+ process.env.CLINE_MCP_SETTINGS_PATH = settingsPath;
342
+ try {
343
+ const runtime = await new DefaultRuntimeBuilder().build({
344
+ config: makeBaseConfig(),
345
+ });
346
+ const mcpTools = runtime.tools.filter((t) => t.name.includes("__"));
347
+ expect(mcpTools).toEqual([]);
348
+ await runtime.shutdown("test");
349
+ } finally {
350
+ process.env.CLINE_MCP_SETTINGS_PATH = previousSettingsPath;
351
+ }
352
+ });
353
+
354
+ it("includes skills tool when workspace skills are available", async () => {
219
355
  const cwd = mkdtempSync(join(tmpdir(), "runtime-builder-skills-"));
220
356
  const skillDir = join(cwd, ".cline", "skills", "commit");
221
357
  mkdirSync(skillDir, { recursive: true });
@@ -229,24 +365,15 @@ Use conventional commits.`,
229
365
  "utf8",
230
366
  );
231
367
 
232
- const runtime = new DefaultRuntimeBuilder().build({
233
- config: {
234
- providerId: "anthropic",
235
- modelId: "claude-sonnet-4-6",
236
- apiKey: "key",
237
- systemPrompt: "test",
238
- cwd,
239
- enableTools: true,
240
- enableSpawnAgent: false,
241
- enableAgentTeams: false,
242
- },
368
+ const runtime = await new DefaultRuntimeBuilder().build({
369
+ config: makeBaseConfig({ cwd }),
243
370
  });
244
371
 
245
372
  expect(runtime.tools.map((tool) => tool.name)).toContain("skills");
246
- runtime.shutdown("test");
373
+ await runtime.shutdown("test");
247
374
  });
248
375
 
249
- it("allows tool routing rules to disable skills even when skills exist", () => {
376
+ it("allows tool routing rules to disable skills even when skills exist", async () => {
250
377
  const cwd = mkdtempSync(
251
378
  join(tmpdir(), "runtime-builder-skills-routing-disabled-"),
252
379
  );
@@ -262,16 +389,11 @@ Use conventional commits.`,
262
389
  "utf8",
263
390
  );
264
391
 
265
- const runtime = new DefaultRuntimeBuilder().build({
266
- config: {
392
+ const runtime = await new DefaultRuntimeBuilder().build({
393
+ config: makeBaseConfig({
267
394
  providerId: "openrouter",
268
395
  modelId: "google/gemini-3-flash-preview",
269
- apiKey: "key",
270
- systemPrompt: "test",
271
396
  cwd,
272
- enableTools: true,
273
- enableSpawnAgent: false,
274
- enableAgentTeams: false,
275
397
  toolRoutingRules: [
276
398
  {
277
399
  mode: "act",
@@ -280,11 +402,11 @@ Use conventional commits.`,
280
402
  disableTools: ["skills"],
281
403
  },
282
404
  ],
283
- },
405
+ }),
284
406
  });
285
407
 
286
408
  expect(runtime.tools.map((tool) => tool.name)).not.toContain("skills");
287
- runtime.shutdown("test");
409
+ await runtime.shutdown("test");
288
410
  });
289
411
 
290
412
  it("marks configured but disabled skills in executor metadata", async () => {
@@ -311,17 +433,8 @@ Disabled skill.`,
311
433
  "utf8",
312
434
  );
313
435
 
314
- const runtime = new DefaultRuntimeBuilder().build({
315
- config: {
316
- providerId: "anthropic",
317
- modelId: "claude-sonnet-4-6",
318
- apiKey: "key",
319
- systemPrompt: "test",
320
- cwd,
321
- enableTools: true,
322
- enableSpawnAgent: false,
323
- enableAgentTeams: false,
324
- },
436
+ const runtime = await new DefaultRuntimeBuilder().build({
437
+ config: makeBaseConfig({ cwd }),
325
438
  });
326
439
 
327
440
  const skillsTool = runtime.tools.find((tool) => tool.name === "skills");
@@ -340,7 +453,7 @@ Disabled skill.`,
340
453
  );
341
454
  expect(disabledResult).toContain("configured but disabled");
342
455
 
343
- runtime.shutdown("test");
456
+ await runtime.shutdown("test");
344
457
  });
345
458
 
346
459
  it("scopes skills tool to session-configured skills", async () => {
@@ -366,18 +479,11 @@ Review skill.`,
366
479
  "utf8",
367
480
  );
368
481
 
369
- const runtime = new DefaultRuntimeBuilder().build({
370
- config: {
371
- providerId: "anthropic",
372
- modelId: "claude-sonnet-4-6",
373
- apiKey: "key",
374
- systemPrompt: "test",
482
+ const runtime = await new DefaultRuntimeBuilder().build({
483
+ config: makeBaseConfig({
375
484
  cwd,
376
- enableTools: true,
377
- enableSpawnAgent: false,
378
- enableAgentTeams: false,
379
485
  skills: ["commit"],
380
- },
486
+ }),
381
487
  });
382
488
 
383
489
  const skillsTool = runtime.tools.find((tool) => tool.name === "skills");
@@ -407,6 +513,6 @@ Review skill.`,
407
513
  expect(blocked).toContain('Skill "review" not found.');
408
514
  expect(blocked).toContain("Available skills: commit");
409
515
 
410
- runtime.shutdown("test");
516
+ await runtime.shutdown("test");
411
517
  });
412
518
  });