@clinebot/core 0.0.35 → 0.0.36

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 (335) hide show
  1. package/README.md +1 -2
  2. package/dist/ClineCore.d.ts +53 -39
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/index.d.ts +1 -1
  5. package/dist/account/index.d.ts.map +1 -1
  6. package/dist/account/rpc.d.ts +6 -6
  7. package/dist/account/rpc.d.ts.map +1 -1
  8. package/dist/cron/index.d.ts +6 -0
  9. package/dist/cron/index.d.ts.map +1 -0
  10. package/dist/cron/resource-limiter.d.ts +9 -0
  11. package/dist/cron/resource-limiter.d.ts.map +1 -0
  12. package/dist/cron/schedule-command-service.d.ts +10 -0
  13. package/dist/cron/schedule-command-service.d.ts.map +1 -0
  14. package/dist/cron/schedule-service.d.ts +100 -0
  15. package/dist/cron/schedule-service.d.ts.map +1 -0
  16. package/dist/cron/scheduler.d.ts +66 -0
  17. package/dist/cron/scheduler.d.ts.map +1 -0
  18. package/dist/cron/sqlite-schedule-store.d.ts +52 -0
  19. package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
  20. package/dist/extensions/config/agent-config-loader.d.ts +4 -3
  21. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  22. package/dist/extensions/config/runtime-commands.d.ts +1 -0
  23. package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
  24. package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
  25. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  26. package/dist/extensions/context/agentic-compaction.d.ts +2 -2
  27. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
  28. package/dist/extensions/context/compaction-shared.d.ts +5 -4
  29. package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
  30. package/dist/extensions/context/compaction.d.ts.map +1 -1
  31. package/dist/extensions/plugin/plugin-config-loader.d.ts +9 -2
  32. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  33. package/dist/extensions/plugin/plugin-loader.d.ts +5 -3
  34. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  35. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
  36. package/dist/extensions/plugin/plugin-sandbox.d.ts +15 -2
  37. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  38. package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
  39. package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
  40. package/dist/extensions/plugin-sandbox-bootstrap.js +211 -211
  41. package/dist/extensions/tools/definitions.d.ts +1 -1
  42. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  43. package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
  44. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
  45. package/dist/extensions/tools/executors/search.d.ts +1 -1
  46. package/dist/extensions/tools/executors/search.d.ts.map +1 -1
  47. package/dist/extensions/tools/index.d.ts +2 -0
  48. package/dist/extensions/tools/index.d.ts.map +1 -1
  49. package/dist/extensions/tools/presets.d.ts +26 -43
  50. package/dist/extensions/tools/presets.d.ts.map +1 -1
  51. package/dist/extensions/tools/runtime.d.ts +25 -0
  52. package/dist/extensions/tools/runtime.d.ts.map +1 -0
  53. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  54. package/dist/extensions/tools/team/team-tools.d.ts +1 -0
  55. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  56. package/dist/hooks/hook-file-hooks.d.ts +4 -1
  57. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  58. package/dist/hooks/index.d.ts +0 -1
  59. package/dist/hooks/index.d.ts.map +1 -1
  60. package/dist/hooks/subprocess.d.ts +8 -1
  61. package/dist/hooks/subprocess.d.ts.map +1 -1
  62. package/dist/hub/browser-websocket.d.ts +18 -0
  63. package/dist/hub/browser-websocket.d.ts.map +1 -0
  64. package/dist/hub/client.d.ts +45 -0
  65. package/dist/hub/client.d.ts.map +1 -0
  66. package/dist/hub/connect.d.ts +15 -0
  67. package/dist/hub/connect.d.ts.map +1 -0
  68. package/dist/hub/daemon-entry.d.ts +2 -0
  69. package/dist/hub/daemon-entry.d.ts.map +1 -0
  70. package/dist/hub/daemon-entry.js +1045 -0
  71. package/dist/hub/daemon.d.ts +5 -0
  72. package/dist/hub/daemon.d.ts.map +1 -0
  73. package/dist/hub/defaults.d.ts +13 -0
  74. package/dist/hub/defaults.d.ts.map +1 -0
  75. package/dist/hub/discovery.d.ts +29 -0
  76. package/dist/hub/discovery.d.ts.map +1 -0
  77. package/dist/hub/index.d.ts +15 -0
  78. package/dist/hub/index.d.ts.map +1 -0
  79. package/dist/hub/index.js +1044 -0
  80. package/dist/hub/native-transport.d.ts +17 -0
  81. package/dist/hub/native-transport.d.ts.map +1 -0
  82. package/dist/hub/runtime-handlers.d.ts +11 -0
  83. package/dist/hub/runtime-handlers.d.ts.map +1 -0
  84. package/dist/hub/server.d.ts +86 -0
  85. package/dist/hub/server.d.ts.map +1 -0
  86. package/dist/hub/session-client.d.ts +87 -0
  87. package/dist/hub/session-client.d.ts.map +1 -0
  88. package/dist/hub/start-shared-server.d.ts +19 -0
  89. package/dist/hub/start-shared-server.d.ts.map +1 -0
  90. package/dist/hub/transport.d.ts +8 -0
  91. package/dist/hub/transport.d.ts.map +1 -0
  92. package/dist/hub/ui-client.d.ts +44 -0
  93. package/dist/hub/ui-client.d.ts.map +1 -0
  94. package/dist/hub/workspace.d.ts +4 -0
  95. package/dist/hub/workspace.d.ts.map +1 -0
  96. package/dist/index.d.ts +26 -15
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +498 -476
  99. package/dist/llms/configured-provider-registry.d.ts +28 -0
  100. package/dist/llms/configured-provider-registry.d.ts.map +1 -0
  101. package/dist/llms/provider-defaults.d.ts +27 -0
  102. package/dist/llms/provider-defaults.d.ts.map +1 -0
  103. package/dist/llms/provider-settings.d.ts +202 -0
  104. package/dist/llms/provider-settings.d.ts.map +1 -0
  105. package/dist/llms/runtime-config.d.ts +4 -0
  106. package/dist/llms/runtime-config.d.ts.map +1 -0
  107. package/dist/llms/runtime-registry.d.ts +20 -0
  108. package/dist/llms/runtime-registry.d.ts.map +1 -0
  109. package/dist/llms/runtime-types.d.ts +85 -0
  110. package/dist/llms/runtime-types.d.ts.map +1 -0
  111. package/dist/runtime/host.d.ts +1 -2
  112. package/dist/runtime/host.d.ts.map +1 -1
  113. package/dist/runtime/rules.d.ts +1 -0
  114. package/dist/runtime/rules.d.ts.map +1 -1
  115. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  116. package/dist/runtime/runtime-host.d.ts +22 -24
  117. package/dist/runtime/runtime-host.d.ts.map +1 -1
  118. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
  119. package/dist/runtime/session-runtime.d.ts +1 -19
  120. package/dist/runtime/session-runtime.d.ts.map +1 -1
  121. package/dist/services/global-settings.d.ts +12 -0
  122. package/dist/services/global-settings.d.ts.map +1 -0
  123. package/dist/services/local-runtime-bootstrap.d.ts +9 -3
  124. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  125. package/dist/services/plugin-tools.d.ts +16 -0
  126. package/dist/services/plugin-tools.d.ts.map +1 -0
  127. package/dist/services/providers/local-provider-registry.d.ts +4 -4
  128. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  129. package/dist/services/providers/local-provider-service.d.ts +13 -13
  130. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  131. package/dist/services/session-data.d.ts +1 -1
  132. package/dist/services/session-data.d.ts.map +1 -1
  133. package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
  134. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  135. package/dist/services/telemetry/index.js +28 -15
  136. package/dist/services/workspace-manifest.d.ts +11 -0
  137. package/dist/services/workspace-manifest.d.ts.map +1 -1
  138. package/dist/session/persistence-service.d.ts +11 -23
  139. package/dist/session/persistence-service.d.ts.map +1 -1
  140. package/dist/session/session-manifest-store.d.ts +22 -0
  141. package/dist/session/session-manifest-store.d.ts.map +1 -0
  142. package/dist/session/session-row.d.ts +93 -0
  143. package/dist/session/session-row.d.ts.map +1 -0
  144. package/dist/session/session-service.d.ts +2 -102
  145. package/dist/session/session-service.d.ts.map +1 -1
  146. package/dist/session/subagent-session-manager.d.ts +36 -0
  147. package/dist/session/subagent-session-manager.d.ts.map +1 -0
  148. package/dist/session/team-persistence-store.d.ts +24 -0
  149. package/dist/session/team-persistence-store.d.ts.map +1 -0
  150. package/dist/transports/hub.d.ts +47 -0
  151. package/dist/transports/hub.d.ts.map +1 -0
  152. package/dist/transports/local.d.ts +10 -6
  153. package/dist/transports/local.d.ts.map +1 -1
  154. package/dist/transports/remote.d.ts +10 -0
  155. package/dist/transports/remote.d.ts.map +1 -0
  156. package/dist/transports/runtime-host-support.d.ts +3 -2
  157. package/dist/transports/runtime-host-support.d.ts.map +1 -1
  158. package/dist/types/chat-schema.d.ts +10 -12
  159. package/dist/types/chat-schema.d.ts.map +1 -1
  160. package/dist/types/config.d.ts +8 -7
  161. package/dist/types/config.d.ts.map +1 -1
  162. package/dist/types/provider-settings.d.ts +4 -5
  163. package/dist/types/provider-settings.d.ts.map +1 -1
  164. package/dist/types/session.d.ts +2 -1
  165. package/dist/types/session.d.ts.map +1 -1
  166. package/dist/types.d.ts +8 -1
  167. package/dist/types.d.ts.map +1 -1
  168. package/package.json +20 -6
  169. package/src/ClineCore.ts +68 -40
  170. package/src/account/index.ts +3 -3
  171. package/src/account/rpc.ts +12 -12
  172. package/src/cron/index.ts +5 -0
  173. package/src/cron/resource-limiter.ts +46 -0
  174. package/src/cron/schedule-command-service.ts +193 -0
  175. package/src/cron/schedule-service.ts +703 -0
  176. package/src/cron/scheduler.ts +637 -0
  177. package/src/cron/sqlite-schedule-store.ts +708 -0
  178. package/src/extensions/config/agent-config-loader.ts +17 -7
  179. package/src/extensions/config/runtime-commands.ts +6 -0
  180. package/src/extensions/config/user-instruction-config-loader.ts +1 -0
  181. package/src/extensions/context/agentic-compaction.ts +3 -3
  182. package/src/extensions/context/basic-compaction.ts +2 -2
  183. package/src/extensions/context/compaction-shared.ts +5 -4
  184. package/src/extensions/context/compaction.ts +3 -3
  185. package/src/extensions/plugin/plugin-config-loader.ts +17 -2
  186. package/src/extensions/plugin/plugin-loader.ts +48 -4
  187. package/src/extensions/plugin/plugin-module-import.ts +0 -2
  188. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +93 -39
  189. package/src/extensions/plugin/plugin-sandbox.ts +47 -27
  190. package/src/extensions/plugin/plugin-targeting.ts +32 -0
  191. package/src/extensions/tools/definitions.ts +30 -49
  192. package/src/extensions/tools/executors/apply-patch.ts +69 -80
  193. package/src/extensions/tools/executors/search.ts +195 -3
  194. package/src/extensions/tools/index.ts +10 -0
  195. package/src/extensions/tools/presets.ts +31 -46
  196. package/src/extensions/tools/runtime.ts +261 -0
  197. package/src/extensions/tools/schemas.ts +4 -2
  198. package/src/extensions/tools/team/team-tools.ts +21 -0
  199. package/src/hooks/hook-file-hooks.ts +8 -2
  200. package/src/hooks/index.ts +0 -7
  201. package/src/hooks/subprocess-runner.ts +1 -1
  202. package/src/hooks/subprocess.ts +9 -0
  203. package/src/hub/browser-websocket.ts +137 -0
  204. package/src/hub/client.ts +574 -0
  205. package/src/hub/connect.ts +156 -0
  206. package/src/hub/daemon-entry.ts +87 -0
  207. package/src/hub/daemon.ts +181 -0
  208. package/src/hub/defaults.ts +43 -0
  209. package/src/hub/discovery.ts +247 -0
  210. package/src/hub/index.ts +14 -0
  211. package/src/hub/native-transport.ts +31 -0
  212. package/src/hub/runtime-handlers.ts +140 -0
  213. package/src/hub/server.ts +1888 -0
  214. package/src/hub/session-client.ts +460 -0
  215. package/src/hub/start-shared-server.ts +58 -0
  216. package/src/hub/transport.ts +14 -0
  217. package/src/hub/ui-client.ts +122 -0
  218. package/src/hub/workspace.ts +19 -0
  219. package/src/index.ts +124 -68
  220. package/src/llms/configured-provider-registry.ts +193 -0
  221. package/src/llms/provider-defaults.ts +637 -0
  222. package/src/llms/provider-settings.ts +263 -0
  223. package/src/llms/runtime-config.ts +43 -0
  224. package/src/llms/runtime-registry.ts +171 -0
  225. package/src/llms/runtime-types.ts +121 -0
  226. package/src/runtime/host.ts +107 -269
  227. package/src/runtime/index.ts +1 -0
  228. package/src/runtime/rules.ts +12 -0
  229. package/src/runtime/runtime-builder.ts +24 -8
  230. package/src/runtime/runtime-host.ts +89 -61
  231. package/src/runtime/runtime-oauth-token-manager.ts +11 -15
  232. package/src/runtime/session-runtime.ts +0 -24
  233. package/src/services/global-settings.ts +122 -0
  234. package/src/services/local-runtime-bootstrap.ts +51 -13
  235. package/src/services/plugin-tools.ts +85 -0
  236. package/src/services/providers/local-provider-registry.ts +6 -6
  237. package/src/services/providers/local-provider-service.ts +42 -37
  238. package/src/services/session-data.ts +15 -9
  239. package/src/services/storage/provider-settings-legacy-migration.ts +6 -4
  240. package/src/services/storage/provider-settings-manager.ts +1 -1
  241. package/src/services/workspace-manifest.ts +18 -0
  242. package/src/session/file-session-service.ts +1 -1
  243. package/src/session/index.ts +6 -27
  244. package/src/session/persistence-service.ts +119 -504
  245. package/src/session/session-manifest-store.ts +158 -0
  246. package/src/session/session-row.ts +199 -0
  247. package/src/session/session-service.ts +17 -376
  248. package/src/session/session-team-coordination.ts +1 -1
  249. package/src/session/subagent-session-manager.ts +397 -0
  250. package/src/session/team-persistence-store.ts +176 -0
  251. package/src/transports/hub.ts +656 -0
  252. package/src/transports/local.ts +135 -40
  253. package/src/transports/remote.ts +26 -0
  254. package/src/transports/runtime-host-support.ts +63 -9
  255. package/src/types/chat-schema.ts +4 -5
  256. package/src/types/config.ts +8 -7
  257. package/src/types/provider-settings.ts +11 -7
  258. package/src/types/session.ts +2 -4
  259. package/src/types.ts +27 -1
  260. package/dist/hooks/persistent.d.ts +0 -64
  261. package/dist/hooks/persistent.d.ts.map +0 -1
  262. package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
  263. package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
  264. package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
  265. package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
  266. package/dist/session/rpc-session-service.d.ts +0 -16
  267. package/dist/session/rpc-session-service.d.ts.map +0 -1
  268. package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
  269. package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
  270. package/dist/transports/rpc.d.ts +0 -51
  271. package/dist/transports/rpc.d.ts.map +0 -1
  272. package/src/ClineCore.test.ts +0 -226
  273. package/src/account/cline-account-service.test.ts +0 -185
  274. package/src/account/featurebase-token.test.ts +0 -175
  275. package/src/account/rpc.test.ts +0 -63
  276. package/src/auth/bounded-ttl-cache.test.ts +0 -38
  277. package/src/auth/client.test.ts +0 -69
  278. package/src/auth/cline.test.ts +0 -267
  279. package/src/auth/codex.test.ts +0 -170
  280. package/src/auth/oca.test.ts +0 -340
  281. package/src/auth/server.test.ts +0 -287
  282. package/src/auth/utils.test.ts +0 -128
  283. package/src/extensions/config/agent-config-loader.test.ts +0 -236
  284. package/src/extensions/config/hooks-config-loader.test.ts +0 -20
  285. package/src/extensions/config/runtime-commands.test.ts +0 -115
  286. package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
  287. package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
  288. package/src/extensions/context/compaction.test.ts +0 -483
  289. package/src/extensions/mcp/config-loader.test.ts +0 -238
  290. package/src/extensions/mcp/manager.test.ts +0 -105
  291. package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
  292. package/src/extensions/plugin/plugin-loader.test.ts +0 -292
  293. package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
  294. package/src/extensions/tools/definitions.test.ts +0 -780
  295. package/src/extensions/tools/executors/bash.test.ts +0 -87
  296. package/src/extensions/tools/executors/editor.test.ts +0 -35
  297. package/src/extensions/tools/executors/file-read.test.ts +0 -125
  298. package/src/extensions/tools/model-tool-routing.test.ts +0 -86
  299. package/src/extensions/tools/presets.test.ts +0 -70
  300. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
  301. package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
  302. package/src/extensions/tools/team/team-tools.test.ts +0 -918
  303. package/src/hooks/checkpoint-hooks.test.ts +0 -168
  304. package/src/hooks/hook-file-hooks.test.ts +0 -311
  305. package/src/hooks/persistent.ts +0 -661
  306. package/src/runtime/history.test.ts +0 -114
  307. package/src/runtime/host.test.ts +0 -230
  308. package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
  309. package/src/runtime/rpc-runtime-ensure.ts +0 -659
  310. package/src/runtime/rpc-spawn-lease.test.ts +0 -81
  311. package/src/runtime/rpc-spawn-lease.ts +0 -156
  312. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
  313. package/src/runtime/runtime-builder.test.ts +0 -615
  314. package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
  315. package/src/runtime/runtime-parity.test.ts +0 -143
  316. package/src/services/providers/local-provider-service.test.ts +0 -1062
  317. package/src/services/session-data.test.ts +0 -160
  318. package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
  319. package/src/services/storage/provider-settings-manager.test.ts +0 -191
  320. package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  321. package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
  322. package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
  323. package/src/services/telemetry/TelemetryService.test.ts +0 -134
  324. package/src/services/telemetry/distinct-id.test.ts +0 -57
  325. package/src/services/workspace/file-indexer.d.ts +0 -11
  326. package/src/services/workspace/file-indexer.test.ts +0 -156
  327. package/src/services/workspace/mention-enricher.test.ts +0 -106
  328. package/src/session/persistence-service.test.ts +0 -300
  329. package/src/session/rpc-session-service.ts +0 -114
  330. package/src/session/session-service.team-persistence.test.ts +0 -48
  331. package/src/session/sqlite-rpc-session-backend.ts +0 -301
  332. package/src/transports/local.e2e.test.ts +0 -380
  333. package/src/transports/local.test.ts +0 -2559
  334. package/src/transports/rpc.test.ts +0 -82
  335. package/src/transports/rpc.ts +0 -665
@@ -1,175 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { ClineAccountService } from "./cline-account-service";
3
- import {
4
- type ClineAccountOperations,
5
- executeRpcClineAccountAction,
6
- RpcClineAccountService,
7
- } from "./rpc";
8
-
9
- describe("ClineAccountService.fetchFeaturebaseToken", () => {
10
- it("returns featurebaseJwt on success", async () => {
11
- const fetchImpl = vi.fn(async (input: unknown, init?: RequestInit) => {
12
- expect(String(input)).toBe(
13
- "https://api.cline.bot/api/v1/users/me/featurebase-token",
14
- );
15
- expect(init?.headers).toMatchObject({
16
- Authorization: "Bearer workos:token-123",
17
- });
18
- return new Response(
19
- JSON.stringify({
20
- success: true,
21
- data: { featurebaseJwt: "eyJhbGciOiJIUzI1NiJ9.test.sig" },
22
- }),
23
- { status: 200, headers: { "Content-Type": "application/json" } },
24
- );
25
- });
26
-
27
- const service = new ClineAccountService({
28
- apiBaseUrl: "https://api.cline.bot",
29
- getAuthToken: async () => "workos:token-123",
30
- fetchImpl: fetchImpl as unknown as typeof fetch,
31
- });
32
-
33
- const result = await service.fetchFeaturebaseToken();
34
- expect(result).toEqual({
35
- featurebaseJwt: "eyJhbGciOiJIUzI1NiJ9.test.sig",
36
- });
37
- expect(fetchImpl).toHaveBeenCalledTimes(1);
38
- });
39
-
40
- it("returns undefined on network/request error", async () => {
41
- const fetchImpl = vi.fn(async () => {
42
- throw new Error("Network error");
43
- });
44
-
45
- const service = new ClineAccountService({
46
- apiBaseUrl: "https://api.cline.bot",
47
- getAuthToken: async () => "workos:token-123",
48
- fetchImpl: fetchImpl as unknown as typeof fetch,
49
- });
50
-
51
- const result = await service.fetchFeaturebaseToken();
52
- expect(result).toBeUndefined();
53
- });
54
-
55
- it("returns undefined when auth token is missing", async () => {
56
- const fetchImpl = vi.fn();
57
-
58
- const service = new ClineAccountService({
59
- apiBaseUrl: "https://api.cline.bot",
60
- getAuthToken: async () => undefined,
61
- fetchImpl: fetchImpl as unknown as typeof fetch,
62
- });
63
-
64
- const result = await service.fetchFeaturebaseToken();
65
- expect(result).toBeUndefined();
66
- expect(fetchImpl).not.toHaveBeenCalled();
67
- });
68
-
69
- it("returns undefined on HTTP error response", async () => {
70
- const fetchImpl = vi.fn(async () => {
71
- return new Response(JSON.stringify({ error: "Unauthorized" }), {
72
- status: 401,
73
- headers: { "Content-Type": "application/json" },
74
- });
75
- });
76
-
77
- const service = new ClineAccountService({
78
- apiBaseUrl: "https://api.cline.bot",
79
- getAuthToken: async () => "workos:token-123",
80
- fetchImpl: fetchImpl as unknown as typeof fetch,
81
- });
82
-
83
- const result = await service.fetchFeaturebaseToken();
84
- expect(result).toBeUndefined();
85
- });
86
- });
87
-
88
- describe("executeRpcClineAccountAction - fetchFeaturebaseToken", () => {
89
- it("dispatches fetchFeaturebaseToken", async () => {
90
- const service: ClineAccountOperations = {
91
- fetchMe: vi.fn(async () => ({
92
- id: "u1",
93
- email: "user1@example.com",
94
- displayName: "User 1",
95
- photoUrl: "",
96
- createdAt: "2025-01-01T00:00:00Z",
97
- updatedAt: "2025-01-01T00:00:00Z",
98
- organizations: [],
99
- })),
100
- fetchBalance: vi.fn(async () => ({ balance: 1, userId: "u1" })),
101
- fetchUsageTransactions: vi.fn(async () => []),
102
- fetchPaymentTransactions: vi.fn(async () => []),
103
- fetchUserOrganizations: vi.fn(async () => []),
104
- fetchOrganizationBalance: vi.fn(async () => ({
105
- balance: 1,
106
- organizationId: "org-1",
107
- })),
108
- fetchOrganizationUsageTransactions: vi.fn(async () => []),
109
- switchAccount: vi.fn(async () => {}),
110
- fetchFeaturebaseToken: vi.fn(async () => ({
111
- featurebaseJwt: "mock-jwt-token",
112
- })),
113
- };
114
-
115
- const result = await executeRpcClineAccountAction(
116
- { action: "clineAccount", operation: "fetchFeaturebaseToken" },
117
- service,
118
- );
119
- expect(service.fetchFeaturebaseToken).toHaveBeenCalledTimes(1);
120
- expect(result).toEqual({ featurebaseJwt: "mock-jwt-token" });
121
- });
122
-
123
- it("returns undefined when fetchFeaturebaseToken is not implemented", async () => {
124
- const service: ClineAccountOperations = {
125
- fetchMe: vi.fn(async () => ({
126
- id: "u1",
127
- email: "user1@example.com",
128
- displayName: "User 1",
129
- photoUrl: "",
130
- createdAt: "2025-01-01T00:00:00Z",
131
- updatedAt: "2025-01-01T00:00:00Z",
132
- organizations: [],
133
- })),
134
- fetchBalance: vi.fn(async () => ({ balance: 1, userId: "u1" })),
135
- fetchUsageTransactions: vi.fn(async () => []),
136
- fetchPaymentTransactions: vi.fn(async () => []),
137
- fetchUserOrganizations: vi.fn(async () => []),
138
- fetchOrganizationBalance: vi.fn(async () => ({
139
- balance: 1,
140
- organizationId: "org-1",
141
- })),
142
- fetchOrganizationUsageTransactions: vi.fn(async () => []),
143
- switchAccount: vi.fn(async () => {}),
144
- };
145
-
146
- const result = await executeRpcClineAccountAction(
147
- { action: "clineAccount", operation: "fetchFeaturebaseToken" },
148
- service,
149
- );
150
- expect(result).toBeUndefined();
151
- });
152
- });
153
-
154
- describe("RpcClineAccountService.fetchFeaturebaseToken", () => {
155
- it("sends provider action payload and parses response", async () => {
156
- const runProviderAction = vi.fn(async (request: unknown) => {
157
- const parsed = request as {
158
- action: string;
159
- operation: string;
160
- };
161
- expect(parsed).toEqual({
162
- action: "clineAccount",
163
- operation: "fetchFeaturebaseToken",
164
- });
165
- return {
166
- result: { featurebaseJwt: "rpc-jwt-token" },
167
- };
168
- });
169
- const service = new RpcClineAccountService({ runProviderAction });
170
-
171
- const result = await service.fetchFeaturebaseToken();
172
- expect(runProviderAction).toHaveBeenCalledTimes(1);
173
- expect(result).toEqual({ featurebaseJwt: "rpc-jwt-token" });
174
- });
175
- });
@@ -1,63 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import {
3
- type ClineAccountOperations,
4
- executeRpcClineAccountAction,
5
- RpcClineAccountService,
6
- } from "./rpc";
7
-
8
- describe("executeRpcClineAccountAction", () => {
9
- it("dispatches fetchMe", async () => {
10
- const service: ClineAccountOperations = {
11
- fetchMe: vi.fn(async () => ({
12
- id: "u1",
13
- email: "user1@example.com",
14
- displayName: "User 1",
15
- photoUrl: "",
16
- createdAt: "2025-01-01T00:00:00Z",
17
- updatedAt: "2025-01-01T00:00:00Z",
18
- organizations: [],
19
- })),
20
- fetchBalance: vi.fn(async () => ({ balance: 1, userId: "u1" })),
21
- fetchUsageTransactions: vi.fn(async () => []),
22
- fetchPaymentTransactions: vi.fn(async () => []),
23
- fetchUserOrganizations: vi.fn(async () => []),
24
- fetchOrganizationBalance: vi.fn(async () => ({
25
- balance: 1,
26
- organizationId: "org-1",
27
- })),
28
- fetchOrganizationUsageTransactions: vi.fn(async () => []),
29
- switchAccount: vi.fn(async () => {}),
30
- fetchFeaturebaseToken: vi.fn(async () => undefined),
31
- };
32
-
33
- const result = await executeRpcClineAccountAction(
34
- { action: "clineAccount", operation: "fetchMe" },
35
- service,
36
- );
37
- expect(service.fetchMe).toHaveBeenCalledTimes(1);
38
- expect(result).toMatchObject({ id: "u1" });
39
- });
40
- });
41
-
42
- describe("RpcClineAccountService", () => {
43
- it("sends provider action payload and parses response", async () => {
44
- const runProviderAction = vi.fn(async (request: unknown) => {
45
- const parsed = request as {
46
- action: string;
47
- operation: string;
48
- };
49
- expect(parsed).toEqual({
50
- action: "clineAccount",
51
- operation: "fetchMe",
52
- });
53
- return {
54
- result: { id: "u2", email: "u2@example.com" },
55
- };
56
- });
57
- const service = new RpcClineAccountService({ runProviderAction });
58
-
59
- const me = await service.fetchMe();
60
- expect(runProviderAction).toHaveBeenCalledTimes(1);
61
- expect(me).toEqual({ id: "u2", email: "u2@example.com" });
62
- });
63
- });
@@ -1,38 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { BoundedTtlCache } from "./bounded-ttl-cache";
3
-
4
- describe("BoundedTtlCache", () => {
5
- it("returns undefined after TTL", () => {
6
- const cache = new BoundedTtlCache(1_000, 10);
7
- cache.set("a", "one", 0);
8
- expect(cache.get("a", 500)).toBe("one");
9
- expect(cache.get("a", 1_500)).toBeUndefined();
10
- });
11
-
12
- it("evicts oldest entries when over max size", () => {
13
- const cache = new BoundedTtlCache(60_000, 2);
14
- cache.set("a", "1", 0);
15
- cache.set("b", "2", 0);
16
- cache.set("c", "3", 0);
17
- expect(cache.get("a", 0)).toBeUndefined();
18
- expect(cache.get("b", 0)).toBe("2");
19
- expect(cache.get("c", 0)).toBe("3");
20
- });
21
-
22
- it("refreshes recency on get so hot keys survive eviction", () => {
23
- const cache = new BoundedTtlCache(60_000, 2);
24
- cache.set("a", "1", 0);
25
- cache.set("b", "2", 0);
26
- expect(cache.get("a", 0)).toBe("1");
27
- cache.set("c", "3", 0);
28
- expect(cache.get("a", 0)).toBe("1");
29
- expect(cache.get("b", 0)).toBeUndefined();
30
- });
31
-
32
- it("supports per-entry TTL override", () => {
33
- const cache = new BoundedTtlCache(60_000, 2);
34
- cache.set("short", "v", 0, 1_000);
35
- expect(cache.get("short", 500)).toBe("v");
36
- expect(cache.get("short", 1_500)).toBeUndefined();
37
- });
38
- });
@@ -1,69 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { createOAuthClientCallbacks } from "./client";
3
-
4
- describe("auth/client createOAuthClientCallbacks", () => {
5
- it("emits instructions and URL and forwards prompts", async () => {
6
- const onOutput = vi.fn();
7
- const onPrompt = vi.fn().mockResolvedValue("value");
8
- const callbacks = createOAuthClientCallbacks({ onOutput, onPrompt });
9
-
10
- callbacks.onAuth({
11
- url: "https://example.com/auth",
12
- instructions: "Open your browser",
13
- });
14
- const answer = await callbacks.onPrompt({ message: "Enter code" });
15
-
16
- expect(answer).toBe("value");
17
- expect(onPrompt).toHaveBeenCalledWith({ message: "Enter code" });
18
- expect(onOutput).toHaveBeenNthCalledWith(1, "Open your browser");
19
- expect(onOutput).toHaveBeenNthCalledWith(2, "https://example.com/auth");
20
- });
21
-
22
- it("tries opening URL and reports opener errors", async () => {
23
- const openUrl = vi.fn().mockRejectedValue(new Error("failed"));
24
- const onOpenUrlError = vi.fn();
25
- const callbacks = createOAuthClientCallbacks({
26
- onPrompt: vi.fn().mockResolvedValue(""),
27
- openUrl,
28
- onOpenUrlError,
29
- });
30
-
31
- callbacks.onAuth({ url: "https://example.com/auth" });
32
- await Promise.resolve();
33
-
34
- expect(openUrl).toHaveBeenCalledWith("https://example.com/auth");
35
- expect(onOpenUrlError).toHaveBeenCalledTimes(1);
36
- expect(onOpenUrlError.mock.calls[0]?.[0]).toMatchObject({
37
- url: "https://example.com/auth",
38
- });
39
- });
40
-
41
- it("forwards onServerListening to the returned callbacks", () => {
42
- const onServerListening = vi.fn();
43
- const callbacks = createOAuthClientCallbacks({
44
- onPrompt: vi.fn().mockResolvedValue(""),
45
- onServerListening,
46
- });
47
-
48
- expect(callbacks.onServerListening).toBe(onServerListening);
49
- });
50
-
51
- it("forwards onServerClose to the returned callbacks", () => {
52
- const onServerClose = vi.fn();
53
- const callbacks = createOAuthClientCallbacks({
54
- onPrompt: vi.fn().mockResolvedValue(""),
55
- onServerClose,
56
- });
57
-
58
- expect(callbacks.onServerClose).toBe(onServerClose);
59
- });
60
-
61
- it("leaves onServerListening and onServerClose undefined when not provided", () => {
62
- const callbacks = createOAuthClientCallbacks({
63
- onPrompt: vi.fn().mockResolvedValue(""),
64
- });
65
-
66
- expect(callbacks.onServerListening).toBeUndefined();
67
- expect(callbacks.onServerClose).toBeUndefined();
68
- });
69
- });
@@ -1,267 +0,0 @@
1
- import { afterEach, describe, expect, it, vi } from "vitest";
2
- import type { ClineOAuthCredentials } from "./cline";
3
- import { getValidClineCredentials, loginClineOAuth } from "./cline";
4
-
5
- const PROVIDER_OPTIONS = {
6
- apiBaseUrl: "https://auth.example.com",
7
- };
8
- const ORIGINAL_FETCH = globalThis.fetch;
9
-
10
- function createCredentials(
11
- overrides: Partial<ClineOAuthCredentials> = {},
12
- ): ClineOAuthCredentials {
13
- return {
14
- access: "access-old",
15
- refresh: "refresh-old",
16
- expires: 0,
17
- accountId: "acct-1",
18
- email: "user@example.com",
19
- metadata: { provider: "google" },
20
- ...overrides,
21
- };
22
- }
23
-
24
- describe("auth/cline getValidClineCredentials", () => {
25
- afterEach(() => {
26
- vi.restoreAllMocks();
27
- globalThis.fetch = ORIGINAL_FETCH;
28
- });
29
-
30
- it("returns existing credentials when not expired", async () => {
31
- const nowSpy = vi.spyOn(Date, "now").mockReturnValue(10_000);
32
- const current = createCredentials({ expires: 400_000 });
33
- const fetchMock = vi.fn();
34
- globalThis.fetch = fetchMock as unknown as typeof fetch;
35
-
36
- const result = await getValidClineCredentials(current, PROVIDER_OPTIONS);
37
- expect(result).toBe(current);
38
- expect(fetchMock).not.toHaveBeenCalled();
39
- nowSpy.mockRestore();
40
- });
41
-
42
- it("refreshes expired credentials", async () => {
43
- const nowSpy = vi.spyOn(Date, "now").mockReturnValue(100_000);
44
- const current = createCredentials({ expires: 101_000 });
45
- const fetchMock = vi.fn(
46
- async () =>
47
- new Response(
48
- JSON.stringify({
49
- success: true,
50
- data: {
51
- accessToken: "access-new",
52
- refreshToken: "refresh-new",
53
- tokenType: "Bearer",
54
- expiresAt: "2030-01-01T00:00:00.000Z",
55
- userInfo: {
56
- subject: "sub-1",
57
- email: "new@example.com",
58
- name: "New User",
59
- clineUserId: "acct-2",
60
- accounts: [],
61
- },
62
- },
63
- }),
64
- { status: 200, headers: { "Content-Type": "application/json" } },
65
- ),
66
- );
67
- globalThis.fetch = fetchMock as unknown as typeof fetch;
68
-
69
- const result = await getValidClineCredentials(current, PROVIDER_OPTIONS);
70
- expect(result).toMatchObject({
71
- access: "access-new",
72
- refresh: "refresh-new",
73
- accountId: "acct-2",
74
- email: "new@example.com",
75
- });
76
- nowSpy.mockRestore();
77
- });
78
-
79
- it("returns null when refresh fails with invalid_grant", async () => {
80
- const nowSpy = vi.spyOn(Date, "now").mockReturnValue(100_000);
81
- const current = createCredentials({ expires: 101_000 });
82
- globalThis.fetch = vi.fn(
83
- async () =>
84
- new Response(
85
- JSON.stringify({
86
- error: "invalid_grant",
87
- error_description: "refresh expired",
88
- }),
89
- {
90
- status: 401,
91
- headers: { "Content-Type": "application/json" },
92
- },
93
- ),
94
- ) as unknown as typeof fetch;
95
-
96
- const result = await getValidClineCredentials(current, PROVIDER_OPTIONS);
97
- expect(result).toBeNull();
98
- nowSpy.mockRestore();
99
- });
100
-
101
- it("keeps current credentials on transient refresh error while token remains valid", async () => {
102
- const nowSpy = vi.spyOn(Date, "now").mockReturnValue(100_000);
103
- const current = createCredentials({ expires: 150_000 });
104
- globalThis.fetch = vi.fn(
105
- async () =>
106
- new Response(
107
- JSON.stringify({
108
- error: "server_error",
109
- error_description: "temporary issue",
110
- }),
111
- {
112
- status: 500,
113
- headers: { "Content-Type": "application/json" },
114
- },
115
- ),
116
- ) as unknown as typeof fetch;
117
-
118
- const result = await getValidClineCredentials(current, PROVIDER_OPTIONS, {
119
- refreshBufferMs: 60_000,
120
- retryableTokenGraceMs: 30_000,
121
- });
122
- expect(result).toBe(current);
123
- nowSpy.mockRestore();
124
- });
125
- });
126
-
127
- describe("auth/cline loginClineOAuth", () => {
128
- afterEach(() => {
129
- vi.restoreAllMocks();
130
- globalThis.fetch = ORIGINAL_FETCH;
131
- });
132
-
133
- it("completes WorkOS device auth and registers tokens", async () => {
134
- const fetchMock = vi
135
- .fn()
136
- .mockResolvedValueOnce(
137
- new Response(
138
- JSON.stringify({
139
- device_code: "dev-code-1",
140
- user_code: "ABCD-EFGH",
141
- verification_uri: "https://example.com/device",
142
- verification_uri_complete:
143
- "https://example.com/device?user_code=ABCD-EFGH",
144
- expires_in: 300,
145
- interval: 1,
146
- }),
147
- { status: 200, headers: { "Content-Type": "application/json" } },
148
- ),
149
- )
150
- .mockResolvedValueOnce(
151
- new Response(
152
- JSON.stringify({
153
- access_token: "workos-access",
154
- refresh_token: "workos-refresh",
155
- token_type: "Bearer",
156
- expires_in: 3600,
157
- }),
158
- { status: 200, headers: { "Content-Type": "application/json" } },
159
- ),
160
- )
161
- .mockResolvedValueOnce(
162
- new Response(
163
- JSON.stringify({
164
- success: true,
165
- data: {
166
- accessToken: "cline-access",
167
- refreshToken: "cline-refresh",
168
- tokenType: "Bearer",
169
- expiresAt: "2030-01-01T00:00:00.000Z",
170
- userInfo: {
171
- subject: "sub-1",
172
- email: "user@example.com",
173
- name: "User",
174
- clineUserId: "acct-1",
175
- accounts: ["acct-1"],
176
- },
177
- },
178
- }),
179
- { status: 200, headers: { "Content-Type": "application/json" } },
180
- ),
181
- );
182
- globalThis.fetch = fetchMock as unknown as typeof fetch;
183
-
184
- const onAuth = vi.fn();
185
- const credentials = await loginClineOAuth({
186
- apiBaseUrl: "https://api.cline.bot",
187
- useWorkOSDeviceAuth: true,
188
- callbacks: {
189
- onAuth,
190
- onPrompt: async () => "",
191
- },
192
- });
193
-
194
- expect(onAuth).toHaveBeenCalledTimes(1);
195
- expect(onAuth.mock.calls[0]?.[0]).toMatchObject({
196
- url: "https://example.com/device?user_code=ABCD-EFGH",
197
- });
198
- expect(credentials).toMatchObject({
199
- access: "cline-access",
200
- refresh: "cline-refresh",
201
- accountId: "acct-1",
202
- email: "user@example.com",
203
- });
204
- expect(fetchMock).toHaveBeenCalledTimes(3);
205
- const registerCallBody = JSON.parse(
206
- String(fetchMock.mock.calls[2]?.[1]?.body ?? "{}"),
207
- );
208
- const deviceAuthBody = String(fetchMock.mock.calls[0]?.[1]?.body ?? "");
209
- const deviceAuthParams = new URLSearchParams(deviceAuthBody);
210
- expect(deviceAuthParams.get("client_id")).toMatch(/client_.*/);
211
- expect(registerCallBody).toMatchObject({
212
- accessToken: "workos-access",
213
- refreshToken: "workos-refresh",
214
- });
215
- });
216
-
217
- it("uses legacy callback OAuth flow by default", async () => {
218
- const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => {
219
- const body =
220
- typeof init?.body === "string"
221
- ? (JSON.parse(init.body) as Record<string, unknown>)
222
- : {};
223
- if (body.grant_type === "authorization_code") {
224
- return new Response(
225
- JSON.stringify({
226
- success: true,
227
- data: {
228
- accessToken: "legacy-access",
229
- refreshToken: "legacy-refresh",
230
- tokenType: "Bearer",
231
- expiresAt: "2030-01-01T00:00:00.000Z",
232
- userInfo: {
233
- subject: "sub-legacy",
234
- email: "legacy@example.com",
235
- name: "Legacy User",
236
- clineUserId: "acct-legacy",
237
- accounts: ["acct-legacy"],
238
- },
239
- },
240
- }),
241
- { status: 200, headers: { "Content-Type": "application/json" } },
242
- );
243
- }
244
- return new Response("not-found", { status: 404 });
245
- });
246
- globalThis.fetch = fetchMock as unknown as typeof fetch;
247
-
248
- const credentials = await loginClineOAuth({
249
- apiBaseUrl: "https://api.cline.bot",
250
- callbackPorts: [48801],
251
- callbacks: {
252
- onAuth: () => {},
253
- onPrompt: async () => "http://127.0.0.1:48801/auth?code=legacy-code",
254
- onManualCodeInput: async () =>
255
- "http://127.0.0.1:48801/auth?code=legacy-code",
256
- },
257
- });
258
-
259
- expect(credentials).toMatchObject({
260
- access: "legacy-access",
261
- refresh: "legacy-refresh",
262
- accountId: "acct-legacy",
263
- email: "legacy@example.com",
264
- });
265
- expect(fetchMock).toHaveBeenCalledTimes(1);
266
- });
267
- });