@clinebot/core 0.0.20 → 0.0.21

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 (356) hide show
  1. package/dist/account/cline-account-service.d.ts +3 -2
  2. package/dist/account/cline-account-service.d.ts.map +1 -0
  3. package/dist/account/index.d.ts +1 -0
  4. package/dist/account/index.d.ts.map +1 -0
  5. package/dist/account/rpc.d.ts +1 -0
  6. package/dist/account/rpc.d.ts.map +1 -0
  7. package/dist/account/types.d.ts +1 -0
  8. package/dist/account/types.d.ts.map +1 -0
  9. package/dist/agents/agent-config-loader.d.ts +1 -0
  10. package/dist/agents/agent-config-loader.d.ts.map +1 -0
  11. package/dist/agents/agent-config-parser.d.ts +1 -0
  12. package/dist/agents/agent-config-parser.d.ts.map +1 -0
  13. package/dist/agents/hooks-config-loader.d.ts +1 -0
  14. package/dist/agents/hooks-config-loader.d.ts.map +1 -0
  15. package/dist/agents/index.d.ts +1 -0
  16. package/dist/agents/index.d.ts.map +1 -0
  17. package/dist/agents/plugin-config-loader.d.ts +1 -0
  18. package/dist/agents/plugin-config-loader.d.ts.map +1 -0
  19. package/dist/agents/plugin-loader.d.ts +1 -0
  20. package/dist/agents/plugin-loader.d.ts.map +1 -0
  21. package/dist/agents/plugin-sandbox.d.ts +1 -0
  22. package/dist/agents/plugin-sandbox.d.ts.map +1 -0
  23. package/dist/agents/unified-config-file-watcher.d.ts +1 -0
  24. package/dist/agents/unified-config-file-watcher.d.ts.map +1 -0
  25. package/dist/agents/user-instruction-config-loader.d.ts +1 -0
  26. package/dist/agents/user-instruction-config-loader.d.ts.map +1 -0
  27. package/dist/auth/client.d.ts +1 -0
  28. package/dist/auth/client.d.ts.map +1 -0
  29. package/dist/auth/cline.d.ts +1 -0
  30. package/dist/auth/cline.d.ts.map +1 -0
  31. package/dist/auth/codex.d.ts +1 -0
  32. package/dist/auth/codex.d.ts.map +1 -0
  33. package/dist/auth/oca.d.ts +1 -0
  34. package/dist/auth/oca.d.ts.map +1 -0
  35. package/dist/auth/server.d.ts +1 -0
  36. package/dist/auth/server.d.ts.map +1 -0
  37. package/dist/auth/types.d.ts +1 -0
  38. package/dist/auth/types.d.ts.map +1 -0
  39. package/dist/auth/utils.d.ts +1 -0
  40. package/dist/auth/utils.d.ts.map +1 -0
  41. package/dist/chat/chat-schema.d.ts +13 -12
  42. package/dist/chat/chat-schema.d.ts.map +1 -0
  43. package/dist/index.d.ts +3 -1
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.node.d.ts +2 -0
  46. package/dist/index.node.d.ts.map +1 -0
  47. package/dist/index.node.js +303 -302
  48. package/dist/input/file-indexer.d.ts +1 -0
  49. package/dist/input/file-indexer.d.ts.map +1 -0
  50. package/dist/input/index.d.ts +1 -0
  51. package/dist/input/index.d.ts.map +1 -0
  52. package/dist/input/mention-enricher.d.ts +1 -0
  53. package/dist/input/mention-enricher.d.ts.map +1 -0
  54. package/dist/mcp/config-loader.d.ts +1 -0
  55. package/dist/mcp/config-loader.d.ts.map +1 -0
  56. package/dist/mcp/index.d.ts +1 -0
  57. package/dist/mcp/index.d.ts.map +1 -0
  58. package/dist/mcp/manager.d.ts +1 -0
  59. package/dist/mcp/manager.d.ts.map +1 -0
  60. package/dist/mcp/types.d.ts +1 -0
  61. package/dist/mcp/types.d.ts.map +1 -0
  62. package/dist/providers/local-provider-registry.d.ts +36 -0
  63. package/dist/providers/local-provider-registry.d.ts.map +1 -0
  64. package/dist/providers/local-provider-service.d.ts +2 -1
  65. package/dist/providers/local-provider-service.d.ts.map +1 -0
  66. package/dist/runtime/commands.d.ts +1 -0
  67. package/dist/runtime/commands.d.ts.map +1 -0
  68. package/dist/runtime/hook-file-hooks.d.ts +1 -0
  69. package/dist/runtime/hook-file-hooks.d.ts.map +1 -0
  70. package/dist/runtime/rules.d.ts +1 -0
  71. package/dist/runtime/rules.d.ts.map +1 -0
  72. package/dist/runtime/runtime-builder.d.ts +1 -0
  73. package/dist/runtime/runtime-builder.d.ts.map +1 -0
  74. package/dist/runtime/sandbox/subprocess-sandbox.d.ts +1 -0
  75. package/dist/runtime/sandbox/subprocess-sandbox.d.ts.map +1 -0
  76. package/dist/runtime/session-runtime.d.ts +2 -0
  77. package/dist/runtime/session-runtime.d.ts.map +1 -0
  78. package/dist/runtime/skills.d.ts +1 -0
  79. package/dist/runtime/skills.d.ts.map +1 -0
  80. package/dist/runtime/tool-approval.d.ts +1 -0
  81. package/dist/runtime/tool-approval.d.ts.map +1 -0
  82. package/dist/runtime/workflows.d.ts +1 -0
  83. package/dist/runtime/workflows.d.ts.map +1 -0
  84. package/dist/session/default-session-manager.d.ts +4 -0
  85. package/dist/session/default-session-manager.d.ts.map +1 -0
  86. package/dist/session/file-session-service.d.ts +1 -0
  87. package/dist/session/file-session-service.d.ts.map +1 -0
  88. package/dist/session/rpc-session-service.d.ts +1 -0
  89. package/dist/session/rpc-session-service.d.ts.map +1 -0
  90. package/dist/session/rpc-spawn-lease.d.ts +1 -0
  91. package/dist/session/rpc-spawn-lease.d.ts.map +1 -0
  92. package/dist/session/runtime-oauth-token-manager.d.ts +1 -0
  93. package/dist/session/runtime-oauth-token-manager.d.ts.map +1 -0
  94. package/dist/session/session-agent-events.d.ts +20 -1
  95. package/dist/session/session-agent-events.d.ts.map +1 -0
  96. package/dist/session/session-artifacts.d.ts +1 -0
  97. package/dist/session/session-artifacts.d.ts.map +1 -0
  98. package/dist/session/session-config-builder.d.ts +1 -0
  99. package/dist/session/session-config-builder.d.ts.map +1 -0
  100. package/dist/session/session-graph.d.ts +1 -0
  101. package/dist/session/session-graph.d.ts.map +1 -0
  102. package/dist/session/session-host.d.ts +1 -0
  103. package/dist/session/session-host.d.ts.map +1 -0
  104. package/dist/session/session-manager.d.ts +1 -0
  105. package/dist/session/session-manager.d.ts.map +1 -0
  106. package/dist/session/session-manifest.d.ts +2 -1
  107. package/dist/session/session-manifest.d.ts.map +1 -0
  108. package/dist/session/session-service.d.ts +1 -0
  109. package/dist/session/session-service.d.ts.map +1 -0
  110. package/dist/session/session-team-coordination.d.ts +1 -0
  111. package/dist/session/session-team-coordination.d.ts.map +1 -0
  112. package/dist/session/session-telemetry.d.ts +3 -1
  113. package/dist/session/session-telemetry.d.ts.map +1 -0
  114. package/dist/session/sqlite-rpc-session-backend.d.ts +1 -0
  115. package/dist/session/sqlite-rpc-session-backend.d.ts.map +1 -0
  116. package/dist/session/unified-session-persistence-service.d.ts +1 -0
  117. package/dist/session/unified-session-persistence-service.d.ts.map +1 -0
  118. package/dist/session/utils/helpers.d.ts +1 -0
  119. package/dist/session/utils/helpers.d.ts.map +1 -0
  120. package/dist/session/utils/types.d.ts +1 -0
  121. package/dist/session/utils/types.d.ts.map +1 -0
  122. package/dist/session/utils/usage.d.ts +1 -0
  123. package/dist/session/utils/usage.d.ts.map +1 -0
  124. package/dist/session/workspace-manager.d.ts +1 -0
  125. package/dist/session/workspace-manager.d.ts.map +1 -0
  126. package/dist/session/workspace-manifest.d.ts +1 -0
  127. package/dist/session/workspace-manifest.d.ts.map +1 -0
  128. package/dist/storage/file-team-store.d.ts +1 -0
  129. package/dist/storage/file-team-store.d.ts.map +1 -0
  130. package/dist/storage/provider-settings-legacy-migration.d.ts +1 -0
  131. package/dist/storage/provider-settings-legacy-migration.d.ts.map +1 -0
  132. package/dist/storage/provider-settings-manager.d.ts +1 -0
  133. package/dist/storage/provider-settings-manager.d.ts.map +1 -0
  134. package/dist/storage/sqlite-session-store.d.ts +1 -0
  135. package/dist/storage/sqlite-session-store.d.ts.map +1 -0
  136. package/dist/storage/sqlite-team-store.d.ts +1 -0
  137. package/dist/storage/sqlite-team-store.d.ts.map +1 -0
  138. package/dist/storage/team-store.d.ts +1 -0
  139. package/dist/storage/team-store.d.ts.map +1 -0
  140. package/dist/team/index.d.ts +1 -0
  141. package/dist/team/index.d.ts.map +1 -0
  142. package/dist/team/projections.d.ts +1 -0
  143. package/dist/team/projections.d.ts.map +1 -0
  144. package/dist/telemetry/ITelemetryAdapter.d.ts +1 -0
  145. package/dist/telemetry/ITelemetryAdapter.d.ts.map +1 -0
  146. package/dist/telemetry/LoggerTelemetryAdapter.d.ts +1 -0
  147. package/dist/telemetry/LoggerTelemetryAdapter.d.ts.map +1 -0
  148. package/dist/telemetry/OpenTelemetryAdapter.d.ts +1 -0
  149. package/dist/telemetry/OpenTelemetryAdapter.d.ts.map +1 -0
  150. package/dist/telemetry/OpenTelemetryProvider.d.ts +1 -0
  151. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -0
  152. package/dist/telemetry/TelemetryService.d.ts +1 -0
  153. package/dist/telemetry/TelemetryService.d.ts.map +1 -0
  154. package/dist/telemetry/core-events.d.ts +55 -22
  155. package/dist/telemetry/core-events.d.ts.map +1 -0
  156. package/dist/telemetry/opentelemetry.d.ts +1 -0
  157. package/dist/telemetry/opentelemetry.d.ts.map +1 -0
  158. package/dist/tools/constants.d.ts +1 -0
  159. package/dist/tools/constants.d.ts.map +1 -0
  160. package/dist/tools/definitions.d.ts +8 -1
  161. package/dist/tools/definitions.d.ts.map +1 -0
  162. package/dist/tools/executors/apply-patch-parser.d.ts +1 -0
  163. package/dist/tools/executors/apply-patch-parser.d.ts.map +1 -0
  164. package/dist/tools/executors/apply-patch.d.ts +1 -0
  165. package/dist/tools/executors/apply-patch.d.ts.map +1 -0
  166. package/dist/tools/executors/bash.d.ts +2 -1
  167. package/dist/tools/executors/bash.d.ts.map +1 -0
  168. package/dist/tools/executors/editor.d.ts +1 -0
  169. package/dist/tools/executors/editor.d.ts.map +1 -0
  170. package/dist/tools/executors/file-read.d.ts +1 -0
  171. package/dist/tools/executors/file-read.d.ts.map +1 -0
  172. package/dist/tools/executors/index.d.ts +14 -7
  173. package/dist/tools/executors/index.d.ts.map +1 -0
  174. package/dist/tools/executors/search.d.ts +1 -0
  175. package/dist/tools/executors/search.d.ts.map +1 -0
  176. package/dist/tools/executors/web-fetch.d.ts +1 -0
  177. package/dist/tools/executors/web-fetch.d.ts.map +1 -0
  178. package/dist/tools/helpers.d.ts +15 -0
  179. package/dist/tools/helpers.d.ts.map +1 -0
  180. package/dist/tools/index.d.ts +2 -1
  181. package/dist/tools/index.d.ts.map +1 -0
  182. package/dist/tools/model-tool-routing.d.ts +1 -0
  183. package/dist/tools/model-tool-routing.d.ts.map +1 -0
  184. package/dist/tools/presets.d.ts +1 -0
  185. package/dist/tools/presets.d.ts.map +1 -0
  186. package/dist/tools/schemas.d.ts +41 -0
  187. package/dist/tools/schemas.d.ts.map +1 -0
  188. package/dist/tools/types.d.ts +3 -2
  189. package/dist/tools/types.d.ts.map +1 -0
  190. package/dist/types/common.d.ts +1 -0
  191. package/dist/types/common.d.ts.map +1 -0
  192. package/dist/types/config.d.ts +1 -0
  193. package/dist/types/config.d.ts.map +1 -0
  194. package/dist/types/events.d.ts +1 -0
  195. package/dist/types/events.d.ts.map +1 -0
  196. package/dist/types/provider-settings.d.ts +1 -0
  197. package/dist/types/provider-settings.d.ts.map +1 -0
  198. package/dist/types/sessions.d.ts +1 -0
  199. package/dist/types/sessions.d.ts.map +1 -0
  200. package/dist/types/storage.d.ts +1 -0
  201. package/dist/types/storage.d.ts.map +1 -0
  202. package/dist/types/workspace.d.ts +1 -0
  203. package/dist/types/workspace.d.ts.map +1 -0
  204. package/dist/types.d.ts +1 -0
  205. package/dist/types.d.ts.map +1 -0
  206. package/package.json +6 -4
  207. package/src/account/cline-account-service.test.ts +0 -101
  208. package/src/account/cline-account-service.ts +0 -287
  209. package/src/account/index.ts +0 -22
  210. package/src/account/rpc.test.ts +0 -62
  211. package/src/account/rpc.ts +0 -172
  212. package/src/account/types.ts +0 -98
  213. package/src/agents/agent-config-loader.test.ts +0 -236
  214. package/src/agents/agent-config-loader.ts +0 -108
  215. package/src/agents/agent-config-parser.ts +0 -198
  216. package/src/agents/hooks-config-loader.test.ts +0 -20
  217. package/src/agents/hooks-config-loader.ts +0 -118
  218. package/src/agents/index.ts +0 -85
  219. package/src/agents/plugin-config-loader.test.ts +0 -140
  220. package/src/agents/plugin-config-loader.ts +0 -97
  221. package/src/agents/plugin-loader.test.ts +0 -228
  222. package/src/agents/plugin-loader.ts +0 -172
  223. package/src/agents/plugin-sandbox-bootstrap.ts +0 -445
  224. package/src/agents/plugin-sandbox.test.ts +0 -317
  225. package/src/agents/plugin-sandbox.ts +0 -341
  226. package/src/agents/unified-config-file-watcher.test.ts +0 -196
  227. package/src/agents/unified-config-file-watcher.ts +0 -483
  228. package/src/agents/user-instruction-config-loader.test.ts +0 -158
  229. package/src/agents/user-instruction-config-loader.ts +0 -438
  230. package/src/auth/client.test.ts +0 -40
  231. package/src/auth/client.ts +0 -25
  232. package/src/auth/cline.test.ts +0 -130
  233. package/src/auth/cline.ts +0 -420
  234. package/src/auth/codex.test.ts +0 -170
  235. package/src/auth/codex.ts +0 -491
  236. package/src/auth/oca.test.ts +0 -215
  237. package/src/auth/oca.ts +0 -573
  238. package/src/auth/server.ts +0 -216
  239. package/src/auth/types.ts +0 -81
  240. package/src/auth/utils.test.ts +0 -128
  241. package/src/auth/utils.ts +0 -247
  242. package/src/chat/chat-schema.ts +0 -82
  243. package/src/index.node.ts +0 -285
  244. package/src/index.ts +0 -211
  245. package/src/input/file-indexer.d.ts +0 -11
  246. package/src/input/file-indexer.test.ts +0 -127
  247. package/src/input/file-indexer.ts +0 -327
  248. package/src/input/index.ts +0 -7
  249. package/src/input/mention-enricher.test.ts +0 -85
  250. package/src/input/mention-enricher.ts +0 -122
  251. package/src/mcp/config-loader.test.ts +0 -238
  252. package/src/mcp/config-loader.ts +0 -219
  253. package/src/mcp/index.ts +0 -26
  254. package/src/mcp/manager.test.ts +0 -106
  255. package/src/mcp/manager.ts +0 -262
  256. package/src/mcp/types.ts +0 -88
  257. package/src/providers/local-provider-service.ts +0 -608
  258. package/src/runtime/commands.test.ts +0 -98
  259. package/src/runtime/commands.ts +0 -83
  260. package/src/runtime/hook-file-hooks.test.ts +0 -237
  261. package/src/runtime/hook-file-hooks.ts +0 -859
  262. package/src/runtime/index.ts +0 -37
  263. package/src/runtime/rules.ts +0 -34
  264. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -202
  265. package/src/runtime/runtime-builder.test.ts +0 -371
  266. package/src/runtime/runtime-builder.ts +0 -589
  267. package/src/runtime/runtime-parity.test.ts +0 -143
  268. package/src/runtime/sandbox/subprocess-sandbox.ts +0 -231
  269. package/src/runtime/session-runtime.ts +0 -46
  270. package/src/runtime/skills.ts +0 -44
  271. package/src/runtime/tool-approval.ts +0 -104
  272. package/src/runtime/workflows.test.ts +0 -119
  273. package/src/runtime/workflows.ts +0 -45
  274. package/src/session/default-session-manager.e2e.test.ts +0 -384
  275. package/src/session/default-session-manager.test.ts +0 -1741
  276. package/src/session/default-session-manager.ts +0 -1233
  277. package/src/session/file-session-service.ts +0 -280
  278. package/src/session/index.ts +0 -42
  279. package/src/session/rpc-session-service.ts +0 -107
  280. package/src/session/rpc-spawn-lease.test.ts +0 -49
  281. package/src/session/rpc-spawn-lease.ts +0 -122
  282. package/src/session/runtime-oauth-token-manager.test.ts +0 -137
  283. package/src/session/runtime-oauth-token-manager.ts +0 -272
  284. package/src/session/session-agent-events.ts +0 -159
  285. package/src/session/session-artifacts.ts +0 -106
  286. package/src/session/session-config-builder.ts +0 -113
  287. package/src/session/session-graph.ts +0 -92
  288. package/src/session/session-host.test.ts +0 -29
  289. package/src/session/session-host.ts +0 -242
  290. package/src/session/session-manager.ts +0 -69
  291. package/src/session/session-manifest.ts +0 -29
  292. package/src/session/session-service.team-persistence.test.ts +0 -48
  293. package/src/session/session-service.ts +0 -673
  294. package/src/session/session-team-coordination.ts +0 -229
  295. package/src/session/session-telemetry.ts +0 -95
  296. package/src/session/sqlite-rpc-session-backend.ts +0 -303
  297. package/src/session/unified-session-persistence-service.test.ts +0 -85
  298. package/src/session/unified-session-persistence-service.ts +0 -996
  299. package/src/session/utils/helpers.ts +0 -139
  300. package/src/session/utils/types.ts +0 -57
  301. package/src/session/utils/usage.ts +0 -32
  302. package/src/session/workspace-manager.ts +0 -98
  303. package/src/session/workspace-manifest.ts +0 -100
  304. package/src/storage/artifact-store.ts +0 -1
  305. package/src/storage/file-team-store.ts +0 -257
  306. package/src/storage/index.ts +0 -11
  307. package/src/storage/provider-settings-legacy-migration.test.ts +0 -307
  308. package/src/storage/provider-settings-legacy-migration.ts +0 -689
  309. package/src/storage/provider-settings-manager.test.ts +0 -145
  310. package/src/storage/provider-settings-manager.ts +0 -150
  311. package/src/storage/session-store.ts +0 -1
  312. package/src/storage/sqlite-session-store.ts +0 -275
  313. package/src/storage/sqlite-team-store.ts +0 -454
  314. package/src/storage/team-store.ts +0 -40
  315. package/src/team/index.ts +0 -4
  316. package/src/team/projections.ts +0 -285
  317. package/src/telemetry/ITelemetryAdapter.ts +0 -94
  318. package/src/telemetry/LoggerTelemetryAdapter.test.ts +0 -42
  319. package/src/telemetry/LoggerTelemetryAdapter.ts +0 -114
  320. package/src/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  321. package/src/telemetry/OpenTelemetryAdapter.ts +0 -348
  322. package/src/telemetry/OpenTelemetryProvider.test.ts +0 -113
  323. package/src/telemetry/OpenTelemetryProvider.ts +0 -322
  324. package/src/telemetry/TelemetryService.test.ts +0 -134
  325. package/src/telemetry/TelemetryService.ts +0 -141
  326. package/src/telemetry/core-events.ts +0 -344
  327. package/src/telemetry/opentelemetry.ts +0 -20
  328. package/src/tools/constants.ts +0 -35
  329. package/src/tools/definitions.test.ts +0 -658
  330. package/src/tools/definitions.ts +0 -726
  331. package/src/tools/executors/apply-patch-parser.ts +0 -520
  332. package/src/tools/executors/apply-patch.ts +0 -359
  333. package/src/tools/executors/bash.ts +0 -205
  334. package/src/tools/executors/editor.test.ts +0 -35
  335. package/src/tools/executors/editor.ts +0 -219
  336. package/src/tools/executors/file-read.test.ts +0 -49
  337. package/src/tools/executors/file-read.ts +0 -110
  338. package/src/tools/executors/index.ts +0 -75
  339. package/src/tools/executors/search.ts +0 -278
  340. package/src/tools/executors/web-fetch.ts +0 -259
  341. package/src/tools/index.ts +0 -168
  342. package/src/tools/model-tool-routing.test.ts +0 -86
  343. package/src/tools/model-tool-routing.ts +0 -132
  344. package/src/tools/presets.test.ts +0 -62
  345. package/src/tools/presets.ts +0 -168
  346. package/src/tools/schemas.ts +0 -284
  347. package/src/tools/types.ts +0 -328
  348. package/src/types/common.ts +0 -14
  349. package/src/types/config.ts +0 -84
  350. package/src/types/events.ts +0 -74
  351. package/src/types/index.ts +0 -24
  352. package/src/types/provider-settings.ts +0 -43
  353. package/src/types/sessions.ts +0 -16
  354. package/src/types/storage.ts +0 -64
  355. package/src/types/workspace.ts +0 -7
  356. package/src/types.ts +0 -128
@@ -1,608 +0,0 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
2
- import { dirname, join } from "node:path";
3
- import { LlmsModels, type LlmsProviders } from "@clinebot/llms";
4
- import type {
5
- RpcAddProviderActionRequest,
6
- RpcOAuthProviderId,
7
- RpcProviderCapability,
8
- RpcProviderListItem,
9
- RpcProviderModel,
10
- RpcSaveProviderSettingsActionRequest,
11
- } from "@clinebot/shared";
12
- import { createOAuthClientCallbacks } from "../auth/client";
13
- import { loginClineOAuth } from "../auth/cline";
14
- import { loginOpenAICodex } from "../auth/codex";
15
- import { loginOcaOAuth } from "../auth/oca";
16
- import type { ProviderSettingsManager } from "../storage/provider-settings-manager";
17
-
18
- type StoredModelsFile = {
19
- version: 1;
20
- providers: Record<
21
- string,
22
- {
23
- provider: {
24
- name: string;
25
- baseUrl: string;
26
- defaultModelId?: string;
27
- capabilities?: RpcProviderCapability[];
28
- modelsSourceUrl?: string;
29
- };
30
- models: Record<
31
- string,
32
- {
33
- id: string;
34
- name: string;
35
- supportsVision?: boolean;
36
- supportsAttachments?: boolean;
37
- supportsReasoning?: boolean;
38
- }
39
- >;
40
- }
41
- >;
42
- };
43
-
44
- function resolveVisibleApiKey(settings: {
45
- apiKey?: string;
46
- auth?: {
47
- apiKey?: string;
48
- };
49
- }): string | undefined {
50
- return settings.apiKey ?? settings.auth?.apiKey;
51
- }
52
-
53
- function hasOAuthAccessToken(settings: {
54
- auth?: {
55
- accessToken?: string;
56
- };
57
- }): boolean {
58
- return (settings.auth?.accessToken?.trim() ?? "").length > 0;
59
- }
60
-
61
- function titleCaseFromId(id: string): string {
62
- return id
63
- .split(/[-_]/)
64
- .filter(Boolean)
65
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
66
- .join(" ");
67
- }
68
-
69
- function createLetter(name: string): string {
70
- const parts = name
71
- .split(/\s+/)
72
- .map((part) => part.trim())
73
- .filter(Boolean);
74
- if (parts.length === 0) {
75
- return "?";
76
- }
77
- if (parts.length === 1) {
78
- return parts[0].slice(0, 2).toUpperCase();
79
- }
80
- return `${parts[0][0]}${parts[1][0]}`.toUpperCase();
81
- }
82
-
83
- function stableColor(id: string): string {
84
- const palette = [
85
- "#c4956a",
86
- "#6b8aad",
87
- "#e8963a",
88
- "#5b9bd5",
89
- "#6bbd7b",
90
- "#9b7dd4",
91
- "#d07f68",
92
- "#57a6a1",
93
- ];
94
- let hash = 0;
95
- for (const ch of id) {
96
- hash = (hash * 31 + ch.charCodeAt(0)) >>> 0;
97
- }
98
- return palette[hash % palette.length];
99
- }
100
-
101
- function resolveModelsRegistryPath(manager: ProviderSettingsManager): string {
102
- return join(dirname(manager.getFilePath()), "models.json");
103
- }
104
-
105
- function emptyModelsFile(): StoredModelsFile {
106
- return { version: 1, providers: {} };
107
- }
108
-
109
- async function readModelsFile(filePath: string): Promise<StoredModelsFile> {
110
- try {
111
- const raw = await readFile(filePath, "utf8");
112
- const parsed = JSON.parse(raw) as Partial<StoredModelsFile>;
113
- if (
114
- parsed &&
115
- parsed.version === 1 &&
116
- parsed.providers &&
117
- typeof parsed.providers === "object"
118
- ) {
119
- return { version: 1, providers: parsed.providers };
120
- }
121
- } catch {
122
- // Invalid or missing files fall back to an empty registry.
123
- }
124
- return emptyModelsFile();
125
- }
126
-
127
- async function writeModelsFile(
128
- filePath: string,
129
- state: StoredModelsFile,
130
- ): Promise<void> {
131
- await mkdir(dirname(filePath), { recursive: true });
132
- await writeFile(filePath, `${JSON.stringify(state, null, 2)}\n`, "utf8");
133
- }
134
-
135
- function toRpcProviderModel(
136
- modelId: string,
137
- info: {
138
- name?: string;
139
- capabilities?: string[];
140
- thinkingConfig?: unknown;
141
- },
142
- ): RpcProviderModel {
143
- return {
144
- id: modelId,
145
- name: info.name ?? modelId,
146
- supportsAttachments: info.capabilities?.includes("files"),
147
- supportsVision: info.capabilities?.includes("images"),
148
- supportsReasoning:
149
- info.capabilities?.includes("reasoning") || info.thinkingConfig != null,
150
- };
151
- }
152
-
153
- function toProviderCapabilities(
154
- capabilities: RpcProviderCapability[] | undefined,
155
- ): Array<"reasoning" | "prompt-cache" | "tools"> | undefined {
156
- if (!capabilities || capabilities.length === 0) {
157
- return undefined;
158
- }
159
- const next = new Set<"reasoning" | "prompt-cache" | "tools">();
160
- if (capabilities.includes("reasoning")) {
161
- next.add("reasoning");
162
- }
163
- if (capabilities.includes("prompt-cache")) {
164
- next.add("prompt-cache");
165
- }
166
- if (capabilities.includes("tools")) {
167
- next.add("tools");
168
- }
169
- return next.size > 0 ? [...next] : undefined;
170
- }
171
-
172
- function toModelCapabilities(
173
- capabilities: RpcProviderCapability[] | undefined,
174
- ): Array<
175
- "streaming" | "tools" | "reasoning" | "prompt-cache" | "images" | "files"
176
- > {
177
- const next = new Set<
178
- "streaming" | "tools" | "reasoning" | "prompt-cache" | "images" | "files"
179
- >();
180
- if (!capabilities || capabilities.length === 0) {
181
- return [...next];
182
- }
183
- if (capabilities.includes("streaming")) next.add("streaming");
184
- if (capabilities.includes("tools")) next.add("tools");
185
- if (capabilities.includes("reasoning")) next.add("reasoning");
186
- if (capabilities.includes("prompt-cache")) next.add("prompt-cache");
187
- if (capabilities.includes("vision")) {
188
- next.add("images");
189
- next.add("files");
190
- }
191
- return [...next];
192
- }
193
-
194
- function registerCustomProvider(
195
- providerId: string,
196
- entry: StoredModelsFile["providers"][string],
197
- ): void {
198
- const modelCapabilities = toModelCapabilities(entry.provider.capabilities);
199
- const modelEntries = Object.values(entry.models)
200
- .map((model) => model.id.trim())
201
- .filter((modelId) => modelId.length > 0);
202
- const defaultModelId =
203
- entry.provider.defaultModelId?.trim() || modelEntries[0] || "default";
204
- const normalizedModels = Object.fromEntries(
205
- modelEntries.map((modelId) => [
206
- modelId,
207
- {
208
- id: modelId,
209
- name: entry.models[modelId]?.name ?? modelId,
210
- capabilities:
211
- modelCapabilities.length > 0 ? modelCapabilities : undefined,
212
- status: "active" as const,
213
- },
214
- ]),
215
- );
216
-
217
- LlmsModels.registerProvider({
218
- provider: {
219
- id: providerId,
220
- name: entry.provider.name.trim() || titleCaseFromId(providerId),
221
- protocol: "openai-chat",
222
- baseUrl: entry.provider.baseUrl,
223
- defaultModelId,
224
- capabilities: toProviderCapabilities(entry.provider.capabilities),
225
- },
226
- models: normalizedModels,
227
- });
228
- }
229
-
230
- let customProvidersLoaded = false;
231
-
232
- export async function ensureCustomProvidersLoaded(
233
- manager: ProviderSettingsManager,
234
- ): Promise<void> {
235
- if (customProvidersLoaded) {
236
- return;
237
- }
238
- const modelsPath = resolveModelsRegistryPath(manager);
239
- const state = await readModelsFile(modelsPath);
240
- for (const [providerId, entry] of Object.entries(state.providers)) {
241
- registerCustomProvider(providerId, entry);
242
- }
243
- customProvidersLoaded = true;
244
- }
245
-
246
- function parseModelIdList(input: unknown): string[] {
247
- if (Array.isArray(input)) {
248
- return input
249
- .map((item) => {
250
- if (typeof item === "string") return item.trim();
251
- if (item && typeof item === "object" && "id" in item) {
252
- const id = (item as { id?: unknown }).id;
253
- return typeof id === "string" ? id.trim() : "";
254
- }
255
- return "";
256
- })
257
- .filter((id) => id.length > 0);
258
- }
259
- return [];
260
- }
261
-
262
- function extractModelIdsFromPayload(
263
- payload: unknown,
264
- providerId: string,
265
- ): string[] {
266
- const rootArray = parseModelIdList(payload);
267
- if (rootArray.length > 0) return rootArray;
268
- if (!payload || typeof payload !== "object") return [];
269
- const data = payload as {
270
- data?: unknown;
271
- models?: unknown;
272
- providers?: Record<string, unknown>;
273
- };
274
- const direct = parseModelIdList(data.data ?? data.models);
275
- if (direct.length > 0) return direct;
276
- if (
277
- data.models &&
278
- typeof data.models === "object" &&
279
- !Array.isArray(data.models)
280
- ) {
281
- const modelKeys = Object.keys(data.models).filter(
282
- (key) => key.trim().length > 0,
283
- );
284
- if (modelKeys.length > 0) return modelKeys;
285
- }
286
- const providerScoped = data.providers?.[providerId];
287
- if (providerScoped && typeof providerScoped === "object") {
288
- const nested = providerScoped as { models?: unknown };
289
- const nestedList = parseModelIdList(nested.models ?? providerScoped);
290
- if (nestedList.length > 0) return nestedList;
291
- }
292
- return [];
293
- }
294
-
295
- async function fetchModelIdsFromSource(
296
- url: string,
297
- providerId: string,
298
- ): Promise<string[]> {
299
- const response = await fetch(url, { method: "GET" });
300
- if (!response.ok) {
301
- throw new Error(
302
- `failed to fetch models from ${url}: HTTP ${response.status}`,
303
- );
304
- }
305
- const payload = (await response.json()) as unknown;
306
- return extractModelIdsFromPayload(payload, providerId);
307
- }
308
-
309
- export async function addLocalProvider(
310
- manager: ProviderSettingsManager,
311
- request: RpcAddProviderActionRequest,
312
- ): Promise<{
313
- providerId: string;
314
- settingsPath: string;
315
- modelsPath: string;
316
- modelsCount: number;
317
- }> {
318
- const providerId = request.providerId.trim().toLowerCase();
319
- if (!providerId) throw new Error("providerId is required");
320
- if (LlmsModels.hasProvider(providerId)) {
321
- throw new Error(`provider "${providerId}" already exists`);
322
- }
323
- const providerName = request.name.trim();
324
- if (!providerName) throw new Error("name is required");
325
- const baseUrl = request.baseUrl.trim();
326
- if (!baseUrl) throw new Error("baseUrl is required");
327
-
328
- const typedModels = (request.models ?? [])
329
- .map((model) => model.trim())
330
- .filter((model) => model.length > 0);
331
- const sourceUrl = request.modelsSourceUrl?.trim();
332
- const fetchedModels = sourceUrl
333
- ? await fetchModelIdsFromSource(sourceUrl, providerId)
334
- : [];
335
- const modelIds = [...new Set([...typedModels, ...fetchedModels])];
336
- if (modelIds.length === 0) {
337
- throw new Error(
338
- "at least one model is required (manual or via modelsSourceUrl)",
339
- );
340
- }
341
-
342
- const defaultModelId =
343
- request.defaultModelId?.trim() &&
344
- modelIds.includes(request.defaultModelId.trim())
345
- ? request.defaultModelId.trim()
346
- : modelIds[0];
347
- const capabilities = request.capabilities?.length
348
- ? [...new Set(request.capabilities)]
349
- : undefined;
350
- const headerEntries = Object.entries(request.headers ?? {}).filter(
351
- ([key]) => key.trim().length > 0,
352
- );
353
-
354
- manager.saveProviderSettings(
355
- {
356
- provider: providerId,
357
- apiKey: request.apiKey?.trim() ? request.apiKey : undefined,
358
- baseUrl,
359
- headers:
360
- headerEntries.length > 0
361
- ? Object.fromEntries(headerEntries)
362
- : undefined,
363
- timeout: request.timeoutMs,
364
- model: defaultModelId,
365
- },
366
- { setLastUsed: false },
367
- );
368
-
369
- const modelsPath = resolveModelsRegistryPath(manager);
370
- const modelsState = await readModelsFile(modelsPath);
371
- const supportsVision = capabilities?.includes("vision") ?? false;
372
- const supportsAttachments = supportsVision;
373
- const supportsReasoning = capabilities?.includes("reasoning") ?? false;
374
- modelsState.providers[providerId] = {
375
- provider: {
376
- name: providerName,
377
- baseUrl,
378
- defaultModelId,
379
- capabilities,
380
- modelsSourceUrl: sourceUrl,
381
- },
382
- models: Object.fromEntries(
383
- modelIds.map((modelId) => [
384
- modelId,
385
- {
386
- id: modelId,
387
- name: modelId,
388
- supportsVision,
389
- supportsAttachments,
390
- supportsReasoning,
391
- },
392
- ]),
393
- ),
394
- };
395
- await writeModelsFile(modelsPath, modelsState);
396
- registerCustomProvider(providerId, modelsState.providers[providerId]);
397
-
398
- return {
399
- providerId,
400
- settingsPath: manager.getFilePath(),
401
- modelsPath,
402
- modelsCount: modelIds.length,
403
- };
404
- }
405
-
406
- export async function listLocalProviders(
407
- manager: ProviderSettingsManager,
408
- ): Promise<{
409
- providers: RpcProviderListItem[];
410
- settingsPath: string;
411
- }> {
412
- const state = manager.read();
413
- const ids = LlmsModels.getProviderIds().sort((a, b) => a.localeCompare(b));
414
- const providerItems = await Promise.all(
415
- ids.map(async (id): Promise<RpcProviderListItem> => {
416
- const info = await LlmsModels.getProvider(id);
417
- const providerModels = await getLocalProviderModels(id);
418
- const persistedSettings = state.providers[id]?.settings;
419
- const providerName = info?.name ?? titleCaseFromId(id);
420
- return {
421
- id,
422
- name: providerName,
423
- models: providerModels.models.length,
424
- color: stableColor(id),
425
- letter: createLetter(providerName),
426
- enabled: Boolean(persistedSettings),
427
- apiKey: persistedSettings
428
- ? resolveVisibleApiKey(persistedSettings)
429
- : undefined,
430
- oauthAccessTokenPresent: persistedSettings
431
- ? hasOAuthAccessToken(persistedSettings)
432
- : undefined,
433
- baseUrl: persistedSettings?.baseUrl ?? info?.baseUrl,
434
- defaultModelId: info?.defaultModelId,
435
- authDescription: "This provider uses API keys for authentication.",
436
- baseUrlDescription: "The base endpoint to use for provider requests.",
437
- modelList: providerModels.models,
438
- };
439
- }),
440
- );
441
-
442
- return {
443
- providers: providerItems,
444
- settingsPath: manager.getFilePath(),
445
- };
446
- }
447
-
448
- export async function getLocalProviderModels(
449
- providerId: string,
450
- ): Promise<{ providerId: string; models: RpcProviderModel[] }> {
451
- const id = providerId.trim();
452
- const modelMap = await LlmsModels.getModelsForProvider(id);
453
- const items = Object.entries(modelMap)
454
- .sort(([a], [b]) => a.localeCompare(b))
455
- .map(([modelId, info]) => toRpcProviderModel(modelId, info));
456
- return {
457
- providerId: id,
458
- models: items,
459
- };
460
- }
461
-
462
- export function saveLocalProviderSettings(
463
- manager: ProviderSettingsManager,
464
- request: RpcSaveProviderSettingsActionRequest,
465
- ): { providerId: string; enabled: boolean; settingsPath: string } {
466
- const providerId = request.providerId.trim();
467
- const state = manager.read();
468
-
469
- if (request.enabled === false) {
470
- delete state.providers[providerId];
471
- if (state.lastUsedProvider === providerId) {
472
- delete state.lastUsedProvider;
473
- }
474
- manager.write(state);
475
- return {
476
- providerId,
477
- enabled: false,
478
- settingsPath: manager.getFilePath(),
479
- };
480
- }
481
-
482
- const existing = manager.getProviderSettings(providerId);
483
- const nextSettings: Record<string, unknown> = {
484
- ...(existing ?? {}),
485
- provider: providerId,
486
- };
487
-
488
- const hasApiKeyUpdate =
489
- Object.hasOwn(request, "apiKey") && typeof request.apiKey === "string";
490
- if (hasApiKeyUpdate) {
491
- const apiKey = request.apiKey?.trim() ?? "";
492
- if (apiKey.length === 0) {
493
- delete nextSettings.apiKey;
494
- } else {
495
- nextSettings.apiKey = request.apiKey;
496
- }
497
- }
498
-
499
- const hasBaseUrlUpdate =
500
- Object.hasOwn(request, "baseUrl") && typeof request.baseUrl === "string";
501
- if (hasBaseUrlUpdate) {
502
- const baseUrl = request.baseUrl?.trim() ?? "";
503
- if (baseUrl.length === 0) {
504
- delete nextSettings.baseUrl;
505
- } else {
506
- nextSettings.baseUrl = request.baseUrl;
507
- }
508
- }
509
-
510
- manager.saveProviderSettings(nextSettings, { setLastUsed: false });
511
- return {
512
- providerId,
513
- enabled: true,
514
- settingsPath: manager.getFilePath(),
515
- };
516
- }
517
-
518
- export function normalizeOAuthProvider(provider: string): RpcOAuthProviderId {
519
- const normalized = provider.trim().toLowerCase();
520
- if (normalized === "codex" || normalized === "openai-codex") {
521
- return "openai-codex";
522
- }
523
- if (normalized === "cline" || normalized === "oca") {
524
- return normalized;
525
- }
526
- throw new Error(
527
- `provider "${provider}" does not support OAuth login (supported: cline, oca, openai-codex)`,
528
- );
529
- }
530
-
531
- function toProviderApiKey(
532
- providerId: RpcOAuthProviderId,
533
- credentials: { access: string },
534
- ): string {
535
- if (providerId === "cline") {
536
- return `workos:${credentials.access}`;
537
- }
538
- return credentials.access;
539
- }
540
-
541
- export async function loginLocalProvider(
542
- providerId: RpcOAuthProviderId,
543
- existing: LlmsProviders.ProviderSettings | undefined,
544
- openUrl: (url: string) => void,
545
- ): Promise<{
546
- access: string;
547
- refresh: string;
548
- expires: number;
549
- accountId?: string;
550
- }> {
551
- const callbacks = createOAuthClientCallbacks({
552
- onPrompt: async (prompt) => prompt.defaultValue ?? "",
553
- openUrl,
554
- onOpenUrlError: ({ error }) => {
555
- throw error instanceof Error ? error : new Error(String(error));
556
- },
557
- });
558
-
559
- if (providerId === "cline") {
560
- return loginClineOAuth({
561
- apiBaseUrl: existing?.baseUrl?.trim() || "https://api.cline.bot",
562
- callbacks,
563
- });
564
- }
565
- if (providerId === "oca") {
566
- return loginOcaOAuth({
567
- mode: existing?.oca?.mode,
568
- callbacks,
569
- });
570
- }
571
- return loginOpenAICodex(callbacks);
572
- }
573
-
574
- export function saveLocalProviderOAuthCredentials(
575
- manager: ProviderSettingsManager,
576
- providerId: RpcOAuthProviderId,
577
- existing: LlmsProviders.ProviderSettings | undefined,
578
- credentials: {
579
- access: string;
580
- refresh: string;
581
- expires: number;
582
- accountId?: string;
583
- },
584
- ): LlmsProviders.ProviderSettings {
585
- const auth = {
586
- ...(existing?.auth ?? {}),
587
- accessToken: toProviderApiKey(providerId, credentials),
588
- refreshToken: credentials.refresh,
589
- accountId: credentials.accountId,
590
- } as LlmsProviders.ProviderSettings["auth"] & { expiresAt?: number };
591
- auth.expiresAt = credentials.expires;
592
- const merged: LlmsProviders.ProviderSettings = {
593
- ...(existing ?? {
594
- provider: providerId as LlmsProviders.ProviderSettings["provider"],
595
- }),
596
- provider: providerId as LlmsProviders.ProviderSettings["provider"],
597
- auth,
598
- };
599
- manager.saveProviderSettings(merged, { tokenSource: "oauth" });
600
- return merged;
601
- }
602
-
603
- export function resolveLocalClineAuthToken(
604
- settings: LlmsProviders.ProviderSettings | undefined,
605
- ): string | undefined {
606
- const token = settings?.auth?.accessToken?.trim() || settings?.apiKey?.trim();
607
- return token && token.length > 0 ? token : undefined;
608
- }
@@ -1,98 +0,0 @@
1
- import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
2
- import { tmpdir } from "node:os";
3
- import { join } from "node:path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
- import { createUserInstructionConfigWatcher } from "../agents";
6
- import {
7
- listAvailableRuntimeCommandsFromWatcher,
8
- resolveRuntimeSlashCommandFromWatcher,
9
- } from "./commands";
10
-
11
- describe("runtime command registry", () => {
12
- const tempRoots: string[] = [];
13
-
14
- afterEach(async () => {
15
- await Promise.all(
16
- tempRoots.map((dir) => rm(dir, { recursive: true, force: true })),
17
- );
18
- tempRoots.length = 0;
19
- });
20
-
21
- it("lists workflow and skill commands together", async () => {
22
- const tempRoot = await mkdtemp(join(tmpdir(), "core-runtime-commands-"));
23
- tempRoots.push(tempRoot);
24
- const skillDir = join(tempRoot, "skills", "debug");
25
- const workflowsDir = join(tempRoot, "workflows");
26
- await mkdir(skillDir, { recursive: true });
27
- await mkdir(workflowsDir, { recursive: true });
28
- await writeFile(join(skillDir, "SKILL.md"), "Use the debugging skill.");
29
- await writeFile(
30
- join(workflowsDir, "release.md"),
31
- `---
32
- name: release
33
- ---
34
- Run the release workflow.`,
35
- );
36
-
37
- const watcher = createUserInstructionConfigWatcher({
38
- skills: { directories: [join(tempRoot, "skills")] },
39
- rules: { directories: [] },
40
- workflows: { directories: [workflowsDir] },
41
- });
42
-
43
- try {
44
- await watcher.start();
45
- expect(listAvailableRuntimeCommandsFromWatcher(watcher)).toEqual([
46
- {
47
- id: "debug",
48
- name: "debug",
49
- instructions: "Use the debugging skill.",
50
- kind: "skill",
51
- },
52
- {
53
- id: "release",
54
- name: "release",
55
- instructions: "Run the release workflow.",
56
- kind: "workflow",
57
- },
58
- ]);
59
- } finally {
60
- watcher.stop();
61
- }
62
- });
63
-
64
- it("expands skill and workflow slash commands with workflow precedence", async () => {
65
- const tempRoot = await mkdtemp(join(tmpdir(), "core-runtime-commands-"));
66
- tempRoots.push(tempRoot);
67
- const skillDir = join(tempRoot, "skills", "ship");
68
- const workflowsDir = join(tempRoot, "workflows");
69
- await mkdir(skillDir, { recursive: true });
70
- await mkdir(workflowsDir, { recursive: true });
71
- await writeFile(join(skillDir, "SKILL.md"), "Use the ship skill.");
72
- await writeFile(
73
- join(workflowsDir, "ship.md"),
74
- `---
75
- name: ship
76
- ---
77
- Run the ship workflow.`,
78
- );
79
-
80
- const watcher = createUserInstructionConfigWatcher({
81
- skills: { directories: [join(tempRoot, "skills")] },
82
- rules: { directories: [] },
83
- workflows: { directories: [workflowsDir] },
84
- });
85
-
86
- try {
87
- await watcher.start();
88
- expect(resolveRuntimeSlashCommandFromWatcher("/ship", watcher)).toBe(
89
- "Run the ship workflow.",
90
- );
91
- expect(resolveRuntimeSlashCommandFromWatcher("/ship now", watcher)).toBe(
92
- "Run the ship workflow. now",
93
- );
94
- } finally {
95
- watcher.stop();
96
- }
97
- });
98
- });