@clinebot/core 0.0.18 → 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 +8 -6
  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,158 +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
- createUserInstructionConfigWatcher,
7
- parseRuleConfigFromMarkdown,
8
- parseSkillConfigFromMarkdown,
9
- parseWorkflowConfigFromMarkdown,
10
- resolveRulesConfigSearchPaths,
11
- resolveSkillsConfigSearchPaths,
12
- resolveWorkflowsConfigSearchPaths,
13
- type UserInstructionConfigWatcherEvent,
14
- } from "./user-instruction-config-loader";
15
-
16
- const WAIT_TIMEOUT_MS = 4_000;
17
- const WAIT_INTERVAL_MS = 25;
18
-
19
- async function waitForEvent(
20
- events: Array<UserInstructionConfigWatcherEvent>,
21
- predicate: (event: UserInstructionConfigWatcherEvent) => boolean,
22
- timeoutMs = WAIT_TIMEOUT_MS,
23
- ): Promise<UserInstructionConfigWatcherEvent> {
24
- const startedAt = Date.now();
25
- while (Date.now() - startedAt < timeoutMs) {
26
- const match = events.find(predicate);
27
- if (match) {
28
- return match;
29
- }
30
- await new Promise((resolve) => setTimeout(resolve, WAIT_INTERVAL_MS));
31
- }
32
- throw new Error("Timed out waiting for watcher event.");
33
- }
34
-
35
- describe("user instruction config loader", () => {
36
- const tempRoots: string[] = [];
37
-
38
- afterEach(async () => {
39
- await Promise.all(
40
- tempRoots.map((dir) => rm(dir, { recursive: true, force: true })),
41
- );
42
- tempRoots.length = 0;
43
- });
44
-
45
- it("resolves legacy-compatible default search paths", () => {
46
- const workspacePath = "/repo/demo";
47
- expect(resolveSkillsConfigSearchPaths(workspacePath)).toEqual(
48
- expect.arrayContaining([
49
- join(workspacePath, ".clinerules", "skills"),
50
- join(workspacePath, ".cline", "skills"),
51
- join(workspacePath, ".claude", "skills"),
52
- join(workspacePath, ".agents", "skills"),
53
- ]),
54
- );
55
- expect(resolveRulesConfigSearchPaths(workspacePath)).toEqual(
56
- expect.arrayContaining([join(workspacePath, ".clinerules")]),
57
- );
58
- expect(resolveWorkflowsConfigSearchPaths(workspacePath)).toEqual(
59
- expect.arrayContaining([join(workspacePath, ".clinerules", "workflows")]),
60
- );
61
- });
62
-
63
- it("parses markdown frontmatter for skill, rule, and workflow configs", () => {
64
- const skill = parseSkillConfigFromMarkdown(
65
- `---
66
- name: debugging
67
- description: Use structured debugging
68
- disabled: true
69
- ---
70
- Follow the debugging checklist.`,
71
- "fallback",
72
- );
73
- expect(skill.name).toBe("debugging");
74
- expect(skill.description).toBe("Use structured debugging");
75
- expect(skill.disabled).toBe(true);
76
- expect(skill.instructions).toBe("Follow the debugging checklist.");
77
-
78
- const rule = parseRuleConfigFromMarkdown(
79
- `---
80
- name: rule-a
81
- disabled: true
82
- ---
83
- Always run tests before merge.`,
84
- "rule-a",
85
- );
86
- expect(rule.name).toBe("rule-a");
87
- expect(rule.disabled).toBe(true);
88
-
89
- const workflow = parseWorkflowConfigFromMarkdown(
90
- `---
91
- name: release
92
- disabled: true
93
- ---
94
- Document rollout and rollback steps.`,
95
- "release",
96
- );
97
- expect(workflow.name).toBe("release");
98
- expect(workflow.disabled).toBe(true);
99
- });
100
-
101
- it("emits typed events for skills, rules, and workflows in one watcher", async () => {
102
- const tempRoot = await mkdtemp(
103
- join(tmpdir(), "core-user-instructions-loader-"),
104
- );
105
- tempRoots.push(tempRoot);
106
- const skillsDir = join(tempRoot, "skills");
107
- const rulesDir = join(tempRoot, "rules");
108
- const workflowsDir = join(tempRoot, "workflows");
109
- await mkdir(join(skillsDir, "incident-response"), { recursive: true });
110
- await mkdir(rulesDir, { recursive: true });
111
- await mkdir(workflowsDir, { recursive: true });
112
-
113
- await writeFile(
114
- join(skillsDir, "incident-response", "SKILL.md"),
115
- `---
116
- name: incident-response
117
- description: Handle incidents fast
118
- ---
119
- Escalation runbook`,
120
- );
121
- await writeFile(
122
- join(rulesDir, "default.md"),
123
- "Keep changes minimal and tested.",
124
- );
125
- await writeFile(
126
- join(workflowsDir, "release.md"),
127
- "Ship with release checklist.",
128
- );
129
-
130
- const watcher = createUserInstructionConfigWatcher({
131
- skills: { directories: [skillsDir] },
132
- rules: { directories: [rulesDir] },
133
- workflows: { directories: [workflowsDir] },
134
- });
135
-
136
- const events: Array<UserInstructionConfigWatcherEvent> = [];
137
- const unsubscribe = watcher.subscribe((event) => events.push(event));
138
-
139
- try {
140
- await watcher.start();
141
- await waitForEvent(
142
- events,
143
- (event) => event.kind === "upsert" && event.record.type === "skill",
144
- );
145
- await waitForEvent(
146
- events,
147
- (event) => event.kind === "upsert" && event.record.type === "rule",
148
- );
149
- await waitForEvent(
150
- events,
151
- (event) => event.kind === "upsert" && event.record.type === "workflow",
152
- );
153
- } finally {
154
- unsubscribe();
155
- watcher.stop();
156
- }
157
- });
158
- });
@@ -1,438 +0,0 @@
1
- import { readdir, stat } from "node:fs/promises";
2
- import { basename, dirname, extname, join } from "node:path";
3
- import {
4
- RULES_CONFIG_DIRECTORY_NAME,
5
- resolveDocumentsRulesDirectoryPath,
6
- resolveDocumentsWorkflowsDirectoryPath,
7
- resolveRulesConfigSearchPaths as resolveRulesConfigSearchPathsFromShared,
8
- resolveSkillsConfigSearchPaths as resolveSkillsConfigSearchPathsFromShared,
9
- resolveWorkflowsConfigSearchPaths as resolveWorkflowsConfigSearchPathsFromShared,
10
- SKILLS_CONFIG_DIRECTORY_NAME,
11
- WORKFLOWS_CONFIG_DIRECTORY_NAME,
12
- } from "@clinebot/shared/storage";
13
- import YAML from "yaml";
14
- import {
15
- type UnifiedConfigDefinition,
16
- type UnifiedConfigFileCandidate,
17
- UnifiedConfigFileWatcher,
18
- type UnifiedConfigWatcherEvent,
19
- } from "./unified-config-file-watcher";
20
-
21
- const SKILL_FILE_NAME = "SKILL.md";
22
-
23
- const MARKDOWN_EXTENSIONS = new Set([".md", ".markdown", ".txt"]);
24
-
25
- export {
26
- RULES_CONFIG_DIRECTORY_NAME,
27
- resolveDocumentsRulesDirectoryPath,
28
- resolveDocumentsWorkflowsDirectoryPath,
29
- SKILLS_CONFIG_DIRECTORY_NAME,
30
- WORKFLOWS_CONFIG_DIRECTORY_NAME,
31
- };
32
-
33
- export interface ParseMarkdownFrontmatterResult {
34
- data: Record<string, unknown>;
35
- body: string;
36
- hadFrontmatter: boolean;
37
- parseError?: string;
38
- }
39
-
40
- export interface SkillConfig {
41
- name: string;
42
- description?: string;
43
- disabled?: boolean;
44
- instructions: string;
45
- frontmatter: Record<string, unknown>;
46
- }
47
-
48
- export interface RuleConfig {
49
- name: string;
50
- disabled?: boolean;
51
- instructions: string;
52
- frontmatter: Record<string, unknown>;
53
- }
54
-
55
- export interface WorkflowConfig {
56
- name: string;
57
- disabled?: boolean;
58
- instructions: string;
59
- frontmatter: Record<string, unknown>;
60
- }
61
-
62
- export type UserInstructionConfigType = "skill" | "rule" | "workflow";
63
-
64
- export type UserInstructionConfig = SkillConfig | RuleConfig | WorkflowConfig;
65
-
66
- export type UserInstructionConfigWatcher = UnifiedConfigFileWatcher<
67
- UserInstructionConfigType,
68
- UserInstructionConfig
69
- >;
70
-
71
- export type UserInstructionConfigWatcherEvent = UnifiedConfigWatcherEvent<
72
- UserInstructionConfigType,
73
- UserInstructionConfig
74
- >;
75
-
76
- export interface CreateInstructionWatcherOptions {
77
- debounceMs?: number;
78
- emitParseErrors?: boolean;
79
- }
80
-
81
- export interface CreateSkillsConfigDefinitionOptions {
82
- directories?: ReadonlyArray<string>;
83
- workspacePath?: string;
84
- }
85
-
86
- export interface CreateRulesConfigDefinitionOptions {
87
- directories?: ReadonlyArray<string>;
88
- workspacePath?: string;
89
- }
90
-
91
- export interface CreateWorkflowsConfigDefinitionOptions {
92
- directories?: ReadonlyArray<string>;
93
- workspacePath?: string;
94
- }
95
-
96
- function normalizeName(name: string): string {
97
- return name.trim().toLowerCase();
98
- }
99
-
100
- function isMarkdownFile(fileName: string): boolean {
101
- return MARKDOWN_EXTENSIONS.has(extname(fileName).toLowerCase());
102
- }
103
-
104
- function parseMarkdownFrontmatter(
105
- content: string,
106
- ): ParseMarkdownFrontmatterResult {
107
- const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
108
- const match = content.match(frontmatterRegex);
109
- if (!match) {
110
- return { data: {}, body: content, hadFrontmatter: false };
111
- }
112
-
113
- const [, yamlContent, body] = match;
114
- try {
115
- const parsed = YAML.parse(yamlContent);
116
- const data =
117
- parsed && typeof parsed === "object" && !Array.isArray(parsed)
118
- ? (parsed as Record<string, unknown>)
119
- : {};
120
- return { data, body, hadFrontmatter: true };
121
- } catch (error) {
122
- const message = error instanceof Error ? error.message : String(error);
123
- return {
124
- data: {},
125
- body: content,
126
- hadFrontmatter: true,
127
- parseError: message,
128
- };
129
- }
130
- }
131
-
132
- function parseStringField(
133
- value: unknown,
134
- fieldName: string,
135
- isRequired: boolean,
136
- ): string | undefined {
137
- if (value === undefined || value === null) {
138
- if (isRequired) {
139
- throw new Error(`Missing required frontmatter field '${fieldName}'.`);
140
- }
141
- return undefined;
142
- }
143
- if (typeof value !== "string") {
144
- throw new Error(`Frontmatter field '${fieldName}' must be a string.`);
145
- }
146
- const normalized = value.trim();
147
- if (!normalized && isRequired) {
148
- throw new Error(`Frontmatter field '${fieldName}' cannot be empty.`);
149
- }
150
- return normalized || undefined;
151
- }
152
-
153
- function parseBooleanField(
154
- value: unknown,
155
- fieldName: string,
156
- ): boolean | undefined {
157
- if (value === undefined || value === null) {
158
- return undefined;
159
- }
160
- if (typeof value !== "boolean") {
161
- throw new Error(`Frontmatter field '${fieldName}' must be a boolean.`);
162
- }
163
- return value;
164
- }
165
-
166
- export function parseSkillConfigFromMarkdown(
167
- content: string,
168
- fallbackName: string,
169
- ): SkillConfig {
170
- const { data, body, parseError } = parseMarkdownFrontmatter(content);
171
- if (parseError) {
172
- throw new Error(`Failed to parse YAML frontmatter: ${parseError}`);
173
- }
174
- const instructions = body.trim();
175
- if (!instructions) {
176
- throw new Error("Missing instructions body in skill file.");
177
- }
178
- const parsedName = parseStringField(data.name, "name", false);
179
- const name = parsedName ?? fallbackName.trim();
180
- if (!name) {
181
- throw new Error("Missing skill name.");
182
- }
183
-
184
- return {
185
- name,
186
- description: parseStringField(data.description, "description", false),
187
- disabled:
188
- parseBooleanField(data.disabled, "disabled") ??
189
- (parseBooleanField(data.enabled, "enabled") === false ? true : undefined),
190
- instructions,
191
- frontmatter: data,
192
- };
193
- }
194
-
195
- export function parseRuleConfigFromMarkdown(
196
- content: string,
197
- fallbackName: string,
198
- ): RuleConfig {
199
- const { data, body, parseError } = parseMarkdownFrontmatter(content);
200
- if (parseError) {
201
- throw new Error(`Failed to parse YAML frontmatter: ${parseError}`);
202
- }
203
- const instructions = body.trim();
204
- if (!instructions) {
205
- throw new Error("Missing instructions body in rule file.");
206
- }
207
- const name =
208
- parseStringField(data.name, "name", false) ?? fallbackName.trim();
209
- if (!name) {
210
- throw new Error("Missing rule name.");
211
- }
212
- return {
213
- name,
214
- disabled:
215
- parseBooleanField(data.disabled, "disabled") ??
216
- (parseBooleanField(data.enabled, "enabled") === false ? true : undefined),
217
- instructions,
218
- frontmatter: data,
219
- };
220
- }
221
-
222
- export function parseWorkflowConfigFromMarkdown(
223
- content: string,
224
- fallbackName: string,
225
- ): WorkflowConfig {
226
- const { data, body, parseError } = parseMarkdownFrontmatter(content);
227
- if (parseError) {
228
- throw new Error(`Failed to parse YAML frontmatter: ${parseError}`);
229
- }
230
- const instructions = body.trim();
231
- if (!instructions) {
232
- throw new Error("Missing instructions body in workflow file.");
233
- }
234
- const name =
235
- parseStringField(data.name, "name", false) ?? fallbackName.trim();
236
- if (!name) {
237
- throw new Error("Missing workflow name.");
238
- }
239
- return {
240
- name,
241
- disabled:
242
- parseBooleanField(data.disabled, "disabled") ??
243
- (parseBooleanField(data.enabled, "enabled") === false ? true : undefined),
244
- instructions,
245
- frontmatter: data,
246
- };
247
- }
248
-
249
- export function resolveSkillsConfigSearchPaths(
250
- workspacePath?: string,
251
- ): string[] {
252
- return resolveSkillsConfigSearchPathsFromShared(workspacePath);
253
- }
254
-
255
- export function resolveRulesConfigSearchPaths(
256
- workspacePath?: string,
257
- ): string[] {
258
- return resolveRulesConfigSearchPathsFromShared(workspacePath);
259
- }
260
-
261
- export function resolveWorkflowsConfigSearchPaths(
262
- workspacePath?: string,
263
- ): string[] {
264
- return resolveWorkflowsConfigSearchPathsFromShared(workspacePath);
265
- }
266
-
267
- async function discoverSkillFiles(
268
- directoryPath: string,
269
- ): Promise<ReadonlyArray<UnifiedConfigFileCandidate>> {
270
- try {
271
- const entries = await readdir(directoryPath, { withFileTypes: true });
272
- const candidates: UnifiedConfigFileCandidate[] = [];
273
- for (const entry of entries) {
274
- if (entry.isFile() && entry.name === SKILL_FILE_NAME) {
275
- candidates.push({
276
- directoryPath,
277
- fileName: entry.name,
278
- filePath: join(directoryPath, entry.name),
279
- });
280
- continue;
281
- }
282
- if (entry.isDirectory()) {
283
- candidates.push({
284
- directoryPath: join(directoryPath, entry.name),
285
- fileName: SKILL_FILE_NAME,
286
- filePath: join(directoryPath, entry.name, SKILL_FILE_NAME),
287
- });
288
- }
289
- }
290
- return candidates;
291
- } catch (error) {
292
- const nodeError = error as NodeJS.ErrnoException;
293
- if (nodeError.code === "ENOENT") {
294
- return [];
295
- }
296
- throw error;
297
- }
298
- }
299
-
300
- async function discoverRulesLikeFiles(
301
- directoryPath: string,
302
- ): Promise<ReadonlyArray<UnifiedConfigFileCandidate>> {
303
- try {
304
- const entryStat = await stat(directoryPath);
305
- if (entryStat.isFile()) {
306
- return [
307
- {
308
- directoryPath: dirname(directoryPath),
309
- fileName: basename(directoryPath),
310
- filePath: directoryPath,
311
- },
312
- ];
313
- }
314
- } catch (error) {
315
- const nodeError = error as NodeJS.ErrnoException;
316
- if (nodeError.code !== "ENOENT") {
317
- throw error;
318
- }
319
- }
320
-
321
- try {
322
- const entries = await readdir(directoryPath, { withFileTypes: true });
323
- return entries
324
- .filter((entry) => entry.isFile() && isMarkdownFile(entry.name))
325
- .map((entry) => ({
326
- directoryPath,
327
- fileName: entry.name,
328
- filePath: join(directoryPath, entry.name),
329
- }));
330
- } catch (error) {
331
- const nodeError = error as NodeJS.ErrnoException;
332
- if (nodeError.code === "ENOENT") {
333
- return [];
334
- }
335
- throw error;
336
- }
337
- }
338
-
339
- export function createSkillsConfigDefinition(
340
- options?: CreateSkillsConfigDefinitionOptions,
341
- ): UnifiedConfigDefinition<"skill", SkillConfig> {
342
- const directories =
343
- options?.directories ??
344
- resolveSkillsConfigSearchPaths(options?.workspacePath);
345
-
346
- return {
347
- type: "skill",
348
- directories,
349
- discoverFiles: discoverSkillFiles,
350
- includeFile: (fileName) => fileName === SKILL_FILE_NAME,
351
- parseFile: (context) =>
352
- parseSkillConfigFromMarkdown(
353
- context.content,
354
- basename(context.directoryPath),
355
- ),
356
- resolveId: (skill) => normalizeName(skill.name),
357
- };
358
- }
359
-
360
- export function createRulesConfigDefinition(
361
- options?: CreateRulesConfigDefinitionOptions,
362
- ): UnifiedConfigDefinition<"rule", RuleConfig> {
363
- const directories =
364
- options?.directories ??
365
- resolveRulesConfigSearchPaths(options?.workspacePath);
366
-
367
- return {
368
- type: "rule",
369
- directories,
370
- discoverFiles: discoverRulesLikeFiles,
371
- includeFile: (fileName, filePath) =>
372
- fileName === ".clinerules" ||
373
- isMarkdownFile(fileName) ||
374
- isMarkdownFile(filePath),
375
- parseFile: (context) =>
376
- parseRuleConfigFromMarkdown(
377
- context.content,
378
- basename(context.filePath, extname(context.filePath)),
379
- ),
380
- resolveId: (rule) => normalizeName(rule.name),
381
- };
382
- }
383
-
384
- export function createWorkflowsConfigDefinition(
385
- options?: CreateWorkflowsConfigDefinitionOptions,
386
- ): UnifiedConfigDefinition<"workflow", WorkflowConfig> {
387
- const directories =
388
- options?.directories ??
389
- resolveWorkflowsConfigSearchPaths(options?.workspacePath);
390
-
391
- return {
392
- type: "workflow",
393
- directories,
394
- discoverFiles: discoverRulesLikeFiles,
395
- includeFile: (fileName) => isMarkdownFile(fileName),
396
- parseFile: (context) =>
397
- parseWorkflowConfigFromMarkdown(
398
- context.content,
399
- basename(context.filePath, extname(context.filePath)),
400
- ),
401
- resolveId: (workflow) => normalizeName(workflow.name),
402
- };
403
- }
404
-
405
- export interface CreateUserInstructionConfigWatcherOptions
406
- extends CreateInstructionWatcherOptions {
407
- skills?: CreateSkillsConfigDefinitionOptions;
408
- rules?: CreateRulesConfigDefinitionOptions;
409
- workflows?: CreateWorkflowsConfigDefinitionOptions;
410
- }
411
-
412
- export function createUserInstructionConfigWatcher(
413
- options?: CreateUserInstructionConfigWatcherOptions,
414
- ): UserInstructionConfigWatcher {
415
- const definitions: ReadonlyArray<
416
- UnifiedConfigDefinition<UserInstructionConfigType, UserInstructionConfig>
417
- > = [
418
- createSkillsConfigDefinition(options?.skills) as UnifiedConfigDefinition<
419
- UserInstructionConfigType,
420
- UserInstructionConfig
421
- >,
422
- createRulesConfigDefinition(options?.rules) as UnifiedConfigDefinition<
423
- UserInstructionConfigType,
424
- UserInstructionConfig
425
- >,
426
- createWorkflowsConfigDefinition(
427
- options?.workflows,
428
- ) as UnifiedConfigDefinition<
429
- UserInstructionConfigType,
430
- UserInstructionConfig
431
- >,
432
- ];
433
-
434
- return new UnifiedConfigFileWatcher(definitions, {
435
- debounceMs: options?.debounceMs,
436
- emitParseErrors: options?.emitParseErrors,
437
- });
438
- }
@@ -1,40 +0,0 @@
1
- import { describe, expect, it, vi } from "vitest";
2
- import { createOAuthClientCallbacks } from "./client.js";
3
-
4
- describe("auth/client createOAuthClientCallbacks", () => {
5
- it("emits instructions and URL and forwards prompts", async () => {
6
- const onOutput = vi.fn();
7
- const onPrompt = vi.fn().mockResolvedValue("value");
8
- const callbacks = createOAuthClientCallbacks({ onOutput, onPrompt });
9
-
10
- callbacks.onAuth({
11
- url: "https://example.com/auth",
12
- instructions: "Open your browser",
13
- });
14
- const answer = await callbacks.onPrompt({ message: "Enter code" });
15
-
16
- expect(answer).toBe("value");
17
- expect(onPrompt).toHaveBeenCalledWith({ message: "Enter code" });
18
- expect(onOutput).toHaveBeenNthCalledWith(1, "Open your browser");
19
- expect(onOutput).toHaveBeenNthCalledWith(2, "https://example.com/auth");
20
- });
21
-
22
- it("tries opening URL and reports opener errors", async () => {
23
- const openUrl = vi.fn().mockRejectedValue(new Error("failed"));
24
- const onOpenUrlError = vi.fn();
25
- const callbacks = createOAuthClientCallbacks({
26
- onPrompt: vi.fn().mockResolvedValue(""),
27
- openUrl,
28
- onOpenUrlError,
29
- });
30
-
31
- callbacks.onAuth({ url: "https://example.com/auth" });
32
- await Promise.resolve();
33
-
34
- expect(openUrl).toHaveBeenCalledWith("https://example.com/auth");
35
- expect(onOpenUrlError).toHaveBeenCalledTimes(1);
36
- expect(onOpenUrlError.mock.calls[0]?.[0]).toMatchObject({
37
- url: "https://example.com/auth",
38
- });
39
- });
40
- });
@@ -1,25 +0,0 @@
1
- import type { OAuthLoginCallbacks, OAuthPrompt } from "./types.js";
2
-
3
- export interface OAuthClientCallbacksOptions {
4
- onPrompt: (prompt: OAuthPrompt) => Promise<string>;
5
- onOutput?: (message: string) => void;
6
- openUrl?: (url: string) => void | Promise<void>;
7
- onOpenUrlError?: (context: { url: string; error: unknown }) => void;
8
- }
9
-
10
- export function createOAuthClientCallbacks(
11
- options: OAuthClientCallbacksOptions,
12
- ): OAuthLoginCallbacks {
13
- return {
14
- onAuth: ({ url, instructions }) => {
15
- options.onOutput?.(instructions ?? "Complete sign-in in your browser.");
16
- if (options.openUrl) {
17
- void Promise.resolve(options.openUrl(url)).catch((error) => {
18
- options.onOpenUrlError?.({ url, error });
19
- });
20
- }
21
- options.onOutput?.(url);
22
- },
23
- onPrompt: options.onPrompt,
24
- };
25
- }