@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,115 +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 {
6
- listAvailableRuntimeCommandsFromWatcher,
7
- resolveRuntimeSlashCommandFromWatcher,
8
- } from "./runtime-commands";
9
- import { createUserInstructionConfigWatcher } from "./user-instruction-config-loader";
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 slash commands with workflow precedence and ignores disabled entries", 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
- await writeFile(
80
- join(workflowsDir, "disabled.md"),
81
- `---
82
- name: disabled
83
- disabled: true
84
- ---
85
- Do not run this workflow.`,
86
- );
87
-
88
- const watcher = createUserInstructionConfigWatcher({
89
- skills: { directories: [join(tempRoot, "skills")] },
90
- rules: { directories: [] },
91
- workflows: { directories: [workflowsDir] },
92
- });
93
-
94
- try {
95
- await watcher.start();
96
- expect(resolveRuntimeSlashCommandFromWatcher("/ship", watcher)).toBe(
97
- "Run the ship workflow.",
98
- );
99
- expect(resolveRuntimeSlashCommandFromWatcher("/ship now", watcher)).toBe(
100
- "Run the ship workflow. now",
101
- );
102
- expect(resolveRuntimeSlashCommandFromWatcher("/disabled", watcher)).toBe(
103
- "/disabled",
104
- );
105
- expect(resolveRuntimeSlashCommandFromWatcher("/missing", watcher)).toBe(
106
- "/missing",
107
- );
108
- expect(
109
- resolveRuntimeSlashCommandFromWatcher("please run /ship", watcher),
110
- ).toBe("please run /ship");
111
- } finally {
112
- watcher.stop();
113
- }
114
- });
115
- });
@@ -1,196 +0,0 @@
1
- import { mkdir, mkdtemp, rm, unlink, writeFile } from "node:fs/promises";
2
- import { tmpdir } from "node:os";
3
- import { basename, join } from "node:path";
4
- import { afterEach, describe, expect, it } from "vitest";
5
- import {
6
- type AgentYamlConfig,
7
- parseAgentConfigFromYaml,
8
- } from "./agent-config-loader";
9
- import {
10
- UnifiedConfigFileWatcher,
11
- type UnifiedConfigWatcherEvent,
12
- } from "./unified-config-file-watcher";
13
-
14
- const WAIT_TIMEOUT_MS = 8_000;
15
- const WAIT_INTERVAL_MS = 25;
16
-
17
- async function waitForEvent<TType extends string, TItem>(
18
- events: Array<UnifiedConfigWatcherEvent<TType, TItem>>,
19
- predicate: (event: UnifiedConfigWatcherEvent<TType, TItem>) => boolean,
20
- timeoutMs = WAIT_TIMEOUT_MS,
21
- ): Promise<UnifiedConfigWatcherEvent<TType, TItem>> {
22
- const startedAt = Date.now();
23
- while (Date.now() - startedAt < timeoutMs) {
24
- const match = events.find(predicate);
25
- if (match) {
26
- return match;
27
- }
28
- await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
29
- }
30
- throw new Error("Timed out waiting for watcher event.");
31
- }
32
-
33
- describe("UnifiedConfigFileWatcher", () => {
34
- const tempRoots: string[] = [];
35
-
36
- afterEach(async () => {
37
- await Promise.all(
38
- tempRoots.map((dir) => rm(dir, { recursive: true, force: true })),
39
- );
40
- tempRoots.length = 0;
41
- });
42
-
43
- it("emits upsert and remove events with config type for agent configs", async () => {
44
- const tempRoot = await mkdtemp(
45
- join(tmpdir(), "core-unified-config-watcher-"),
46
- );
47
- tempRoots.push(tempRoot);
48
- const agentsDir = join(tempRoot, "agents");
49
- await mkdir(agentsDir, { recursive: true });
50
- const agentFilePath = join(agentsDir, "reviewer.yaml");
51
- await writeFile(
52
- agentFilePath,
53
- `---
54
- name: Reviewer
55
- description: Reviews patches
56
- tools: read_files
57
- ---
58
- Review code carefully.`,
59
- );
60
-
61
- const watcher = new UnifiedConfigFileWatcher([
62
- {
63
- type: "agent" as const,
64
- directories: [agentsDir],
65
- includeFile: (fileName) => /\.(yaml|yml)$/i.test(fileName),
66
- parseFile: (context) => parseAgentConfigFromYaml(context.content),
67
- resolveId: (config) => config.name.toLowerCase(),
68
- },
69
- ]);
70
-
71
- const events: Array<
72
- UnifiedConfigWatcherEvent<
73
- "agent",
74
- ReturnType<typeof parseAgentConfigFromYaml>
75
- >
76
- > = [];
77
- const unsubscribe = watcher.subscribe((event) => events.push(event));
78
-
79
- try {
80
- await watcher.start();
81
- await waitForEvent(
82
- events,
83
- (event) => event.kind === "upsert" && event.record.id === "reviewer",
84
- );
85
-
86
- events.length = 0;
87
- await writeFile(
88
- agentFilePath,
89
- `---
90
- name: Reviewer
91
- description: Reviews patches
92
- ---
93
- Review code with strictness.`,
94
- );
95
- await watcher.refreshType("agent");
96
- await waitForEvent(
97
- events,
98
- (event) => event.kind === "upsert" && event.record.type === "agent",
99
- );
100
-
101
- events.length = 0;
102
- await unlink(agentFilePath);
103
- await watcher.refreshType("agent");
104
- await waitForEvent(
105
- events,
106
- (event) => event.kind === "remove" && event.type === "agent",
107
- );
108
- } finally {
109
- unsubscribe();
110
- watcher.stop();
111
- }
112
- }, 15_000);
113
-
114
- it("supports one watcher instance for multiple config types", async () => {
115
- const tempRoot = await mkdtemp(
116
- join(tmpdir(), "core-unified-config-watcher-"),
117
- );
118
- tempRoots.push(tempRoot);
119
- const agentsDir = join(tempRoot, "agents");
120
- const skillsDir = join(tempRoot, "skills");
121
- await mkdir(agentsDir, { recursive: true });
122
- await mkdir(skillsDir, { recursive: true });
123
-
124
- await writeFile(
125
- join(agentsDir, "researcher.yaml"),
126
- `---
127
- name: Researcher
128
- description: Finds context
129
- ---
130
- Investigate related code paths.`,
131
- );
132
- await writeFile(
133
- join(skillsDir, "SKILL.md"),
134
- `---
135
- name: incident-response
136
- description: Handle incidents
137
- ---
138
- Escalation playbook`,
139
- );
140
-
141
- const watcher = new UnifiedConfigFileWatcher<
142
- "agent" | "skill",
143
- AgentYamlConfig | { path: string }
144
- >([
145
- {
146
- type: "agent" as const,
147
- directories: [agentsDir],
148
- includeFile: (fileName) => /\.(yaml|yml)$/i.test(fileName),
149
- parseFile: (context) =>
150
- parseAgentConfigFromYaml(context.content) as
151
- | AgentYamlConfig
152
- | { path: string },
153
- resolveId: (config) =>
154
- "name" in config ? config.name.toLowerCase() : "invalid-agent-config",
155
- },
156
- {
157
- type: "skill" as const,
158
- directories: [skillsDir],
159
- includeFile: (fileName) => fileName === "SKILL.md",
160
- parseFile: (context) => ({ path: context.filePath }),
161
- resolveId: (_parsed, context) => basename(context.directoryPath),
162
- },
163
- ]);
164
-
165
- const events: Array<
166
- UnifiedConfigWatcherEvent<
167
- "agent" | "skill",
168
- AgentYamlConfig | { path: string }
169
- >
170
- > = [];
171
- const unsubscribe = watcher.subscribe((event) => events.push(event));
172
-
173
- try {
174
- await watcher.start();
175
- await waitForEvent(
176
- events,
177
- (event) =>
178
- event.kind === "upsert" &&
179
- (event.record.type === "agent" || event.record.type === "skill"),
180
- );
181
- expect(
182
- events.some(
183
- (event) => event.kind === "upsert" && event.record.type === "agent",
184
- ),
185
- ).toBe(true);
186
- expect(
187
- events.some(
188
- (event) => event.kind === "upsert" && event.record.type === "skill",
189
- ),
190
- ).toBe(true);
191
- } finally {
192
- unsubscribe();
193
- watcher.stop();
194
- }
195
- });
196
- });
@@ -1,246 +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 {
6
- createRulesConfigDefinition,
7
- createSkillsConfigDefinition,
8
- createUserInstructionConfigWatcher,
9
- createWorkflowsConfigDefinition,
10
- parseRuleConfigFromMarkdown,
11
- parseSkillConfigFromMarkdown,
12
- parseWorkflowConfigFromMarkdown,
13
- resolveRulesConfigSearchPaths,
14
- resolveSkillsConfigSearchPaths,
15
- resolveWorkflowsConfigSearchPaths,
16
- type UserInstructionConfigWatcherEvent,
17
- } from "./user-instruction-config-loader";
18
-
19
- const WAIT_TIMEOUT_MS = 4_000;
20
- const WAIT_INTERVAL_MS = 25;
21
-
22
- async function waitForEvent(
23
- events: Array<UserInstructionConfigWatcherEvent>,
24
- predicate: (event: UserInstructionConfigWatcherEvent) => boolean,
25
- timeoutMs = WAIT_TIMEOUT_MS,
26
- ): Promise<UserInstructionConfigWatcherEvent> {
27
- const startedAt = Date.now();
28
- while (Date.now() - startedAt < timeoutMs) {
29
- const match = events.find(predicate);
30
- if (match) {
31
- return match;
32
- }
33
- await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
34
- }
35
- throw new Error("Timed out waiting for watcher event.");
36
- }
37
-
38
- describe("user instruction config loader", () => {
39
- const tempRoots: string[] = [];
40
-
41
- afterEach(async () => {
42
- await Promise.all(
43
- tempRoots.map((dir) => rm(dir, { recursive: true, force: true })),
44
- );
45
- tempRoots.length = 0;
46
- });
47
-
48
- it("resolves legacy-compatible default search paths", () => {
49
- const workspacePath = "/repo/demo";
50
- expect(resolveSkillsConfigSearchPaths(workspacePath)).toEqual(
51
- expect.arrayContaining([
52
- join(workspacePath, ".clinerules", "skills"),
53
- join(workspacePath, ".cline", "skills"),
54
- join(workspacePath, ".agents", "skills"),
55
- ]),
56
- );
57
- expect(resolveRulesConfigSearchPaths(workspacePath)).toEqual(
58
- expect.arrayContaining([
59
- join(workspacePath, "AGENTS.md"),
60
- join(workspacePath, ".clinerules"),
61
- join(workspacePath, ".cline", "rules"),
62
- ]),
63
- );
64
- expect(resolveWorkflowsConfigSearchPaths(workspacePath)).toEqual(
65
- expect.arrayContaining([join(workspacePath, ".clinerules", "workflows")]),
66
- );
67
- });
68
-
69
- it("discovers managed plugin instruction roots from workspace .cline manifests", () => {
70
- const workspacePath = "/repo/demo";
71
- expect(
72
- createSkillsConfigDefinition({ workspacePath }).directories,
73
- ).toContain(join(workspacePath, ".cline"));
74
- expect(
75
- createRulesConfigDefinition({ workspacePath }).directories,
76
- ).toContain(join(workspacePath, ".cline"));
77
- expect(
78
- createWorkflowsConfigDefinition({ workspacePath }).directories,
79
- ).toContain(join(workspacePath, ".cline"));
80
- });
81
-
82
- it("parses markdown frontmatter for skill, rule, and workflow configs", () => {
83
- const skill = parseSkillConfigFromMarkdown(
84
- `---
85
- name: debugging
86
- description: Use structured debugging
87
- disabled: true
88
- ---
89
- Follow the debugging checklist.`,
90
- "fallback",
91
- );
92
- expect(skill.name).toBe("debugging");
93
- expect(skill.description).toBe("Use structured debugging");
94
- expect(skill.disabled).toBe(true);
95
- expect(skill.instructions).toBe("Follow the debugging checklist.");
96
-
97
- const rule = parseRuleConfigFromMarkdown(
98
- `---
99
- name: rule-a
100
- disabled: true
101
- ---
102
- Always run tests before merge.`,
103
- "rule-a",
104
- );
105
- expect(rule.name).toBe("rule-a");
106
- expect(rule.disabled).toBe(true);
107
-
108
- const workflow = parseWorkflowConfigFromMarkdown(
109
- `---
110
- name: release
111
- disabled: true
112
- ---
113
- Document rollout and rollback steps.`,
114
- "release",
115
- );
116
- expect(workflow.name).toBe("release");
117
- expect(workflow.disabled).toBe(true);
118
- });
119
-
120
- it("emits typed events for skills, rules, and workflows in one watcher", async () => {
121
- const tempRoot = await mkdtemp(
122
- join(tmpdir(), "core-user-instructions-loader-"),
123
- );
124
- tempRoots.push(tempRoot);
125
- const skillsDir = join(tempRoot, "skills");
126
- const rulesDir = join(tempRoot, "rules");
127
- const workflowsDir = join(tempRoot, "workflows");
128
- await mkdir(join(skillsDir, "incident-response"), { recursive: true });
129
- await mkdir(rulesDir, { recursive: true });
130
- await mkdir(workflowsDir, { recursive: true });
131
-
132
- await writeFile(
133
- join(skillsDir, "incident-response", "SKILL.md"),
134
- `---
135
- name: incident-response
136
- description: Handle incidents fast
137
- ---
138
- Escalation runbook`,
139
- );
140
- await writeFile(
141
- join(rulesDir, "default.md"),
142
- "Keep changes minimal and tested.",
143
- );
144
- await writeFile(
145
- join(workflowsDir, "release.md"),
146
- "Ship with release checklist.",
147
- );
148
-
149
- const watcher = createUserInstructionConfigWatcher({
150
- skills: { directories: [skillsDir] },
151
- rules: { directories: [rulesDir] },
152
- workflows: { directories: [workflowsDir] },
153
- });
154
-
155
- const events: Array<UserInstructionConfigWatcherEvent> = [];
156
- const unsubscribe = watcher.subscribe((event) => events.push(event));
157
-
158
- try {
159
- await watcher.start();
160
- await waitForEvent(
161
- events,
162
- (event) => event.kind === "upsert" && event.record.type === "skill",
163
- );
164
- await waitForEvent(
165
- events,
166
- (event) => event.kind === "upsert" && event.record.type === "rule",
167
- );
168
- await waitForEvent(
169
- events,
170
- (event) => event.kind === "upsert" && event.record.type === "workflow",
171
- );
172
- } finally {
173
- unsubscribe();
174
- watcher.stop();
175
- }
176
- });
177
-
178
- it("loads enterprise-style managed rules, workflows, and skills through the default workspace watcher", async () => {
179
- const tempRoot = await mkdtemp(
180
- join(tmpdir(), "core-user-instructions-managed-"),
181
- );
182
- tempRoots.push(tempRoot);
183
-
184
- const pluginRoot = join(tempRoot, ".cline", "enterprise");
185
- await mkdir(join(pluginRoot, "workflows"), { recursive: true });
186
- await mkdir(join(pluginRoot, "skills", "security-review"), {
187
- recursive: true,
188
- });
189
- await writeFile(
190
- join(pluginRoot, "managed.json"),
191
- JSON.stringify({ source: "enterprise", version: "1", files: [] }),
192
- );
193
- await writeFile(
194
- join(pluginRoot, "rules.md"),
195
- `---
196
- name: enterprise-policy
197
- ---
198
- Follow enterprise policy.`,
199
- );
200
- await writeFile(
201
- join(pluginRoot, "workflows", "triage.md"),
202
- `---
203
- name: triage
204
- ---
205
- Follow the triage workflow.`,
206
- );
207
- await writeFile(
208
- join(pluginRoot, "skills", "security-review", "SKILL.md"),
209
- `---
210
- name: security-review
211
- ---
212
- Use the security review checklist.`,
213
- );
214
-
215
- const watcher = createUserInstructionConfigWatcher({
216
- skills: { workspacePath: tempRoot },
217
- rules: { workspacePath: tempRoot },
218
- workflows: { workspacePath: tempRoot },
219
- });
220
-
221
- try {
222
- await watcher.start();
223
- const rules = watcher.getSnapshot("rule");
224
- const workflows = watcher.getSnapshot("workflow");
225
- const skills = watcher.getSnapshot("skill");
226
-
227
- expect(
228
- [...rules.values()].some((rule) =>
229
- rule.item.instructions.includes("enterprise policy"),
230
- ),
231
- ).toBe(true);
232
- expect(
233
- [...workflows.values()].some((workflow) =>
234
- workflow.item.instructions.includes("triage workflow"),
235
- ),
236
- ).toBe(true);
237
- expect(
238
- [...skills.values()].some((skill) =>
239
- skill.item.instructions.includes("security review checklist"),
240
- ),
241
- ).toBe(true);
242
- } finally {
243
- watcher.stop();
244
- }
245
- });
246
- });