@clinebot/core 0.0.22 → 0.0.24

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 (260) hide show
  1. package/dist/ClineCore.d.ts +110 -0
  2. package/dist/ClineCore.d.ts.map +1 -0
  3. package/dist/account/cline-account-service.d.ts +2 -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 +3 -1
  8. package/dist/account/rpc.d.ts.map +1 -1
  9. package/dist/account/types.d.ts +3 -0
  10. package/dist/account/types.d.ts.map +1 -1
  11. package/dist/agents/plugin-loader.d.ts.map +1 -1
  12. package/dist/agents/plugin-sandbox-bootstrap.js +17 -17
  13. package/dist/auth/client.d.ts +1 -1
  14. package/dist/auth/client.d.ts.map +1 -1
  15. package/dist/auth/cline.d.ts +1 -1
  16. package/dist/auth/cline.d.ts.map +1 -1
  17. package/dist/auth/codex.d.ts +1 -1
  18. package/dist/auth/codex.d.ts.map +1 -1
  19. package/dist/auth/oca.d.ts +1 -1
  20. package/dist/auth/oca.d.ts.map +1 -1
  21. package/dist/auth/utils.d.ts +2 -2
  22. package/dist/auth/utils.d.ts.map +1 -1
  23. package/dist/index.d.ts +50 -5
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +949 -0
  26. package/dist/providers/local-provider-service.d.ts +4 -4
  27. package/dist/providers/local-provider-service.d.ts.map +1 -1
  28. package/dist/runtime/runtime-builder.d.ts +1 -0
  29. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  30. package/dist/runtime/session-runtime.d.ts +2 -1
  31. package/dist/runtime/session-runtime.d.ts.map +1 -1
  32. package/dist/runtime/team-runtime-registry.d.ts +13 -0
  33. package/dist/runtime/team-runtime-registry.d.ts.map +1 -0
  34. package/dist/session/default-session-manager.d.ts +2 -2
  35. package/dist/session/default-session-manager.d.ts.map +1 -1
  36. package/dist/session/rpc-runtime-ensure.d.ts +53 -0
  37. package/dist/session/rpc-runtime-ensure.d.ts.map +1 -0
  38. package/dist/session/session-config-builder.d.ts +2 -3
  39. package/dist/session/session-config-builder.d.ts.map +1 -1
  40. package/dist/session/session-host.d.ts +8 -18
  41. package/dist/session/session-host.d.ts.map +1 -1
  42. package/dist/session/session-manager.d.ts +1 -1
  43. package/dist/session/session-manager.d.ts.map +1 -1
  44. package/dist/session/session-manifest.d.ts +1 -2
  45. package/dist/session/session-manifest.d.ts.map +1 -1
  46. package/dist/session/unified-session-persistence-service.d.ts +2 -2
  47. package/dist/session/unified-session-persistence-service.d.ts.map +1 -1
  48. package/dist/session/utils/helpers.d.ts +1 -1
  49. package/dist/session/utils/helpers.d.ts.map +1 -1
  50. package/dist/session/utils/types.d.ts +1 -1
  51. package/dist/session/utils/types.d.ts.map +1 -1
  52. package/dist/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  53. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
  54. package/dist/telemetry/distinct-id.d.ts +2 -0
  55. package/dist/telemetry/distinct-id.d.ts.map +1 -0
  56. package/dist/telemetry/{opentelemetry.d.ts → index.d.ts} +1 -1
  57. package/dist/telemetry/index.d.ts.map +1 -0
  58. package/dist/telemetry/index.js +28 -0
  59. package/dist/tools/constants.d.ts +1 -1
  60. package/dist/tools/constants.d.ts.map +1 -1
  61. package/dist/tools/definitions.d.ts +3 -3
  62. package/dist/tools/definitions.d.ts.map +1 -1
  63. package/dist/tools/executors/apply-patch.d.ts +1 -1
  64. package/dist/tools/executors/apply-patch.d.ts.map +1 -1
  65. package/dist/tools/executors/bash.d.ts +1 -1
  66. package/dist/tools/executors/bash.d.ts.map +1 -1
  67. package/dist/tools/executors/editor.d.ts +1 -1
  68. package/dist/tools/executors/editor.d.ts.map +1 -1
  69. package/dist/tools/executors/file-read.d.ts +1 -1
  70. package/dist/tools/executors/file-read.d.ts.map +1 -1
  71. package/dist/tools/executors/index.d.ts +14 -14
  72. package/dist/tools/executors/index.d.ts.map +1 -1
  73. package/dist/tools/executors/search.d.ts +1 -1
  74. package/dist/tools/executors/search.d.ts.map +1 -1
  75. package/dist/tools/executors/web-fetch.d.ts +1 -1
  76. package/dist/tools/executors/web-fetch.d.ts.map +1 -1
  77. package/dist/tools/helpers.d.ts +1 -1
  78. package/dist/tools/helpers.d.ts.map +1 -1
  79. package/dist/tools/index.d.ts +10 -10
  80. package/dist/tools/index.d.ts.map +1 -1
  81. package/dist/tools/model-tool-routing.d.ts +1 -1
  82. package/dist/tools/model-tool-routing.d.ts.map +1 -1
  83. package/dist/tools/presets.d.ts +1 -1
  84. package/dist/tools/presets.d.ts.map +1 -1
  85. package/dist/types/common.d.ts +17 -8
  86. package/dist/types/common.d.ts.map +1 -1
  87. package/dist/types/config.d.ts +4 -3
  88. package/dist/types/config.d.ts.map +1 -1
  89. package/dist/types/provider-settings.d.ts +1 -1
  90. package/dist/types/provider-settings.d.ts.map +1 -1
  91. package/dist/types.d.ts +5 -2
  92. package/dist/types.d.ts.map +1 -1
  93. package/dist/version.d.ts +2 -0
  94. package/dist/version.d.ts.map +1 -0
  95. package/package.json +44 -38
  96. package/src/ClineCore.ts +137 -0
  97. package/src/account/cline-account-service.test.ts +101 -0
  98. package/src/account/cline-account-service.ts +300 -0
  99. package/src/account/featurebase-token.test.ts +175 -0
  100. package/src/account/index.ts +23 -0
  101. package/src/account/rpc.test.ts +63 -0
  102. package/src/account/rpc.ts +185 -0
  103. package/src/account/types.ts +102 -0
  104. package/src/agents/agent-config-loader.test.ts +236 -0
  105. package/src/agents/agent-config-loader.ts +108 -0
  106. package/src/agents/agent-config-parser.ts +198 -0
  107. package/src/agents/hooks-config-loader.test.ts +20 -0
  108. package/src/agents/hooks-config-loader.ts +118 -0
  109. package/src/agents/index.ts +85 -0
  110. package/src/agents/plugin-config-loader.test.ts +140 -0
  111. package/src/agents/plugin-config-loader.ts +97 -0
  112. package/src/agents/plugin-loader.test.ts +210 -0
  113. package/src/agents/plugin-loader.ts +175 -0
  114. package/src/agents/plugin-sandbox-bootstrap.ts +448 -0
  115. package/src/agents/plugin-sandbox.test.ts +296 -0
  116. package/src/agents/plugin-sandbox.ts +341 -0
  117. package/src/agents/unified-config-file-watcher.test.ts +196 -0
  118. package/src/agents/unified-config-file-watcher.ts +483 -0
  119. package/src/agents/user-instruction-config-loader.test.ts +158 -0
  120. package/src/agents/user-instruction-config-loader.ts +438 -0
  121. package/src/auth/client.test.ts +40 -0
  122. package/src/auth/client.ts +25 -0
  123. package/src/auth/cline.test.ts +130 -0
  124. package/src/auth/cline.ts +420 -0
  125. package/src/auth/codex.test.ts +170 -0
  126. package/src/auth/codex.ts +491 -0
  127. package/src/auth/oca.test.ts +215 -0
  128. package/src/auth/oca.ts +573 -0
  129. package/src/auth/server.ts +216 -0
  130. package/src/auth/types.ts +81 -0
  131. package/src/auth/utils.test.ts +128 -0
  132. package/src/auth/utils.ts +247 -0
  133. package/src/chat/chat-schema.ts +82 -0
  134. package/src/index.ts +479 -0
  135. package/src/input/file-indexer.d.ts +11 -0
  136. package/src/input/file-indexer.test.ts +127 -0
  137. package/src/input/file-indexer.ts +327 -0
  138. package/src/input/index.ts +7 -0
  139. package/src/input/mention-enricher.test.ts +85 -0
  140. package/src/input/mention-enricher.ts +122 -0
  141. package/src/mcp/config-loader.test.ts +238 -0
  142. package/src/mcp/config-loader.ts +219 -0
  143. package/src/mcp/index.ts +26 -0
  144. package/src/mcp/manager.test.ts +106 -0
  145. package/src/mcp/manager.ts +262 -0
  146. package/src/mcp/types.ts +88 -0
  147. package/src/providers/local-provider-registry.ts +232 -0
  148. package/src/providers/local-provider-service.test.ts +783 -0
  149. package/src/providers/local-provider-service.ts +471 -0
  150. package/src/runtime/commands.test.ts +98 -0
  151. package/src/runtime/commands.ts +83 -0
  152. package/src/runtime/hook-file-hooks.test.ts +237 -0
  153. package/src/runtime/hook-file-hooks.ts +859 -0
  154. package/src/runtime/index.ts +37 -0
  155. package/src/runtime/rules.ts +34 -0
  156. package/src/runtime/runtime-builder.team-persistence.test.ts +245 -0
  157. package/src/runtime/runtime-builder.test.ts +371 -0
  158. package/src/runtime/runtime-builder.ts +631 -0
  159. package/src/runtime/runtime-parity.test.ts +143 -0
  160. package/src/runtime/sandbox/subprocess-sandbox.ts +231 -0
  161. package/src/runtime/session-runtime.ts +49 -0
  162. package/src/runtime/skills.ts +44 -0
  163. package/src/runtime/team-runtime-registry.ts +46 -0
  164. package/src/runtime/tool-approval.ts +104 -0
  165. package/src/runtime/workflows.test.ts +119 -0
  166. package/src/runtime/workflows.ts +45 -0
  167. package/src/session/default-session-manager.e2e.test.ts +384 -0
  168. package/src/session/default-session-manager.test.ts +1931 -0
  169. package/src/session/default-session-manager.ts +1422 -0
  170. package/src/session/file-session-service.ts +280 -0
  171. package/src/session/index.ts +45 -0
  172. package/src/session/rpc-runtime-ensure.ts +521 -0
  173. package/src/session/rpc-session-service.ts +107 -0
  174. package/src/session/rpc-spawn-lease.test.ts +49 -0
  175. package/src/session/rpc-spawn-lease.ts +122 -0
  176. package/src/session/runtime-oauth-token-manager.test.ts +137 -0
  177. package/src/session/runtime-oauth-token-manager.ts +272 -0
  178. package/src/session/session-agent-events.ts +248 -0
  179. package/src/session/session-artifacts.ts +106 -0
  180. package/src/session/session-config-builder.ts +113 -0
  181. package/src/session/session-graph.ts +92 -0
  182. package/src/session/session-host.test.ts +89 -0
  183. package/src/session/session-host.ts +205 -0
  184. package/src/session/session-manager.ts +69 -0
  185. package/src/session/session-manifest.ts +29 -0
  186. package/src/session/session-service.team-persistence.test.ts +48 -0
  187. package/src/session/session-service.ts +673 -0
  188. package/src/session/session-team-coordination.ts +229 -0
  189. package/src/session/session-telemetry.ts +100 -0
  190. package/src/session/sqlite-rpc-session-backend.ts +303 -0
  191. package/src/session/unified-session-persistence-service.test.ts +85 -0
  192. package/src/session/unified-session-persistence-service.ts +994 -0
  193. package/src/session/utils/helpers.ts +139 -0
  194. package/src/session/utils/types.ts +57 -0
  195. package/src/session/utils/usage.ts +32 -0
  196. package/src/session/workspace-manager.ts +98 -0
  197. package/src/session/workspace-manifest.ts +100 -0
  198. package/src/storage/artifact-store.ts +1 -0
  199. package/src/storage/file-team-store.ts +257 -0
  200. package/src/storage/index.ts +11 -0
  201. package/src/storage/provider-settings-legacy-migration.test.ts +424 -0
  202. package/src/storage/provider-settings-legacy-migration.ts +826 -0
  203. package/src/storage/provider-settings-manager.test.ts +191 -0
  204. package/src/storage/provider-settings-manager.ts +152 -0
  205. package/src/storage/session-store.ts +1 -0
  206. package/src/storage/sqlite-session-store.ts +275 -0
  207. package/src/storage/sqlite-team-store.ts +454 -0
  208. package/src/storage/team-store.ts +40 -0
  209. package/src/team/index.ts +4 -0
  210. package/src/team/projections.ts +285 -0
  211. package/src/telemetry/ITelemetryAdapter.ts +94 -0
  212. package/src/telemetry/LoggerTelemetryAdapter.test.ts +42 -0
  213. package/src/telemetry/LoggerTelemetryAdapter.ts +114 -0
  214. package/src/telemetry/OpenTelemetryAdapter.test.ts +157 -0
  215. package/src/telemetry/OpenTelemetryAdapter.ts +348 -0
  216. package/src/telemetry/OpenTelemetryProvider.test.ts +113 -0
  217. package/src/telemetry/OpenTelemetryProvider.ts +325 -0
  218. package/src/telemetry/TelemetryService.test.ts +134 -0
  219. package/src/telemetry/TelemetryService.ts +141 -0
  220. package/src/telemetry/core-events.ts +400 -0
  221. package/src/telemetry/distinct-id.test.ts +57 -0
  222. package/src/telemetry/distinct-id.ts +58 -0
  223. package/src/telemetry/index.ts +20 -0
  224. package/src/tools/constants.ts +35 -0
  225. package/src/tools/definitions.test.ts +704 -0
  226. package/src/tools/definitions.ts +709 -0
  227. package/src/tools/executors/apply-patch-parser.ts +520 -0
  228. package/src/tools/executors/apply-patch.ts +359 -0
  229. package/src/tools/executors/bash.test.ts +87 -0
  230. package/src/tools/executors/bash.ts +207 -0
  231. package/src/tools/executors/editor.test.ts +35 -0
  232. package/src/tools/executors/editor.ts +219 -0
  233. package/src/tools/executors/file-read.test.ts +49 -0
  234. package/src/tools/executors/file-read.ts +110 -0
  235. package/src/tools/executors/index.ts +87 -0
  236. package/src/tools/executors/search.ts +278 -0
  237. package/src/tools/executors/web-fetch.ts +259 -0
  238. package/src/tools/helpers.ts +130 -0
  239. package/src/tools/index.ts +169 -0
  240. package/src/tools/model-tool-routing.test.ts +86 -0
  241. package/src/tools/model-tool-routing.ts +132 -0
  242. package/src/tools/presets.test.ts +62 -0
  243. package/src/tools/presets.ts +168 -0
  244. package/src/tools/schemas.ts +327 -0
  245. package/src/tools/types.ts +329 -0
  246. package/src/types/common.ts +26 -0
  247. package/src/types/config.ts +86 -0
  248. package/src/types/events.ts +74 -0
  249. package/src/types/index.ts +24 -0
  250. package/src/types/provider-settings.ts +43 -0
  251. package/src/types/sessions.ts +16 -0
  252. package/src/types/storage.ts +64 -0
  253. package/src/types/workspace.ts +7 -0
  254. package/src/types.ts +132 -0
  255. package/src/version.ts +3 -0
  256. package/dist/index.node.d.ts +0 -47
  257. package/dist/index.node.d.ts.map +0 -1
  258. package/dist/index.node.js +0 -948
  259. package/dist/telemetry/opentelemetry.d.ts.map +0 -1
  260. package/dist/telemetry/opentelemetry.js +0 -27
@@ -0,0 +1,175 @@
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
+ });
@@ -0,0 +1,23 @@
1
+ export {
2
+ ClineAccountService,
3
+ type ClineAccountServiceOptions,
4
+ } from "./cline-account-service";
5
+ export {
6
+ type ClineAccountOperations,
7
+ executeRpcClineAccountAction,
8
+ isRpcClineAccountActionRequest,
9
+ RpcClineAccountService,
10
+ type RpcProviderActionExecutor,
11
+ } from "./rpc";
12
+ export type {
13
+ ClineAccountBalance,
14
+ ClineAccountOrganization,
15
+ ClineAccountOrganizationBalance,
16
+ ClineAccountOrganizationUsageTransaction,
17
+ ClineAccountPaymentTransaction,
18
+ ClineAccountUsageTransaction,
19
+ ClineAccountUser,
20
+ ClineOrganization,
21
+ FeaturebaseTokenResponse,
22
+ UserRemoteConfigResponse,
23
+ } from "./types";
@@ -0,0 +1,63 @@
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
+ });
@@ -0,0 +1,185 @@
1
+ import type {
2
+ RpcClineAccountActionRequest,
3
+ RpcProviderActionRequest,
4
+ } from "@clinebot/shared";
5
+ import type {
6
+ ClineAccountBalance,
7
+ ClineAccountOrganization,
8
+ ClineAccountOrganizationBalance,
9
+ ClineAccountOrganizationUsageTransaction,
10
+ ClineAccountPaymentTransaction,
11
+ ClineAccountUsageTransaction,
12
+ ClineAccountUser,
13
+ FeaturebaseTokenResponse,
14
+ } from "./types";
15
+
16
+ export interface ClineAccountOperations {
17
+ fetchMe(): Promise<ClineAccountUser>;
18
+ fetchBalance(userId?: string): Promise<ClineAccountBalance>;
19
+ fetchUsageTransactions(
20
+ userId?: string,
21
+ ): Promise<ClineAccountUsageTransaction[]>;
22
+ fetchPaymentTransactions(
23
+ userId?: string,
24
+ ): Promise<ClineAccountPaymentTransaction[]>;
25
+ fetchUserOrganizations(): Promise<ClineAccountOrganization[]>;
26
+ fetchOrganizationBalance(
27
+ organizationId: string,
28
+ ): Promise<ClineAccountOrganizationBalance>;
29
+ fetchOrganizationUsageTransactions(input: {
30
+ organizationId: string;
31
+ memberId?: string;
32
+ }): Promise<ClineAccountOrganizationUsageTransaction[]>;
33
+ switchAccount(organizationId?: string | null): Promise<void>;
34
+ fetchFeaturebaseToken?(): Promise<FeaturebaseTokenResponse | undefined>;
35
+ }
36
+
37
+ export function isRpcClineAccountActionRequest(
38
+ request: RpcProviderActionRequest,
39
+ ): request is RpcClineAccountActionRequest {
40
+ return request.action === "clineAccount";
41
+ }
42
+
43
+ export async function executeRpcClineAccountAction(
44
+ request: RpcClineAccountActionRequest,
45
+ service: ClineAccountOperations,
46
+ ): Promise<unknown> {
47
+ switch (request.operation) {
48
+ case "fetchMe":
49
+ return service.fetchMe();
50
+ case "fetchBalance":
51
+ return service.fetchBalance(request.userId);
52
+ case "fetchUsageTransactions":
53
+ return service.fetchUsageTransactions(request.userId);
54
+ case "fetchPaymentTransactions":
55
+ return service.fetchPaymentTransactions(request.userId);
56
+ case "fetchUserOrganizations":
57
+ return service.fetchUserOrganizations();
58
+ case "fetchOrganizationBalance":
59
+ return service.fetchOrganizationBalance(request.organizationId);
60
+ case "fetchOrganizationUsageTransactions":
61
+ return service.fetchOrganizationUsageTransactions({
62
+ organizationId: request.organizationId,
63
+ memberId: request.memberId,
64
+ });
65
+ case "switchAccount":
66
+ await service.switchAccount(request.organizationId);
67
+ return { updated: true };
68
+ case "fetchFeaturebaseToken":
69
+ return service.fetchFeaturebaseToken?.();
70
+ default: {
71
+ const exhaustive: never = request;
72
+ throw new Error(
73
+ `Unsupported Cline account operation: ${String(exhaustive)}`,
74
+ );
75
+ }
76
+ }
77
+ }
78
+
79
+ export interface RpcProviderActionExecutor {
80
+ runProviderAction(request: RpcProviderActionRequest): Promise<{
81
+ result: unknown;
82
+ }>;
83
+ }
84
+
85
+ export class RpcClineAccountService implements ClineAccountOperations {
86
+ private readonly executor: RpcProviderActionExecutor;
87
+
88
+ constructor(executor: RpcProviderActionExecutor) {
89
+ this.executor = executor;
90
+ }
91
+
92
+ public async fetchMe(): Promise<ClineAccountUser> {
93
+ return this.request<ClineAccountUser>({
94
+ action: "clineAccount",
95
+ operation: "fetchMe",
96
+ });
97
+ }
98
+
99
+ public async fetchBalance(userId?: string): Promise<ClineAccountBalance> {
100
+ return this.request<ClineAccountBalance>({
101
+ action: "clineAccount",
102
+ operation: "fetchBalance",
103
+ ...(userId?.trim() ? { userId: userId.trim() } : {}),
104
+ });
105
+ }
106
+
107
+ public async fetchUsageTransactions(
108
+ userId?: string,
109
+ ): Promise<ClineAccountUsageTransaction[]> {
110
+ return this.request<ClineAccountUsageTransaction[]>({
111
+ action: "clineAccount",
112
+ operation: "fetchUsageTransactions",
113
+ ...(userId?.trim() ? { userId: userId.trim() } : {}),
114
+ });
115
+ }
116
+
117
+ public async fetchPaymentTransactions(
118
+ userId?: string,
119
+ ): Promise<ClineAccountPaymentTransaction[]> {
120
+ return this.request<ClineAccountPaymentTransaction[]>({
121
+ action: "clineAccount",
122
+ operation: "fetchPaymentTransactions",
123
+ ...(userId?.trim() ? { userId: userId.trim() } : {}),
124
+ });
125
+ }
126
+
127
+ public async fetchUserOrganizations(): Promise<ClineAccountOrganization[]> {
128
+ return this.request<ClineAccountOrganization[]>({
129
+ action: "clineAccount",
130
+ operation: "fetchUserOrganizations",
131
+ });
132
+ }
133
+
134
+ public async fetchOrganizationBalance(
135
+ organizationId: string,
136
+ ): Promise<ClineAccountOrganizationBalance> {
137
+ const orgId = organizationId.trim();
138
+ if (!orgId) {
139
+ throw new Error("organizationId is required");
140
+ }
141
+ return this.request<ClineAccountOrganizationBalance>({
142
+ action: "clineAccount",
143
+ operation: "fetchOrganizationBalance",
144
+ organizationId: orgId,
145
+ });
146
+ }
147
+
148
+ public async fetchOrganizationUsageTransactions(input: {
149
+ organizationId: string;
150
+ memberId?: string;
151
+ }): Promise<ClineAccountOrganizationUsageTransaction[]> {
152
+ const orgId = input.organizationId.trim();
153
+ if (!orgId) {
154
+ throw new Error("organizationId is required");
155
+ }
156
+ return this.request<ClineAccountOrganizationUsageTransaction[]>({
157
+ action: "clineAccount",
158
+ operation: "fetchOrganizationUsageTransactions",
159
+ organizationId: orgId,
160
+ ...(input.memberId?.trim() ? { memberId: input.memberId.trim() } : {}),
161
+ });
162
+ }
163
+
164
+ public async switchAccount(organizationId?: string | null): Promise<void> {
165
+ await this.request<{ updated: boolean }>({
166
+ action: "clineAccount",
167
+ operation: "switchAccount",
168
+ organizationId: organizationId?.trim() || null,
169
+ });
170
+ }
171
+
172
+ public async fetchFeaturebaseToken(): Promise<
173
+ FeaturebaseTokenResponse | undefined
174
+ > {
175
+ return this.request<FeaturebaseTokenResponse | undefined>({
176
+ action: "clineAccount",
177
+ operation: "fetchFeaturebaseToken",
178
+ });
179
+ }
180
+
181
+ private async request<T>(request: RpcClineAccountActionRequest): Promise<T> {
182
+ const response = await this.executor.runProviderAction(request);
183
+ return response.result as T;
184
+ }
185
+ }
@@ -0,0 +1,102 @@
1
+ export interface ClineAccountOrganization {
2
+ active: boolean;
3
+ memberId: string;
4
+ name: string;
5
+ organizationId: string;
6
+ roles: Array<"admin" | "member" | "owner">;
7
+ }
8
+
9
+ export interface ClineAccountUser {
10
+ id: string;
11
+ email: string;
12
+ displayName: string;
13
+ photoUrl: string;
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ organizations: ClineAccountOrganization[];
17
+ }
18
+
19
+ export interface UserRemoteConfigResponse {
20
+ organizationId: string;
21
+ value: string;
22
+ enabled: boolean;
23
+ }
24
+
25
+ export interface ClineAccountBalance {
26
+ balance: number;
27
+ userId: string;
28
+ }
29
+
30
+ export interface ClineAccountUsageTransaction {
31
+ aiInferenceProviderName: string;
32
+ aiModelName: string;
33
+ aiModelTypeName: string;
34
+ completionTokens: number;
35
+ costUsd: number;
36
+ createdAt: string;
37
+ creditsUsed: number;
38
+ generationId: string;
39
+ id: string;
40
+ metadata: {
41
+ additionalProp1: string;
42
+ additionalProp2: string;
43
+ additionalProp3: string;
44
+ };
45
+ operation?: string;
46
+ organizationId: string;
47
+ promptTokens: number;
48
+ totalTokens: number;
49
+ userId: string;
50
+ }
51
+
52
+ export interface ClineAccountPaymentTransaction {
53
+ paidAt: string;
54
+ creatorId: string;
55
+ amountCents: number;
56
+ credits: number;
57
+ }
58
+
59
+ export interface ClineOrganization {
60
+ createdAt: string;
61
+ defaultRemoteConfig?: string;
62
+ deletedAt?: string;
63
+ externalOrganizationId?: string;
64
+ id: string;
65
+ memberCount?: number;
66
+ name: string;
67
+ remoteConfigEnabled: boolean;
68
+ updatedAt: string;
69
+ }
70
+
71
+ export interface ClineAccountOrganizationBalance {
72
+ balance: number;
73
+ organizationId: string;
74
+ }
75
+
76
+ export interface FeaturebaseTokenResponse {
77
+ featurebaseJwt: string;
78
+ }
79
+
80
+ export interface ClineAccountOrganizationUsageTransaction {
81
+ aiInferenceProviderName: string;
82
+ aiModelName: string;
83
+ aiModelTypeName: string;
84
+ completionTokens: number;
85
+ costUsd: number;
86
+ createdAt: string;
87
+ creditsUsed: number;
88
+ generationId: string;
89
+ id: string;
90
+ memberDisplayName: string;
91
+ memberEmail: string;
92
+ metadata: {
93
+ additionalProp1: string;
94
+ additionalProp2: string;
95
+ additionalProp3: string;
96
+ };
97
+ operation?: string;
98
+ organizationId: string;
99
+ promptTokens: number;
100
+ totalTokens: number;
101
+ userId: string;
102
+ }