@clinebot/core 0.0.35 → 0.0.37

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 (441) hide show
  1. package/README.md +1 -2
  2. package/dist/ClineCore.d.ts +362 -39
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts.map +1 -1
  5. package/dist/account/index.d.ts +1 -1
  6. package/dist/account/index.d.ts.map +1 -1
  7. package/dist/account/rpc.d.ts +6 -6
  8. package/dist/account/rpc.d.ts.map +1 -1
  9. package/dist/cron/cron-event-ingress.d.ts +38 -0
  10. package/dist/cron/cron-event-ingress.d.ts.map +1 -0
  11. package/dist/cron/cron-materializer.d.ts +36 -0
  12. package/dist/cron/cron-materializer.d.ts.map +1 -0
  13. package/dist/cron/cron-reconciler.d.ts +62 -0
  14. package/dist/cron/cron-reconciler.d.ts.map +1 -0
  15. package/dist/cron/cron-report-writer.d.ts +41 -0
  16. package/dist/cron/cron-report-writer.d.ts.map +1 -0
  17. package/dist/cron/cron-runner.d.ts +43 -0
  18. package/dist/cron/cron-runner.d.ts.map +1 -0
  19. package/dist/cron/cron-schema.d.ts +3 -0
  20. package/dist/cron/cron-schema.d.ts.map +1 -0
  21. package/dist/cron/cron-service.d.ts +57 -0
  22. package/dist/cron/cron-service.d.ts.map +1 -0
  23. package/dist/cron/cron-spec-parser.d.ts +27 -0
  24. package/dist/cron/cron-spec-parser.d.ts.map +1 -0
  25. package/dist/cron/cron-watcher.d.ts +23 -0
  26. package/dist/cron/cron-watcher.d.ts.map +1 -0
  27. package/dist/cron/resource-limiter.d.ts +9 -0
  28. package/dist/cron/resource-limiter.d.ts.map +1 -0
  29. package/dist/cron/schedule-command-service.d.ts +10 -0
  30. package/dist/cron/schedule-command-service.d.ts.map +1 -0
  31. package/dist/cron/schedule-service.d.ts +100 -0
  32. package/dist/cron/schedule-service.d.ts.map +1 -0
  33. package/dist/cron/scheduler.d.ts +68 -0
  34. package/dist/cron/scheduler.d.ts.map +1 -0
  35. package/dist/cron/sqlite-cron-store.d.ts +230 -0
  36. package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
  37. package/dist/cron/sqlite-schedule-store.d.ts +52 -0
  38. package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
  39. package/dist/extensions/config/agent-config-loader.d.ts +4 -3
  40. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  41. package/dist/extensions/config/runtime-commands.d.ts +1 -0
  42. package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
  43. package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
  44. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  45. package/dist/extensions/context/agentic-compaction.d.ts +2 -2
  46. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
  47. package/dist/extensions/context/compaction-shared.d.ts +5 -4
  48. package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
  49. package/dist/extensions/context/compaction.d.ts.map +1 -1
  50. package/dist/extensions/plugin/plugin-config-loader.d.ts +15 -2
  51. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  52. package/dist/extensions/plugin/plugin-loader.d.ts +13 -7
  53. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  54. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
  55. package/dist/extensions/plugin/plugin-sandbox.d.ts +21 -2
  56. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  57. package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
  58. package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
  59. package/dist/extensions/plugin-sandbox-bootstrap.js +237 -276
  60. package/dist/extensions/tools/constants.d.ts +1 -0
  61. package/dist/extensions/tools/constants.d.ts.map +1 -1
  62. package/dist/extensions/tools/definitions.d.ts +3 -4
  63. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  64. package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
  65. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
  66. package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
  67. package/dist/extensions/tools/executors/search.d.ts +1 -1
  68. package/dist/extensions/tools/executors/search.d.ts.map +1 -1
  69. package/dist/extensions/tools/helpers.d.ts +1 -0
  70. package/dist/extensions/tools/helpers.d.ts.map +1 -1
  71. package/dist/extensions/tools/index.d.ts +3 -2
  72. package/dist/extensions/tools/index.d.ts.map +1 -1
  73. package/dist/extensions/tools/presets.d.ts +27 -44
  74. package/dist/extensions/tools/presets.d.ts.map +1 -1
  75. package/dist/extensions/tools/runtime.d.ts +25 -0
  76. package/dist/extensions/tools/runtime.d.ts.map +1 -0
  77. package/dist/extensions/tools/schemas.d.ts +25 -3
  78. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  79. package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
  80. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
  81. package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
  82. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
  83. package/dist/extensions/tools/team/team-tools.d.ts +1 -0
  84. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  85. package/dist/extensions/tools/types.d.ts +0 -5
  86. package/dist/extensions/tools/types.d.ts.map +1 -1
  87. package/dist/hooks/hook-bridge.d.ts +118 -0
  88. package/dist/hooks/hook-bridge.d.ts.map +1 -0
  89. package/dist/hooks/hook-file-hooks.d.ts +6 -2
  90. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  91. package/dist/hooks/hook-registry.d.ts +16 -0
  92. package/dist/hooks/hook-registry.d.ts.map +1 -0
  93. package/dist/hooks/index.d.ts +0 -1
  94. package/dist/hooks/index.d.ts.map +1 -1
  95. package/dist/hooks/subprocess.d.ts +8 -1
  96. package/dist/hooks/subprocess.d.ts.map +1 -1
  97. package/dist/hub/browser-websocket.d.ts +18 -0
  98. package/dist/hub/browser-websocket.d.ts.map +1 -0
  99. package/dist/hub/client.d.ts +51 -0
  100. package/dist/hub/client.d.ts.map +1 -0
  101. package/dist/hub/connect.d.ts +15 -0
  102. package/dist/hub/connect.d.ts.map +1 -0
  103. package/dist/hub/daemon-entry.d.ts +2 -0
  104. package/dist/hub/daemon-entry.d.ts.map +1 -0
  105. package/dist/hub/daemon-entry.js +1305 -0
  106. package/dist/hub/daemon.d.ts +5 -0
  107. package/dist/hub/daemon.d.ts.map +1 -0
  108. package/dist/hub/defaults.d.ts +17 -0
  109. package/dist/hub/defaults.d.ts.map +1 -0
  110. package/dist/hub/discovery.d.ts +29 -0
  111. package/dist/hub/discovery.d.ts.map +1 -0
  112. package/dist/hub/index.d.ts +15 -0
  113. package/dist/hub/index.d.ts.map +1 -0
  114. package/dist/hub/index.js +1294 -0
  115. package/dist/hub/native-transport.d.ts +17 -0
  116. package/dist/hub/native-transport.d.ts.map +1 -0
  117. package/dist/hub/runtime-handlers.d.ts +11 -0
  118. package/dist/hub/runtime-handlers.d.ts.map +1 -0
  119. package/dist/hub/server.d.ts +104 -0
  120. package/dist/hub/server.d.ts.map +1 -0
  121. package/dist/hub/session-client.d.ts +90 -0
  122. package/dist/hub/session-client.d.ts.map +1 -0
  123. package/dist/hub/start-shared-server.d.ts +19 -0
  124. package/dist/hub/start-shared-server.d.ts.map +1 -0
  125. package/dist/hub/transport.d.ts +8 -0
  126. package/dist/hub/transport.d.ts.map +1 -0
  127. package/dist/hub/ui-client.d.ts +45 -0
  128. package/dist/hub/ui-client.d.ts.map +1 -0
  129. package/dist/hub/workspace.d.ts +4 -0
  130. package/dist/hub/workspace.d.ts.map +1 -0
  131. package/dist/index.d.ts +29 -16
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +782 -471
  134. package/dist/llms/cline-recommended-models.d.ts +20 -0
  135. package/dist/llms/cline-recommended-models.d.ts.map +1 -0
  136. package/dist/llms/configured-provider-registry.d.ts +28 -0
  137. package/dist/llms/configured-provider-registry.d.ts.map +1 -0
  138. package/dist/llms/handler-factory.d.ts +16 -0
  139. package/dist/llms/handler-factory.d.ts.map +1 -0
  140. package/dist/llms/provider-defaults.d.ts +27 -0
  141. package/dist/llms/provider-defaults.d.ts.map +1 -0
  142. package/dist/llms/provider-settings.d.ts +245 -0
  143. package/dist/llms/provider-settings.d.ts.map +1 -0
  144. package/dist/llms/runtime-config.d.ts +4 -0
  145. package/dist/llms/runtime-config.d.ts.map +1 -0
  146. package/dist/llms/runtime-registry.d.ts +20 -0
  147. package/dist/llms/runtime-registry.d.ts.map +1 -0
  148. package/dist/llms/runtime-types.d.ts +85 -0
  149. package/dist/llms/runtime-types.d.ts.map +1 -0
  150. package/dist/runtime/agent-config-adapter.d.ts +148 -0
  151. package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
  152. package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
  153. package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
  154. package/dist/runtime/history.d.ts +6 -0
  155. package/dist/runtime/history.d.ts.map +1 -1
  156. package/dist/runtime/host.d.ts +1 -2
  157. package/dist/runtime/host.d.ts.map +1 -1
  158. package/dist/runtime/loop-detection.d.ts +59 -0
  159. package/dist/runtime/loop-detection.d.ts.map +1 -0
  160. package/dist/runtime/mistake-tracker.d.ts +69 -0
  161. package/dist/runtime/mistake-tracker.d.ts.map +1 -0
  162. package/dist/runtime/rules.d.ts +1 -0
  163. package/dist/runtime/rules.d.ts.map +1 -1
  164. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  165. package/dist/runtime/runtime-event-adapter.d.ts +102 -0
  166. package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
  167. package/dist/runtime/runtime-host.d.ts +49 -26
  168. package/dist/runtime/runtime-host.d.ts.map +1 -1
  169. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
  170. package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
  171. package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
  172. package/dist/runtime/session-runtime.d.ts +16 -21
  173. package/dist/runtime/session-runtime.d.ts.map +1 -1
  174. package/dist/runtime/user-input-builder.d.ts +24 -0
  175. package/dist/runtime/user-input-builder.d.ts.map +1 -0
  176. package/dist/services/global-settings.d.ts +12 -0
  177. package/dist/services/global-settings.d.ts.map +1 -0
  178. package/dist/services/index.js +28 -0
  179. package/dist/services/local-runtime-bootstrap.d.ts +9 -3
  180. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  181. package/dist/services/plugin-tools.d.ts +16 -0
  182. package/dist/services/plugin-tools.d.ts.map +1 -0
  183. package/dist/services/providers/local-provider-registry.d.ts +199 -23
  184. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  185. package/dist/services/providers/local-provider-service.d.ts +15 -13
  186. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  187. package/dist/services/session-data.d.ts +1 -1
  188. package/dist/services/session-data.d.ts.map +1 -1
  189. package/dist/services/session-telemetry.d.ts +7 -2
  190. package/dist/services/session-telemetry.d.ts.map +1 -1
  191. package/dist/services/storage/file-team-store.d.ts.map +1 -1
  192. package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
  193. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  194. package/dist/services/storage/provider-settings-manager.d.ts +1 -0
  195. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
  196. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
  197. package/dist/services/workspace-manifest.d.ts +11 -0
  198. package/dist/services/workspace-manifest.d.ts.map +1 -1
  199. package/dist/session/conversation-store.d.ts +30 -0
  200. package/dist/session/conversation-store.d.ts.map +1 -0
  201. package/dist/session/message-builder.d.ts +65 -0
  202. package/dist/session/message-builder.d.ts.map +1 -0
  203. package/dist/session/persistence-service.d.ts +11 -23
  204. package/dist/session/persistence-service.d.ts.map +1 -1
  205. package/dist/session/session-manifest-store.d.ts +22 -0
  206. package/dist/session/session-manifest-store.d.ts.map +1 -0
  207. package/dist/session/session-manifest.d.ts +1 -1
  208. package/dist/session/session-row.d.ts +93 -0
  209. package/dist/session/session-row.d.ts.map +1 -0
  210. package/dist/session/session-service.d.ts +2 -102
  211. package/dist/session/session-service.d.ts.map +1 -1
  212. package/dist/session/subagent-session-manager.d.ts +36 -0
  213. package/dist/session/subagent-session-manager.d.ts.map +1 -0
  214. package/dist/session/team-persistence-store.d.ts +24 -0
  215. package/dist/session/team-persistence-store.d.ts.map +1 -0
  216. package/dist/transports/hub.d.ts +58 -0
  217. package/dist/transports/hub.d.ts.map +1 -0
  218. package/dist/transports/local.d.ts +23 -9
  219. package/dist/transports/local.d.ts.map +1 -1
  220. package/dist/transports/remote.d.ts +10 -0
  221. package/dist/transports/remote.d.ts.map +1 -0
  222. package/dist/transports/runtime-host-support.d.ts +3 -2
  223. package/dist/transports/runtime-host-support.d.ts.map +1 -1
  224. package/dist/types/chat-schema.d.ts +15 -17
  225. package/dist/types/chat-schema.d.ts.map +1 -1
  226. package/dist/types/config.d.ts +17 -7
  227. package/dist/types/config.d.ts.map +1 -1
  228. package/dist/types/events.d.ts +7 -6
  229. package/dist/types/events.d.ts.map +1 -1
  230. package/dist/types/provider-settings.d.ts +4 -5
  231. package/dist/types/provider-settings.d.ts.map +1 -1
  232. package/dist/types/session.d.ts +7 -3
  233. package/dist/types/session.d.ts.map +1 -1
  234. package/dist/types.d.ts +11 -4
  235. package/dist/types.d.ts.map +1 -1
  236. package/package.json +20 -6
  237. package/src/ClineCore.ts +757 -44
  238. package/src/account/cline-account-service.ts +44 -6
  239. package/src/account/index.ts +3 -3
  240. package/src/account/rpc.ts +12 -12
  241. package/src/cron/cron-event-ingress.ts +357 -0
  242. package/src/cron/cron-materializer.ts +97 -0
  243. package/src/cron/cron-reconciler.ts +241 -0
  244. package/src/cron/cron-report-writer.ts +153 -0
  245. package/src/cron/cron-runner.ts +495 -0
  246. package/src/cron/cron-schema.ts +127 -0
  247. package/src/cron/cron-service.ts +163 -0
  248. package/src/cron/cron-spec-parser.ts +489 -0
  249. package/src/cron/cron-watcher.ts +102 -0
  250. package/src/cron/index.ts +15 -0
  251. package/src/cron/resource-limiter.ts +46 -0
  252. package/src/cron/schedule-command-service.ts +193 -0
  253. package/src/cron/schedule-service.ts +703 -0
  254. package/src/cron/scheduler.ts +772 -0
  255. package/src/cron/sqlite-cron-store.ts +1286 -0
  256. package/src/cron/sqlite-schedule-store.ts +708 -0
  257. package/src/extensions/config/agent-config-loader.ts +17 -7
  258. package/src/extensions/config/runtime-commands.ts +6 -0
  259. package/src/extensions/config/user-instruction-config-loader.ts +1 -0
  260. package/src/extensions/context/agentic-compaction.ts +3 -3
  261. package/src/extensions/context/basic-compaction.ts +2 -2
  262. package/src/extensions/context/compaction-shared.ts +5 -4
  263. package/src/extensions/context/compaction.ts +3 -3
  264. package/src/extensions/plugin/plugin-config-loader.ts +37 -2
  265. package/src/extensions/plugin/plugin-loader.ts +69 -9
  266. package/src/extensions/plugin/plugin-module-import.ts +0 -2
  267. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +243 -39
  268. package/src/extensions/plugin/plugin-sandbox.ts +173 -29
  269. package/src/extensions/plugin/plugin-targeting.ts +32 -0
  270. package/src/extensions/tools/constants.ts +2 -0
  271. package/src/extensions/tools/definitions.ts +61 -71
  272. package/src/extensions/tools/executors/apply-patch.ts +69 -80
  273. package/src/extensions/tools/executors/editor.ts +4 -3
  274. package/src/extensions/tools/executors/search.ts +195 -3
  275. package/src/extensions/tools/helpers.ts +24 -0
  276. package/src/extensions/tools/index.ts +11 -2
  277. package/src/extensions/tools/presets.ts +32 -47
  278. package/src/extensions/tools/runtime.ts +261 -0
  279. package/src/extensions/tools/schemas.ts +17 -20
  280. package/src/extensions/tools/team/delegated-agent.ts +8 -3
  281. package/src/extensions/tools/team/multi-agent.ts +135 -19
  282. package/src/extensions/tools/team/team-tools.ts +172 -91
  283. package/src/extensions/tools/types.ts +0 -6
  284. package/src/hooks/hook-bridge.ts +489 -0
  285. package/src/hooks/hook-file-hooks.ts +66 -5
  286. package/src/hooks/hook-registry.ts +257 -0
  287. package/src/hooks/index.ts +0 -7
  288. package/src/hooks/subprocess-runner.ts +1 -1
  289. package/src/hooks/subprocess.ts +9 -0
  290. package/src/hub/browser-websocket.ts +159 -0
  291. package/src/hub/client.ts +633 -0
  292. package/src/hub/connect.ts +156 -0
  293. package/src/hub/daemon-entry.ts +122 -0
  294. package/src/hub/daemon.ts +284 -0
  295. package/src/hub/defaults.ts +70 -0
  296. package/src/hub/discovery.ts +247 -0
  297. package/src/hub/index.ts +14 -0
  298. package/src/hub/native-transport.ts +31 -0
  299. package/src/hub/runtime-handlers.ts +141 -0
  300. package/src/hub/server.ts +2317 -0
  301. package/src/hub/session-client.ts +502 -0
  302. package/src/hub/start-shared-server.ts +61 -0
  303. package/src/hub/transport.ts +14 -0
  304. package/src/hub/ui-client.ts +126 -0
  305. package/src/hub/workspace.ts +19 -0
  306. package/src/index.ts +169 -68
  307. package/src/llms/cline-recommended-models.ts +167 -0
  308. package/src/llms/configured-provider-registry.ts +193 -0
  309. package/src/llms/handler-factory.ts +56 -0
  310. package/src/llms/provider-defaults.ts +653 -0
  311. package/src/llms/provider-settings.ts +310 -0
  312. package/src/llms/runtime-config.ts +43 -0
  313. package/src/llms/runtime-registry.ts +172 -0
  314. package/src/llms/runtime-types.ts +121 -0
  315. package/src/runtime/agent-config-adapter.ts +636 -0
  316. package/src/runtime/agent-runtime-config-builder.ts +205 -0
  317. package/src/runtime/error-feedback.ts +142 -0
  318. package/src/runtime/history.ts +137 -0
  319. package/src/runtime/host.ts +127 -267
  320. package/src/runtime/index.ts +1 -0
  321. package/src/runtime/loop-detection.ts +162 -0
  322. package/src/runtime/mistake-tracker.ts +221 -0
  323. package/src/runtime/rules.ts +12 -0
  324. package/src/runtime/runtime-builder.ts +85 -13
  325. package/src/runtime/runtime-event-adapter.ts +412 -0
  326. package/src/runtime/runtime-host.ts +134 -62
  327. package/src/runtime/runtime-oauth-token-manager.ts +11 -15
  328. package/src/runtime/session-runtime-orchestrator.ts +1253 -0
  329. package/src/runtime/session-runtime.ts +16 -26
  330. package/src/runtime/user-input-builder.ts +167 -0
  331. package/src/services/global-settings.ts +122 -0
  332. package/src/services/local-runtime-bootstrap.ts +175 -31
  333. package/src/services/plugin-tools.ts +86 -0
  334. package/src/services/providers/local-provider-registry.ts +277 -61
  335. package/src/services/providers/local-provider-service.ts +109 -44
  336. package/src/services/session-data.ts +18 -10
  337. package/src/services/session-telemetry.ts +6 -15
  338. package/src/services/storage/file-team-store.ts +1 -5
  339. package/src/services/storage/provider-settings-legacy-migration.ts +14 -51
  340. package/src/services/storage/provider-settings-manager.ts +17 -2
  341. package/src/services/storage/sqlite-team-store.ts +1 -5
  342. package/src/services/workspace-manifest.ts +18 -0
  343. package/src/session/conversation-store.ts +77 -0
  344. package/src/session/file-session-service.ts +1 -1
  345. package/src/session/index.ts +6 -27
  346. package/src/session/message-builder.ts +941 -0
  347. package/src/session/persistence-service.ts +119 -504
  348. package/src/session/session-manifest-store.ts +158 -0
  349. package/src/session/session-row.ts +199 -0
  350. package/src/session/session-service.ts +17 -376
  351. package/src/session/session-team-coordination.ts +1 -1
  352. package/src/session/subagent-session-manager.ts +397 -0
  353. package/src/session/team-persistence-store.ts +176 -0
  354. package/src/transports/hub.ts +1081 -0
  355. package/src/transports/local.ts +419 -93
  356. package/src/transports/remote.ts +27 -0
  357. package/src/transports/runtime-host-support.ts +63 -9
  358. package/src/types/chat-schema.ts +4 -5
  359. package/src/types/config.ts +17 -7
  360. package/src/types/events.ts +8 -6
  361. package/src/types/index.ts +3 -0
  362. package/src/types/provider-settings.ts +18 -7
  363. package/src/types/session.ts +7 -6
  364. package/src/types.ts +42 -2
  365. package/dist/hooks/persistent.d.ts +0 -64
  366. package/dist/hooks/persistent.d.ts.map +0 -1
  367. package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
  368. package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
  369. package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
  370. package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
  371. package/dist/services/telemetry/index.js +0 -15
  372. package/dist/session/rpc-session-service.d.ts +0 -16
  373. package/dist/session/rpc-session-service.d.ts.map +0 -1
  374. package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
  375. package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
  376. package/dist/transports/rpc.d.ts +0 -51
  377. package/dist/transports/rpc.d.ts.map +0 -1
  378. package/src/ClineCore.test.ts +0 -226
  379. package/src/account/cline-account-service.test.ts +0 -185
  380. package/src/account/featurebase-token.test.ts +0 -175
  381. package/src/account/rpc.test.ts +0 -63
  382. package/src/auth/bounded-ttl-cache.test.ts +0 -38
  383. package/src/auth/client.test.ts +0 -69
  384. package/src/auth/cline.test.ts +0 -267
  385. package/src/auth/codex.test.ts +0 -170
  386. package/src/auth/oca.test.ts +0 -340
  387. package/src/auth/server.test.ts +0 -287
  388. package/src/auth/utils.test.ts +0 -128
  389. package/src/extensions/config/agent-config-loader.test.ts +0 -236
  390. package/src/extensions/config/hooks-config-loader.test.ts +0 -20
  391. package/src/extensions/config/runtime-commands.test.ts +0 -115
  392. package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
  393. package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
  394. package/src/extensions/context/compaction.test.ts +0 -483
  395. package/src/extensions/mcp/config-loader.test.ts +0 -238
  396. package/src/extensions/mcp/manager.test.ts +0 -105
  397. package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
  398. package/src/extensions/plugin/plugin-loader.test.ts +0 -292
  399. package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
  400. package/src/extensions/tools/definitions.test.ts +0 -780
  401. package/src/extensions/tools/executors/bash.test.ts +0 -87
  402. package/src/extensions/tools/executors/editor.test.ts +0 -35
  403. package/src/extensions/tools/executors/file-read.test.ts +0 -125
  404. package/src/extensions/tools/model-tool-routing.test.ts +0 -86
  405. package/src/extensions/tools/presets.test.ts +0 -70
  406. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
  407. package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
  408. package/src/extensions/tools/team/team-tools.test.ts +0 -918
  409. package/src/hooks/checkpoint-hooks.test.ts +0 -168
  410. package/src/hooks/hook-file-hooks.test.ts +0 -311
  411. package/src/hooks/persistent.ts +0 -661
  412. package/src/runtime/history.test.ts +0 -114
  413. package/src/runtime/host.test.ts +0 -230
  414. package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
  415. package/src/runtime/rpc-runtime-ensure.ts +0 -659
  416. package/src/runtime/rpc-spawn-lease.test.ts +0 -81
  417. package/src/runtime/rpc-spawn-lease.ts +0 -156
  418. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
  419. package/src/runtime/runtime-builder.test.ts +0 -615
  420. package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
  421. package/src/runtime/runtime-parity.test.ts +0 -143
  422. package/src/services/providers/local-provider-service.test.ts +0 -1062
  423. package/src/services/session-data.test.ts +0 -160
  424. package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
  425. package/src/services/storage/provider-settings-manager.test.ts +0 -191
  426. package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  427. package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
  428. package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
  429. package/src/services/telemetry/TelemetryService.test.ts +0 -134
  430. package/src/services/telemetry/distinct-id.test.ts +0 -57
  431. package/src/services/workspace/file-indexer.d.ts +0 -11
  432. package/src/services/workspace/file-indexer.test.ts +0 -156
  433. package/src/services/workspace/mention-enricher.test.ts +0 -106
  434. package/src/session/persistence-service.test.ts +0 -300
  435. package/src/session/rpc-session-service.ts +0 -114
  436. package/src/session/session-service.team-persistence.test.ts +0 -48
  437. package/src/session/sqlite-rpc-session-backend.ts +0 -301
  438. package/src/transports/local.e2e.test.ts +0 -380
  439. package/src/transports/local.test.ts +0 -2559
  440. package/src/transports/rpc.test.ts +0 -82
  441. package/src/transports/rpc.ts +0 -665
@@ -1,1062 +0,0 @@
1
- import { mkdtempSync, rmSync } from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import * as LlmsModels from "@clinebot/llms";
5
- import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
- import { ProviderSettingsManager } from "../storage/provider-settings-manager";
7
- import {
8
- readModelsFile,
9
- resolveModelsRegistryPath,
10
- } from "./local-provider-registry";
11
- import {
12
- addLocalProvider,
13
- deleteLocalProvider,
14
- getLocalProviderModels,
15
- listLocalProviders,
16
- normalizeOAuthProvider,
17
- resolveLocalClineAuthToken,
18
- saveLocalProviderSettings,
19
- updateLocalProvider,
20
- } from "./local-provider-service";
21
-
22
- // ---------------------------------------------------------------------------
23
- // Helpers
24
- // ---------------------------------------------------------------------------
25
-
26
- function makeTempManager(): {
27
- manager: ProviderSettingsManager;
28
- cleanup: () => void;
29
- } {
30
- const dir = mkdtempSync(
31
- path.join(os.tmpdir(), "local-provider-service-test-"),
32
- );
33
- const manager = new ProviderSettingsManager({
34
- filePath: path.join(dir, "providers.json"),
35
- });
36
- return {
37
- manager,
38
- cleanup: () => rmSync(dir, { recursive: true, force: true }),
39
- };
40
- }
41
-
42
- // ---------------------------------------------------------------------------
43
- // Shared state reset
44
- // ---------------------------------------------------------------------------
45
-
46
- afterEach(() => {
47
- LlmsModels.resetRegistry();
48
- vi.restoreAllMocks();
49
- vi.unstubAllGlobals();
50
- });
51
-
52
- // ===========================================================================
53
- // extractModelIdsFromPayload — tested indirectly via addLocalProvider
54
- // ===========================================================================
55
-
56
- describe("addLocalProvider – model ID parsing via modelsSourceUrl", () => {
57
- let manager: ProviderSettingsManager;
58
- let cleanup: () => void;
59
-
60
- beforeEach(() => {
61
- ({ manager, cleanup } = makeTempManager());
62
- });
63
-
64
- afterEach(() => cleanup());
65
-
66
- it("parses a flat array payload from modelsSourceUrl", async () => {
67
- const mockFetch = vi.fn().mockResolvedValue({
68
- ok: true,
69
- json: async () => ["alpha", "beta", "gamma"],
70
- });
71
- vi.stubGlobal("fetch", mockFetch);
72
-
73
- const result = await addLocalProvider(manager, {
74
- providerId: "flat-array-provider",
75
- name: "Flat Array",
76
- baseUrl: "https://example.invalid/v1",
77
- models: [],
78
- modelsSourceUrl: "https://example.invalid/models",
79
- });
80
-
81
- expect(result.modelsCount).toBe(3);
82
- const { models } = await getLocalProviderModels("flat-array-provider");
83
- expect(models.map((m) => m.id).sort()).toEqual(["alpha", "beta", "gamma"]);
84
- });
85
-
86
- it("parses a { data: [...] } payload from modelsSourceUrl", async () => {
87
- vi.stubGlobal(
88
- "fetch",
89
- vi.fn().mockResolvedValue({
90
- ok: true,
91
- json: async () => ({ data: [{ id: "model-x" }, { id: "model-y" }] }),
92
- }),
93
- );
94
-
95
- await addLocalProvider(manager, {
96
- providerId: "data-array-provider",
97
- name: "Data Array",
98
- baseUrl: "https://example.invalid/v1",
99
- models: [],
100
- modelsSourceUrl: "https://example.invalid/models",
101
- });
102
-
103
- const { models } = await getLocalProviderModels("data-array-provider");
104
- expect(models.map((m) => m.id).sort()).toEqual(["model-x", "model-y"]);
105
- });
106
-
107
- it("parses a { models: { id1: {}, id2: {} } } object-keyed payload", async () => {
108
- vi.stubGlobal(
109
- "fetch",
110
- vi.fn().mockResolvedValue({
111
- ok: true,
112
- json: async () => ({ models: { "key-a": {}, "key-b": {} } }),
113
- }),
114
- );
115
-
116
- await addLocalProvider(manager, {
117
- providerId: "obj-keys-provider",
118
- name: "Object Keys",
119
- baseUrl: "https://example.invalid/v1",
120
- models: [],
121
- modelsSourceUrl: "https://example.invalid/models",
122
- });
123
-
124
- const { models } = await getLocalProviderModels("obj-keys-provider");
125
- expect(models.map((m) => m.id).sort()).toEqual(["key-a", "key-b"]);
126
- });
127
-
128
- it("parses a { providers: { <id>: { models: [...] } } } nested payload", async () => {
129
- vi.stubGlobal(
130
- "fetch",
131
- vi.fn().mockResolvedValue({
132
- ok: true,
133
- json: async () => ({
134
- providers: {
135
- "nested-provider": { models: ["nested-a", "nested-b"] },
136
- },
137
- }),
138
- }),
139
- );
140
-
141
- await addLocalProvider(manager, {
142
- providerId: "nested-provider",
143
- name: "Nested Provider",
144
- baseUrl: "https://example.invalid/v1",
145
- models: [],
146
- modelsSourceUrl: "https://example.invalid/models",
147
- });
148
-
149
- const { models } = await getLocalProviderModels("nested-provider");
150
- expect(models.map((m) => m.id).sort()).toEqual(["nested-a", "nested-b"]);
151
- });
152
-
153
- it("merges manually specified models with fetched models and deduplicates", async () => {
154
- vi.stubGlobal(
155
- "fetch",
156
- vi.fn().mockResolvedValue({
157
- ok: true,
158
- json: async () => ["fetched-1", "fetched-2", "manual-1"],
159
- }),
160
- );
161
-
162
- const result = await addLocalProvider(manager, {
163
- providerId: "merged-provider",
164
- name: "Merged",
165
- baseUrl: "https://example.invalid/v1",
166
- models: ["manual-1", "manual-2"],
167
- modelsSourceUrl: "https://example.invalid/models",
168
- });
169
-
170
- // manual-1, manual-2, fetched-1, fetched-2, manual-1 → Set → 4
171
- expect(result.modelsCount).toBe(4);
172
- const { models } = await getLocalProviderModels("merged-provider");
173
- const ids = models.map((m) => m.id).sort();
174
- expect(ids).toEqual(["fetched-1", "fetched-2", "manual-1", "manual-2"]);
175
- });
176
-
177
- it("throws when fetch returns non-OK status", async () => {
178
- vi.stubGlobal(
179
- "fetch",
180
- vi.fn().mockResolvedValue({
181
- ok: false,
182
- status: 404,
183
- }),
184
- );
185
-
186
- await expect(
187
- addLocalProvider(manager, {
188
- providerId: "fail-fetch-provider",
189
- name: "Fail",
190
- baseUrl: "https://example.invalid/v1",
191
- models: [],
192
- modelsSourceUrl: "https://example.invalid/models",
193
- }),
194
- ).rejects.toThrow("HTTP 404");
195
- });
196
-
197
- it("ignores empty string entries in array payloads", async () => {
198
- vi.stubGlobal(
199
- "fetch",
200
- vi.fn().mockResolvedValue({
201
- ok: true,
202
- json: async () => ["good-model", "", " "],
203
- }),
204
- );
205
-
206
- await addLocalProvider(manager, {
207
- providerId: "empty-strings-provider",
208
- name: "Empty Strings",
209
- baseUrl: "https://example.invalid/v1",
210
- models: [],
211
- modelsSourceUrl: "https://example.invalid/models",
212
- });
213
-
214
- const { models } = await getLocalProviderModels("empty-strings-provider");
215
- expect(models.map((m) => m.id)).toEqual(["good-model"]);
216
- });
217
-
218
- it("ignores non-array, non-object payload shapes and falls back to manual models", async () => {
219
- vi.stubGlobal(
220
- "fetch",
221
- vi.fn().mockResolvedValue({
222
- ok: true,
223
- json: async () => "just a string",
224
- }),
225
- );
226
-
227
- await addLocalProvider(manager, {
228
- providerId: "fallback-provider",
229
- name: "Fallback",
230
- baseUrl: "https://example.invalid/v1",
231
- models: ["fallback-model"],
232
- modelsSourceUrl: "https://example.invalid/models",
233
- });
234
-
235
- const { models } = await getLocalProviderModels("fallback-provider");
236
- expect(models.map((m) => m.id)).toEqual(["fallback-model"]);
237
- });
238
- });
239
-
240
- // ===========================================================================
241
- // addLocalProvider – validation guards
242
- // ===========================================================================
243
-
244
- describe("addLocalProvider – validation", () => {
245
- let manager: ProviderSettingsManager;
246
- let cleanup: () => void;
247
-
248
- beforeEach(() => {
249
- ({ manager, cleanup } = makeTempManager());
250
- });
251
-
252
- afterEach(() => cleanup());
253
-
254
- it("throws when providerId is empty", async () => {
255
- await expect(
256
- addLocalProvider(manager, {
257
- providerId: " ",
258
- name: "X",
259
- baseUrl: "https://example.invalid",
260
- models: ["m"],
261
- }),
262
- ).rejects.toThrow("providerId is required");
263
- });
264
-
265
- it("throws when name is empty", async () => {
266
- await expect(
267
- addLocalProvider(manager, {
268
- providerId: "my-provider",
269
- name: " ",
270
- baseUrl: "https://example.invalid",
271
- models: ["m"],
272
- }),
273
- ).rejects.toThrow("name is required");
274
- });
275
-
276
- it("throws when baseUrl is empty and apiKey is provided", async () => {
277
- await expect(
278
- addLocalProvider(manager, {
279
- providerId: "my-provider2",
280
- name: "My Provider",
281
- baseUrl: " ",
282
- apiKey: "present-key",
283
- models: ["m"],
284
- }),
285
- ).rejects.toThrow("baseUrl is required");
286
- });
287
-
288
- it("throws when no models are provided and no modelsSourceUrl", async () => {
289
- await expect(
290
- addLocalProvider(manager, {
291
- providerId: "no-models-provider",
292
- name: "No Models",
293
- baseUrl: "https://example.invalid",
294
- models: [],
295
- }),
296
- ).rejects.toThrow("at least one model is required");
297
- });
298
-
299
- it("throws when provider already exists", async () => {
300
- // Register a provider first
301
- await addLocalProvider(manager, {
302
- providerId: "duplicate-provider",
303
- name: "First",
304
- baseUrl: "https://example.invalid/v1",
305
- models: ["m1"],
306
- });
307
-
308
- await expect(
309
- addLocalProvider(manager, {
310
- providerId: "duplicate-provider",
311
- name: "Second",
312
- baseUrl: "https://example.invalid/v1",
313
- models: ["m2"],
314
- }),
315
- ).rejects.toThrow('"duplicate-provider" already exists');
316
- });
317
- });
318
-
319
- // ===========================================================================
320
- // addLocalProvider – delete compatibility path
321
- // ===========================================================================
322
-
323
- describe("addLocalProvider – delete compatibility", () => {
324
- let manager: ProviderSettingsManager;
325
- let cleanup: () => void;
326
-
327
- beforeEach(async () => {
328
- ({ manager, cleanup } = makeTempManager());
329
- await addLocalProvider(manager, {
330
- providerId: "legacy-delete-provider",
331
- name: "Legacy Delete Provider",
332
- baseUrl: "https://example.invalid/v1",
333
- models: ["legacy-model"],
334
- });
335
- manager.saveProviderSettings(
336
- {
337
- provider: "legacy-delete-provider",
338
- baseUrl: "https://example.invalid/v1",
339
- model: "legacy-model",
340
- },
341
- { setLastUsed: true },
342
- );
343
- });
344
-
345
- afterEach(() => cleanup());
346
-
347
- it("treats empty baseUrl and apiKey as a delete request for existing provider", async () => {
348
- const result = await addLocalProvider(manager, {
349
- providerId: "legacy-delete-provider",
350
- name: "Ignored",
351
- baseUrl: " ",
352
- apiKey: " ",
353
- models: [],
354
- });
355
-
356
- expect(result.providerId).toBe("legacy-delete-provider");
357
- expect(result.modelsCount).toBe(0);
358
- expect(LlmsModels.hasProvider("legacy-delete-provider")).toBe(false);
359
- expect(
360
- manager.getProviderSettings("legacy-delete-provider"),
361
- ).toBeUndefined();
362
- expect(manager.getLastUsedProviderSettings()).toBeUndefined();
363
- });
364
-
365
- it("is a no-op delete when provider is already missing", async () => {
366
- await deleteLocalProvider(manager, {
367
- providerId: "legacy-delete-provider",
368
- });
369
-
370
- await expect(
371
- addLocalProvider(manager, {
372
- providerId: "legacy-delete-provider",
373
- name: "Ignored",
374
- baseUrl: " ",
375
- models: [],
376
- }),
377
- ).resolves.toMatchObject({
378
- providerId: "legacy-delete-provider",
379
- modelsCount: 0,
380
- });
381
- });
382
- });
383
-
384
- // ===========================================================================
385
- // addLocalProvider – defaultModelId selection
386
- // ===========================================================================
387
-
388
- describe("addLocalProvider – defaultModelId selection", () => {
389
- let manager: ProviderSettingsManager;
390
- let cleanup: () => void;
391
-
392
- beforeEach(() => {
393
- ({ manager, cleanup } = makeTempManager());
394
- });
395
-
396
- afterEach(() => cleanup());
397
-
398
- it("uses explicit defaultModelId when it is in the model list", async () => {
399
- await addLocalProvider(manager, {
400
- providerId: "default-model-provider",
401
- name: "Test",
402
- baseUrl: "https://example.invalid/v1",
403
- models: ["model-a", "model-b", "model-c"],
404
- defaultModelId: "model-b",
405
- });
406
-
407
- const settings = manager.getProviderSettings("default-model-provider");
408
- expect(settings?.model).toBe("model-b");
409
- });
410
-
411
- it("falls back to the first model when defaultModelId is not in the list", async () => {
412
- await addLocalProvider(manager, {
413
- providerId: "fallback-default-provider",
414
- name: "Test",
415
- baseUrl: "https://example.invalid/v1",
416
- models: ["model-a", "model-b"],
417
- defaultModelId: "not-in-list",
418
- });
419
-
420
- const settings = manager.getProviderSettings("fallback-default-provider");
421
- expect(settings?.model).toBe("model-a");
422
- });
423
- });
424
-
425
- // ===========================================================================
426
- // addLocalProvider – capabilities → vision / reasoning flags
427
- // ===========================================================================
428
-
429
- describe("addLocalProvider – capabilities", () => {
430
- let manager: ProviderSettingsManager;
431
- let cleanup: () => void;
432
-
433
- beforeEach(() => {
434
- ({ manager, cleanup } = makeTempManager());
435
- });
436
-
437
- afterEach(() => cleanup());
438
-
439
- it("sets supportsVision and supportsAttachments when capability is 'vision'", async () => {
440
- await addLocalProvider(manager, {
441
- providerId: "vision-provider",
442
- name: "Vision",
443
- baseUrl: "https://example.invalid/v1",
444
- models: ["vis-model"],
445
- capabilities: ["vision"],
446
- });
447
-
448
- const { models } = await getLocalProviderModels("vision-provider");
449
- expect(models).toHaveLength(1);
450
- expect(models[0].supportsVision).toBe(true);
451
- expect(models[0].supportsAttachments).toBe(true);
452
- });
453
-
454
- it("sets supportsReasoning when capability is 'reasoning'", async () => {
455
- await addLocalProvider(manager, {
456
- providerId: "reasoning-provider",
457
- name: "Reasoning",
458
- baseUrl: "https://example.invalid/v1",
459
- models: ["r-model"],
460
- capabilities: ["reasoning"],
461
- });
462
-
463
- const { models } = await getLocalProviderModels("reasoning-provider");
464
- expect(models[0].supportsReasoning).toBe(true);
465
- expect(models[0].supportsVision).toBeFalsy();
466
- });
467
-
468
- it("does not set vision/reasoning flags when capabilities are absent", async () => {
469
- await addLocalProvider(manager, {
470
- providerId: "plain-provider",
471
- name: "Plain",
472
- baseUrl: "https://example.invalid/v1",
473
- models: ["plain-model"],
474
- });
475
-
476
- const { models } = await getLocalProviderModels("plain-provider");
477
- expect(models[0].supportsVision).toBeFalsy();
478
- expect(models[0].supportsReasoning).toBeFalsy();
479
- });
480
-
481
- it("merges LiteLLM private models into the provider model listing when auth is configured", async () => {
482
- manager.saveProviderSettings(
483
- {
484
- provider: "litellm",
485
- apiKey: "test-key-catalog",
486
- baseUrl: "http://localhost:4010",
487
- model: "gpt-4o",
488
- },
489
- { setLastUsed: false },
490
- );
491
- vi.stubGlobal(
492
- "fetch",
493
- vi.fn().mockResolvedValue({
494
- ok: true,
495
- json: async () => ({
496
- data: [
497
- {
498
- model_name: "private-proxy-model",
499
- litellm_params: { model: "openai/gpt-4o-mini" },
500
- model_info: {
501
- supports_vision: true,
502
- supports_reasoning: true,
503
- },
504
- },
505
- ],
506
- }),
507
- }),
508
- );
509
-
510
- const { models } = await getLocalProviderModels(
511
- "litellm",
512
- manager.getProviderConfig("litellm"),
513
- );
514
-
515
- expect(models.map((model) => model.id)).toContain("private-proxy-model");
516
- expect(models.map((model) => model.id)).toContain("openai/gpt-4o-mini");
517
- expect(
518
- models.find((model) => model.id === "private-proxy-model"),
519
- ).toMatchObject({
520
- supportsVision: true,
521
- supportsReasoning: true,
522
- });
523
- });
524
- });
525
-
526
- // ===========================================================================
527
- // saveLocalProviderSettings
528
- // ===========================================================================
529
-
530
- describe("saveLocalProviderSettings", () => {
531
- let manager: ProviderSettingsManager;
532
- let cleanup: () => void;
533
-
534
- beforeEach(async () => {
535
- ({ manager, cleanup } = makeTempManager());
536
- // Seed a provider so there is something to operate on
537
- await addLocalProvider(manager, {
538
- providerId: "test-provider",
539
- name: "Test",
540
- baseUrl: "https://example.invalid/v1",
541
- models: ["m1"],
542
- });
543
- });
544
-
545
- afterEach(() => cleanup());
546
-
547
- it("disabling a provider removes it from settings", () => {
548
- const result = saveLocalProviderSettings(manager, {
549
- providerId: "test-provider",
550
- enabled: false,
551
- });
552
-
553
- expect(result.enabled).toBe(false);
554
- expect(manager.getProviderSettings("test-provider")).toBeUndefined();
555
- });
556
-
557
- it("updates apiKey", () => {
558
- saveLocalProviderSettings(manager, {
559
- providerId: "test-provider",
560
- enabled: true,
561
- apiKey: "new-key",
562
- });
563
-
564
- expect(manager.getProviderSettings("test-provider")?.apiKey).toBe(
565
- "new-key",
566
- );
567
- });
568
-
569
- it("clears apiKey when empty string is provided", () => {
570
- // First set a key
571
- saveLocalProviderSettings(manager, {
572
- providerId: "test-provider",
573
- enabled: true,
574
- apiKey: "some-key",
575
- });
576
- // Then clear it
577
- saveLocalProviderSettings(manager, {
578
- providerId: "test-provider",
579
- enabled: true,
580
- apiKey: "",
581
- });
582
-
583
- const settings = manager.getProviderSettings("test-provider");
584
- expect(settings).not.toHaveProperty("apiKey");
585
- });
586
-
587
- it("merges auth object rather than replacing it", () => {
588
- saveLocalProviderSettings(manager, {
589
- providerId: "test-provider",
590
- enabled: true,
591
- auth: { accessToken: "tok1" },
592
- });
593
- saveLocalProviderSettings(manager, {
594
- providerId: "test-provider",
595
- enabled: true,
596
- auth: { refreshToken: "ref1" },
597
- });
598
-
599
- const settings = manager.getProviderSettings("test-provider") as Record<
600
- string,
601
- unknown
602
- >;
603
- const auth = settings?.auth as Record<string, unknown>;
604
- expect(auth?.accessToken).toBe("tok1");
605
- expect(auth?.refreshToken).toBe("ref1");
606
- });
607
-
608
- it("passes through scalar fields like maxTokens and timeout", () => {
609
- saveLocalProviderSettings(manager, {
610
- providerId: "test-provider",
611
- enabled: true,
612
- maxTokens: 4096,
613
- timeout: 30_000,
614
- });
615
-
616
- const settings = manager.getProviderSettings("test-provider") as Record<
617
- string,
618
- unknown
619
- >;
620
- expect(settings?.maxTokens).toBe(4096);
621
- expect(settings?.timeout).toBe(30_000);
622
- });
623
-
624
- it("disabling a last-used provider also clears lastUsedProvider", async () => {
625
- // Set test-provider as last used
626
- manager.saveProviderSettings(
627
- { provider: "test-provider", model: "m1" },
628
- { setLastUsed: true },
629
- );
630
- expect(manager.getLastUsedProviderSettings()?.provider).toBe(
631
- "test-provider",
632
- );
633
-
634
- saveLocalProviderSettings(manager, {
635
- providerId: "test-provider",
636
- enabled: false,
637
- });
638
-
639
- expect(manager.getLastUsedProviderSettings()).toBeUndefined();
640
- });
641
- });
642
-
643
- // ===========================================================================
644
- // updateLocalProvider
645
- // ===========================================================================
646
-
647
- describe("updateLocalProvider", () => {
648
- let manager: ProviderSettingsManager;
649
- let cleanup: () => void;
650
-
651
- beforeEach(async () => {
652
- ({ manager, cleanup } = makeTempManager());
653
- await addLocalProvider(manager, {
654
- providerId: "editable-provider",
655
- name: "Editable Provider",
656
- baseUrl: "https://example.invalid/v1",
657
- apiKey: "seed-key",
658
- models: ["model-a", "model-b"],
659
- defaultModelId: "model-a",
660
- });
661
- });
662
-
663
- afterEach(() => cleanup());
664
-
665
- it("updates provider metadata and model registry", async () => {
666
- await updateLocalProvider(manager, {
667
- providerId: "editable-provider",
668
- name: "Renamed Provider",
669
- baseUrl: "https://api.example.invalid/v2",
670
- models: ["model-c", "model-d"],
671
- defaultModelId: "model-d",
672
- capabilities: ["vision", "reasoning"],
673
- });
674
-
675
- const provider = await LlmsModels.getProvider("editable-provider");
676
- expect(provider?.name).toBe("Renamed Provider");
677
- expect(provider?.baseUrl).toBe("https://api.example.invalid/v2");
678
- expect(provider?.defaultModelId).toBe("model-d");
679
-
680
- const { models } = await getLocalProviderModels("editable-provider");
681
- expect(models.map((model) => model.id).sort()).toEqual([
682
- "model-c",
683
- "model-d",
684
- ]);
685
- expect(models.find((model) => model.id === "model-c")?.supportsVision).toBe(
686
- true,
687
- );
688
- expect(
689
- models.find((model) => model.id === "model-c")?.supportsReasoning,
690
- ).toBe(true);
691
- });
692
-
693
- it("updates provider settings and can clear optional fields", async () => {
694
- await updateLocalProvider(manager, {
695
- providerId: "editable-provider",
696
- baseUrl: "https://api.example.invalid/v3",
697
- apiKey: "",
698
- headers: null,
699
- timeoutMs: null,
700
- });
701
-
702
- const settings = manager.getProviderSettings("editable-provider");
703
- expect(settings?.baseUrl).toBe("https://api.example.invalid/v3");
704
- expect(settings).not.toHaveProperty("apiKey");
705
- expect(settings).not.toHaveProperty("headers");
706
- expect(settings).not.toHaveProperty("timeout");
707
- });
708
-
709
- it("clears capabilities with null and does not treat [] as a clear sentinel", async () => {
710
- await updateLocalProvider(manager, {
711
- providerId: "editable-provider",
712
- capabilities: ["vision"],
713
- });
714
- const modelsPath = resolveModelsRegistryPath(manager);
715
- let modelsState = await readModelsFile(modelsPath);
716
- expect(
717
- modelsState.providers["editable-provider"]?.provider.capabilities,
718
- ).toEqual(["vision"]);
719
-
720
- await updateLocalProvider(manager, {
721
- providerId: "editable-provider",
722
- capabilities: [],
723
- });
724
- modelsState = await readModelsFile(modelsPath);
725
- expect(
726
- modelsState.providers["editable-provider"]?.provider.capabilities,
727
- ).toEqual([]);
728
-
729
- await updateLocalProvider(manager, {
730
- providerId: "editable-provider",
731
- capabilities: null,
732
- });
733
- modelsState = await readModelsFile(modelsPath);
734
- expect(
735
- modelsState.providers["editable-provider"]?.provider.capabilities,
736
- ).toBeUndefined();
737
- });
738
-
739
- it("allows modelsSourceUrl: null to clear URL while preserving existing models", async () => {
740
- const fetchMock = vi.fn().mockResolvedValue({
741
- ok: true,
742
- json: async () => ["remote-a", "remote-b"],
743
- });
744
- vi.stubGlobal("fetch", fetchMock);
745
-
746
- await updateLocalProvider(manager, {
747
- providerId: "editable-provider",
748
- models: ["model-a", "model-b"],
749
- modelsSourceUrl: "https://example.invalid/models",
750
- });
751
-
752
- await updateLocalProvider(manager, {
753
- providerId: "editable-provider",
754
- modelsSourceUrl: null,
755
- });
756
-
757
- const modelsState = await readModelsFile(
758
- resolveModelsRegistryPath(manager),
759
- );
760
- expect(
761
- modelsState.providers["editable-provider"]?.provider.modelsSourceUrl,
762
- ).toBeUndefined();
763
-
764
- const { models } = await getLocalProviderModels("editable-provider");
765
- expect(models.map((model) => model.id).sort()).toEqual([
766
- "model-a",
767
- "model-b",
768
- "remote-a",
769
- "remote-b",
770
- ]);
771
- expect(fetchMock).toHaveBeenCalledTimes(1);
772
- });
773
-
774
- it("throws when updating a provider that does not exist in custom registry", async () => {
775
- await expect(
776
- updateLocalProvider(manager, {
777
- providerId: "missing-provider",
778
- name: "Nope",
779
- }),
780
- ).rejects.toThrow('"missing-provider" does not exist');
781
- });
782
- });
783
-
784
- // ===========================================================================
785
- // deleteLocalProvider
786
- // ===========================================================================
787
-
788
- describe("deleteLocalProvider", () => {
789
- let manager: ProviderSettingsManager;
790
- let cleanup: () => void;
791
-
792
- beforeEach(async () => {
793
- ({ manager, cleanup } = makeTempManager());
794
- await addLocalProvider(manager, {
795
- providerId: "delete-me-provider",
796
- name: "Delete Me",
797
- baseUrl: "https://example.invalid/v1",
798
- models: ["delete-model"],
799
- });
800
- manager.saveProviderSettings(
801
- {
802
- provider: "delete-me-provider",
803
- baseUrl: "https://example.invalid/v1",
804
- model: "delete-model",
805
- },
806
- { setLastUsed: true },
807
- );
808
- });
809
-
810
- afterEach(() => cleanup());
811
-
812
- it("removes provider from registry and local settings", async () => {
813
- await deleteLocalProvider(manager, {
814
- providerId: "delete-me-provider",
815
- });
816
-
817
- expect(LlmsModels.hasProvider("delete-me-provider")).toBe(false);
818
- expect(manager.getProviderSettings("delete-me-provider")).toBeUndefined();
819
- expect(manager.getLastUsedProviderSettings()).toBeUndefined();
820
- });
821
-
822
- it("throws when deleting an unknown provider", async () => {
823
- await expect(
824
- deleteLocalProvider(manager, { providerId: "missing-provider" }),
825
- ).rejects.toThrow('"missing-provider" does not exist');
826
- });
827
- });
828
-
829
- // ===========================================================================
830
- // listLocalProviders
831
- // ===========================================================================
832
-
833
- describe("listLocalProviders", () => {
834
- let manager: ProviderSettingsManager;
835
- let cleanup: () => void;
836
-
837
- beforeEach(() => {
838
- ({ manager, cleanup } = makeTempManager());
839
- });
840
-
841
- afterEach(() => cleanup());
842
-
843
- it("includes all registered providers", async () => {
844
- await addLocalProvider(manager, {
845
- providerId: "list-provider-a",
846
- name: "Provider A",
847
- baseUrl: "https://example.invalid/a",
848
- models: ["ma1"],
849
- });
850
- await addLocalProvider(manager, {
851
- providerId: "list-provider-b",
852
- name: "Provider B",
853
- baseUrl: "https://example.invalid/b",
854
- models: ["mb1"],
855
- });
856
-
857
- const { providers } = await listLocalProviders(manager);
858
- const ids = providers.map((p) => p.id);
859
- expect(ids).toContain("list-provider-a");
860
- expect(ids).toContain("list-provider-b");
861
- });
862
-
863
- it("marks enabled providers correctly", async () => {
864
- await addLocalProvider(manager, {
865
- providerId: "enabled-check-provider",
866
- name: "Enabled Check",
867
- baseUrl: "https://example.invalid/v1",
868
- models: ["m1"],
869
- });
870
-
871
- const { providers } = await listLocalProviders(manager);
872
- const p = providers.find((x) => x.id === "enabled-check-provider");
873
- expect(p?.enabled).toBe(true);
874
- });
875
-
876
- it("exposes model count", async () => {
877
- await addLocalProvider(manager, {
878
- providerId: "count-provider",
879
- name: "Count",
880
- baseUrl: "https://example.invalid/v1",
881
- models: ["x", "y", "z"],
882
- });
883
-
884
- const { providers } = await listLocalProviders(manager);
885
- const p = providers.find((x) => x.id === "count-provider");
886
- expect(p?.models).toBe(3);
887
- });
888
-
889
- it("generates a stable color and letter for each provider", async () => {
890
- await addLocalProvider(manager, {
891
- providerId: "color-letter-provider",
892
- name: "Color Letter",
893
- baseUrl: "https://example.invalid/v1",
894
- models: ["m1"],
895
- });
896
-
897
- const { providers } = await listLocalProviders(manager);
898
- const p = providers.find((x) => x.id === "color-letter-provider");
899
- expect(p?.color).toMatch(/^#[0-9a-f]{6}$/i);
900
- expect(p?.letter).toBeTruthy();
901
- });
902
-
903
- it("includes built-in model lists in the provider catalog path", async () => {
904
- manager.saveProviderSettings(
905
- {
906
- provider: "openai-native",
907
- apiKey: "test-key",
908
- baseUrl: "https://api.openai.com/v1",
909
- model: "gpt-5.3-codex",
910
- },
911
- { setLastUsed: false },
912
- );
913
-
914
- const { providers } = await listLocalProviders(manager);
915
- const openai = providers.find(
916
- (provider) => provider.id === "openai-native",
917
- );
918
-
919
- expect(openai?.modelList?.length).toBeGreaterThan(0);
920
- expect(
921
- openai?.modelList?.some((model) => model.id === "gpt-5.3-codex"),
922
- ).toBe(true);
923
- });
924
-
925
- it("uses the same built-in model list for cline as openrouter", async () => {
926
- manager.saveProviderSettings(
927
- {
928
- provider: "cline",
929
- apiKey: "test-key",
930
- baseUrl: "https://api.cline.bot/api/v1",
931
- model: "anthropic/claude-sonnet-4.6",
932
- },
933
- { setLastUsed: false },
934
- );
935
-
936
- const { providers } = await listLocalProviders(manager);
937
- const cline = providers.find((provider) => provider.id === "cline");
938
- const openrouter = providers.find(
939
- (provider) => provider.id === "openrouter",
940
- );
941
-
942
- expect(cline?.modelList?.length).toBeGreaterThan(0);
943
- expect(cline?.modelList).toEqual(openrouter?.modelList);
944
- });
945
-
946
- it("does not eagerly fetch LiteLLM private models while listing providers", async () => {
947
- manager.saveProviderSettings(
948
- {
949
- provider: "litellm",
950
- apiKey: "test-key",
951
- baseUrl: "http://localhost:4000",
952
- model: "gpt-4o",
953
- },
954
- { setLastUsed: false },
955
- );
956
- const fetchMock = vi.fn().mockResolvedValue({
957
- ok: true,
958
- json: async () => ({
959
- data: [
960
- {
961
- model_name: "team-private-model",
962
- litellm_params: { model: "team/private-model" },
963
- model_info: {},
964
- },
965
- ],
966
- }),
967
- });
968
- vi.stubGlobal("fetch", fetchMock);
969
-
970
- const { providers } = await listLocalProviders(manager);
971
- const litellm = providers.find((provider) => provider.id === "litellm");
972
-
973
- expect(fetchMock).not.toHaveBeenCalled();
974
- expect(litellm?.modelList?.length).toBeGreaterThan(0);
975
- expect(
976
- litellm?.modelList?.some((model) => model.id === "team/private-model"),
977
- ).toBe(false);
978
- });
979
- });
980
-
981
- // ===========================================================================
982
- // normalizeOAuthProvider
983
- // ===========================================================================
984
-
985
- describe("normalizeOAuthProvider", () => {
986
- it("normalizes 'cline' to 'cline'", () => {
987
- expect(normalizeOAuthProvider("cline")).toBe("cline");
988
- expect(normalizeOAuthProvider(" CLINE ")).toBe("cline");
989
- });
990
-
991
- it("normalizes 'oca' to 'oca'", () => {
992
- expect(normalizeOAuthProvider("oca")).toBe("oca");
993
- expect(normalizeOAuthProvider("OCA")).toBe("oca");
994
- });
995
-
996
- it("normalizes 'codex' and 'openai-codex' to 'openai-codex'", () => {
997
- expect(normalizeOAuthProvider("codex")).toBe("openai-codex");
998
- expect(normalizeOAuthProvider("openai-codex")).toBe("openai-codex");
999
- expect(normalizeOAuthProvider("OPENAI-CODEX")).toBe("openai-codex");
1000
- });
1001
-
1002
- it("throws for unsupported providers", () => {
1003
- expect(() => normalizeOAuthProvider("anthropic")).toThrow(
1004
- "does not support OAuth login",
1005
- );
1006
- expect(() => normalizeOAuthProvider("")).toThrow();
1007
- });
1008
- });
1009
-
1010
- // ===========================================================================
1011
- // resolveLocalClineAuthToken
1012
- // ===========================================================================
1013
-
1014
- describe("resolveLocalClineAuthToken", () => {
1015
- it("returns undefined when settings is undefined", () => {
1016
- expect(resolveLocalClineAuthToken(undefined)).toBeUndefined();
1017
- });
1018
-
1019
- it("returns accessToken when present", () => {
1020
- expect(
1021
- resolveLocalClineAuthToken({
1022
- provider: "cline" as never,
1023
- auth: { accessToken: "tok123" },
1024
- }),
1025
- ).toBe("tok123");
1026
- });
1027
-
1028
- it("falls back to apiKey when accessToken is absent", () => {
1029
- expect(
1030
- resolveLocalClineAuthToken({
1031
- provider: "cline" as never,
1032
- apiKey: "api-key-456",
1033
- }),
1034
- ).toBe("api-key-456");
1035
- });
1036
-
1037
- it("prefers accessToken over apiKey", () => {
1038
- expect(
1039
- resolveLocalClineAuthToken({
1040
- provider: "cline" as never,
1041
- apiKey: "api-key",
1042
- auth: { accessToken: "access-token" },
1043
- }),
1044
- ).toBe("access-token");
1045
- });
1046
-
1047
- it("returns undefined when both accessToken and apiKey are empty strings", () => {
1048
- expect(
1049
- resolveLocalClineAuthToken({
1050
- provider: "cline" as never,
1051
- apiKey: " ",
1052
- auth: { accessToken: " " },
1053
- }),
1054
- ).toBeUndefined();
1055
- });
1056
-
1057
- it("returns undefined when both fields are absent", () => {
1058
- expect(
1059
- resolveLocalClineAuthToken({ provider: "cline" as never }),
1060
- ).toBeUndefined();
1061
- });
1062
- });