@clinebot/core 0.0.35 → 0.0.37

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 (441) hide show
  1. package/README.md +1 -2
  2. package/dist/ClineCore.d.ts +362 -39
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts.map +1 -1
  5. package/dist/account/index.d.ts +1 -1
  6. package/dist/account/index.d.ts.map +1 -1
  7. package/dist/account/rpc.d.ts +6 -6
  8. package/dist/account/rpc.d.ts.map +1 -1
  9. package/dist/cron/cron-event-ingress.d.ts +38 -0
  10. package/dist/cron/cron-event-ingress.d.ts.map +1 -0
  11. package/dist/cron/cron-materializer.d.ts +36 -0
  12. package/dist/cron/cron-materializer.d.ts.map +1 -0
  13. package/dist/cron/cron-reconciler.d.ts +62 -0
  14. package/dist/cron/cron-reconciler.d.ts.map +1 -0
  15. package/dist/cron/cron-report-writer.d.ts +41 -0
  16. package/dist/cron/cron-report-writer.d.ts.map +1 -0
  17. package/dist/cron/cron-runner.d.ts +43 -0
  18. package/dist/cron/cron-runner.d.ts.map +1 -0
  19. package/dist/cron/cron-schema.d.ts +3 -0
  20. package/dist/cron/cron-schema.d.ts.map +1 -0
  21. package/dist/cron/cron-service.d.ts +57 -0
  22. package/dist/cron/cron-service.d.ts.map +1 -0
  23. package/dist/cron/cron-spec-parser.d.ts +27 -0
  24. package/dist/cron/cron-spec-parser.d.ts.map +1 -0
  25. package/dist/cron/cron-watcher.d.ts +23 -0
  26. package/dist/cron/cron-watcher.d.ts.map +1 -0
  27. package/dist/cron/resource-limiter.d.ts +9 -0
  28. package/dist/cron/resource-limiter.d.ts.map +1 -0
  29. package/dist/cron/schedule-command-service.d.ts +10 -0
  30. package/dist/cron/schedule-command-service.d.ts.map +1 -0
  31. package/dist/cron/schedule-service.d.ts +100 -0
  32. package/dist/cron/schedule-service.d.ts.map +1 -0
  33. package/dist/cron/scheduler.d.ts +68 -0
  34. package/dist/cron/scheduler.d.ts.map +1 -0
  35. package/dist/cron/sqlite-cron-store.d.ts +230 -0
  36. package/dist/cron/sqlite-cron-store.d.ts.map +1 -0
  37. package/dist/cron/sqlite-schedule-store.d.ts +52 -0
  38. package/dist/cron/sqlite-schedule-store.d.ts.map +1 -0
  39. package/dist/extensions/config/agent-config-loader.d.ts +4 -3
  40. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -1
  41. package/dist/extensions/config/runtime-commands.d.ts +1 -0
  42. package/dist/extensions/config/runtime-commands.d.ts.map +1 -1
  43. package/dist/extensions/config/user-instruction-config-loader.d.ts +1 -0
  44. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -1
  45. package/dist/extensions/context/agentic-compaction.d.ts +2 -2
  46. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -1
  47. package/dist/extensions/context/compaction-shared.d.ts +5 -4
  48. package/dist/extensions/context/compaction-shared.d.ts.map +1 -1
  49. package/dist/extensions/context/compaction.d.ts.map +1 -1
  50. package/dist/extensions/plugin/plugin-config-loader.d.ts +15 -2
  51. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  52. package/dist/extensions/plugin/plugin-loader.d.ts +13 -7
  53. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  54. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -1
  55. package/dist/extensions/plugin/plugin-sandbox.d.ts +21 -2
  56. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  57. package/dist/extensions/plugin/plugin-targeting.d.ts +7 -0
  58. package/dist/extensions/plugin/plugin-targeting.d.ts.map +1 -0
  59. package/dist/extensions/plugin-sandbox-bootstrap.js +237 -276
  60. package/dist/extensions/tools/constants.d.ts +1 -0
  61. package/dist/extensions/tools/constants.d.ts.map +1 -1
  62. package/dist/extensions/tools/definitions.d.ts +3 -4
  63. package/dist/extensions/tools/definitions.d.ts.map +1 -1
  64. package/dist/extensions/tools/executors/apply-patch.d.ts +3 -1
  65. package/dist/extensions/tools/executors/apply-patch.d.ts.map +1 -1
  66. package/dist/extensions/tools/executors/editor.d.ts.map +1 -1
  67. package/dist/extensions/tools/executors/search.d.ts +1 -1
  68. package/dist/extensions/tools/executors/search.d.ts.map +1 -1
  69. package/dist/extensions/tools/helpers.d.ts +1 -0
  70. package/dist/extensions/tools/helpers.d.ts.map +1 -1
  71. package/dist/extensions/tools/index.d.ts +3 -2
  72. package/dist/extensions/tools/index.d.ts.map +1 -1
  73. package/dist/extensions/tools/presets.d.ts +27 -44
  74. package/dist/extensions/tools/presets.d.ts.map +1 -1
  75. package/dist/extensions/tools/runtime.d.ts +25 -0
  76. package/dist/extensions/tools/runtime.d.ts.map +1 -0
  77. package/dist/extensions/tools/schemas.d.ts +25 -3
  78. package/dist/extensions/tools/schemas.d.ts.map +1 -1
  79. package/dist/extensions/tools/team/delegated-agent.d.ts +2 -2
  80. package/dist/extensions/tools/team/delegated-agent.d.ts.map +1 -1
  81. package/dist/extensions/tools/team/multi-agent.d.ts +7 -3
  82. package/dist/extensions/tools/team/multi-agent.d.ts.map +1 -1
  83. package/dist/extensions/tools/team/team-tools.d.ts +1 -0
  84. package/dist/extensions/tools/team/team-tools.d.ts.map +1 -1
  85. package/dist/extensions/tools/types.d.ts +0 -5
  86. package/dist/extensions/tools/types.d.ts.map +1 -1
  87. package/dist/hooks/hook-bridge.d.ts +118 -0
  88. package/dist/hooks/hook-bridge.d.ts.map +1 -0
  89. package/dist/hooks/hook-file-hooks.d.ts +6 -2
  90. package/dist/hooks/hook-file-hooks.d.ts.map +1 -1
  91. package/dist/hooks/hook-registry.d.ts +16 -0
  92. package/dist/hooks/hook-registry.d.ts.map +1 -0
  93. package/dist/hooks/index.d.ts +0 -1
  94. package/dist/hooks/index.d.ts.map +1 -1
  95. package/dist/hooks/subprocess.d.ts +8 -1
  96. package/dist/hooks/subprocess.d.ts.map +1 -1
  97. package/dist/hub/browser-websocket.d.ts +18 -0
  98. package/dist/hub/browser-websocket.d.ts.map +1 -0
  99. package/dist/hub/client.d.ts +51 -0
  100. package/dist/hub/client.d.ts.map +1 -0
  101. package/dist/hub/connect.d.ts +15 -0
  102. package/dist/hub/connect.d.ts.map +1 -0
  103. package/dist/hub/daemon-entry.d.ts +2 -0
  104. package/dist/hub/daemon-entry.d.ts.map +1 -0
  105. package/dist/hub/daemon-entry.js +1305 -0
  106. package/dist/hub/daemon.d.ts +5 -0
  107. package/dist/hub/daemon.d.ts.map +1 -0
  108. package/dist/hub/defaults.d.ts +17 -0
  109. package/dist/hub/defaults.d.ts.map +1 -0
  110. package/dist/hub/discovery.d.ts +29 -0
  111. package/dist/hub/discovery.d.ts.map +1 -0
  112. package/dist/hub/index.d.ts +15 -0
  113. package/dist/hub/index.d.ts.map +1 -0
  114. package/dist/hub/index.js +1294 -0
  115. package/dist/hub/native-transport.d.ts +17 -0
  116. package/dist/hub/native-transport.d.ts.map +1 -0
  117. package/dist/hub/runtime-handlers.d.ts +11 -0
  118. package/dist/hub/runtime-handlers.d.ts.map +1 -0
  119. package/dist/hub/server.d.ts +104 -0
  120. package/dist/hub/server.d.ts.map +1 -0
  121. package/dist/hub/session-client.d.ts +90 -0
  122. package/dist/hub/session-client.d.ts.map +1 -0
  123. package/dist/hub/start-shared-server.d.ts +19 -0
  124. package/dist/hub/start-shared-server.d.ts.map +1 -0
  125. package/dist/hub/transport.d.ts +8 -0
  126. package/dist/hub/transport.d.ts.map +1 -0
  127. package/dist/hub/ui-client.d.ts +45 -0
  128. package/dist/hub/ui-client.d.ts.map +1 -0
  129. package/dist/hub/workspace.d.ts +4 -0
  130. package/dist/hub/workspace.d.ts.map +1 -0
  131. package/dist/index.d.ts +29 -16
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +782 -471
  134. package/dist/llms/cline-recommended-models.d.ts +20 -0
  135. package/dist/llms/cline-recommended-models.d.ts.map +1 -0
  136. package/dist/llms/configured-provider-registry.d.ts +28 -0
  137. package/dist/llms/configured-provider-registry.d.ts.map +1 -0
  138. package/dist/llms/handler-factory.d.ts +16 -0
  139. package/dist/llms/handler-factory.d.ts.map +1 -0
  140. package/dist/llms/provider-defaults.d.ts +27 -0
  141. package/dist/llms/provider-defaults.d.ts.map +1 -0
  142. package/dist/llms/provider-settings.d.ts +245 -0
  143. package/dist/llms/provider-settings.d.ts.map +1 -0
  144. package/dist/llms/runtime-config.d.ts +4 -0
  145. package/dist/llms/runtime-config.d.ts.map +1 -0
  146. package/dist/llms/runtime-registry.d.ts +20 -0
  147. package/dist/llms/runtime-registry.d.ts.map +1 -0
  148. package/dist/llms/runtime-types.d.ts +85 -0
  149. package/dist/llms/runtime-types.d.ts.map +1 -0
  150. package/dist/runtime/agent-config-adapter.d.ts +148 -0
  151. package/dist/runtime/agent-config-adapter.d.ts.map +1 -0
  152. package/dist/runtime/agent-runtime-config-builder.d.ts +96 -0
  153. package/dist/runtime/agent-runtime-config-builder.d.ts.map +1 -0
  154. package/dist/runtime/history.d.ts +6 -0
  155. package/dist/runtime/history.d.ts.map +1 -1
  156. package/dist/runtime/host.d.ts +1 -2
  157. package/dist/runtime/host.d.ts.map +1 -1
  158. package/dist/runtime/loop-detection.d.ts +59 -0
  159. package/dist/runtime/loop-detection.d.ts.map +1 -0
  160. package/dist/runtime/mistake-tracker.d.ts +69 -0
  161. package/dist/runtime/mistake-tracker.d.ts.map +1 -0
  162. package/dist/runtime/rules.d.ts +1 -0
  163. package/dist/runtime/rules.d.ts.map +1 -1
  164. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  165. package/dist/runtime/runtime-event-adapter.d.ts +102 -0
  166. package/dist/runtime/runtime-event-adapter.d.ts.map +1 -0
  167. package/dist/runtime/runtime-host.d.ts +49 -26
  168. package/dist/runtime/runtime-host.d.ts.map +1 -1
  169. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +1 -1
  170. package/dist/runtime/session-runtime-orchestrator.d.ts +261 -0
  171. package/dist/runtime/session-runtime-orchestrator.d.ts.map +1 -0
  172. package/dist/runtime/session-runtime.d.ts +16 -21
  173. package/dist/runtime/session-runtime.d.ts.map +1 -1
  174. package/dist/runtime/user-input-builder.d.ts +24 -0
  175. package/dist/runtime/user-input-builder.d.ts.map +1 -0
  176. package/dist/services/global-settings.d.ts +12 -0
  177. package/dist/services/global-settings.d.ts.map +1 -0
  178. package/dist/services/index.js +28 -0
  179. package/dist/services/local-runtime-bootstrap.d.ts +9 -3
  180. package/dist/services/local-runtime-bootstrap.d.ts.map +1 -1
  181. package/dist/services/plugin-tools.d.ts +16 -0
  182. package/dist/services/plugin-tools.d.ts.map +1 -0
  183. package/dist/services/providers/local-provider-registry.d.ts +199 -23
  184. package/dist/services/providers/local-provider-registry.d.ts.map +1 -1
  185. package/dist/services/providers/local-provider-service.d.ts +15 -13
  186. package/dist/services/providers/local-provider-service.d.ts.map +1 -1
  187. package/dist/services/session-data.d.ts +1 -1
  188. package/dist/services/session-data.d.ts.map +1 -1
  189. package/dist/services/session-telemetry.d.ts +7 -2
  190. package/dist/services/session-telemetry.d.ts.map +1 -1
  191. package/dist/services/storage/file-team-store.d.ts.map +1 -1
  192. package/dist/services/storage/provider-settings-legacy-migration.d.ts +1 -1
  193. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +1 -1
  194. package/dist/services/storage/provider-settings-manager.d.ts +1 -0
  195. package/dist/services/storage/provider-settings-manager.d.ts.map +1 -1
  196. package/dist/services/storage/sqlite-team-store.d.ts.map +1 -1
  197. package/dist/services/workspace-manifest.d.ts +11 -0
  198. package/dist/services/workspace-manifest.d.ts.map +1 -1
  199. package/dist/session/conversation-store.d.ts +30 -0
  200. package/dist/session/conversation-store.d.ts.map +1 -0
  201. package/dist/session/message-builder.d.ts +65 -0
  202. package/dist/session/message-builder.d.ts.map +1 -0
  203. package/dist/session/persistence-service.d.ts +11 -23
  204. package/dist/session/persistence-service.d.ts.map +1 -1
  205. package/dist/session/session-manifest-store.d.ts +22 -0
  206. package/dist/session/session-manifest-store.d.ts.map +1 -0
  207. package/dist/session/session-manifest.d.ts +1 -1
  208. package/dist/session/session-row.d.ts +93 -0
  209. package/dist/session/session-row.d.ts.map +1 -0
  210. package/dist/session/session-service.d.ts +2 -102
  211. package/dist/session/session-service.d.ts.map +1 -1
  212. package/dist/session/subagent-session-manager.d.ts +36 -0
  213. package/dist/session/subagent-session-manager.d.ts.map +1 -0
  214. package/dist/session/team-persistence-store.d.ts +24 -0
  215. package/dist/session/team-persistence-store.d.ts.map +1 -0
  216. package/dist/transports/hub.d.ts +58 -0
  217. package/dist/transports/hub.d.ts.map +1 -0
  218. package/dist/transports/local.d.ts +23 -9
  219. package/dist/transports/local.d.ts.map +1 -1
  220. package/dist/transports/remote.d.ts +10 -0
  221. package/dist/transports/remote.d.ts.map +1 -0
  222. package/dist/transports/runtime-host-support.d.ts +3 -2
  223. package/dist/transports/runtime-host-support.d.ts.map +1 -1
  224. package/dist/types/chat-schema.d.ts +15 -17
  225. package/dist/types/chat-schema.d.ts.map +1 -1
  226. package/dist/types/config.d.ts +17 -7
  227. package/dist/types/config.d.ts.map +1 -1
  228. package/dist/types/events.d.ts +7 -6
  229. package/dist/types/events.d.ts.map +1 -1
  230. package/dist/types/provider-settings.d.ts +4 -5
  231. package/dist/types/provider-settings.d.ts.map +1 -1
  232. package/dist/types/session.d.ts +7 -3
  233. package/dist/types/session.d.ts.map +1 -1
  234. package/dist/types.d.ts +11 -4
  235. package/dist/types.d.ts.map +1 -1
  236. package/package.json +20 -6
  237. package/src/ClineCore.ts +757 -44
  238. package/src/account/cline-account-service.ts +44 -6
  239. package/src/account/index.ts +3 -3
  240. package/src/account/rpc.ts +12 -12
  241. package/src/cron/cron-event-ingress.ts +357 -0
  242. package/src/cron/cron-materializer.ts +97 -0
  243. package/src/cron/cron-reconciler.ts +241 -0
  244. package/src/cron/cron-report-writer.ts +153 -0
  245. package/src/cron/cron-runner.ts +495 -0
  246. package/src/cron/cron-schema.ts +127 -0
  247. package/src/cron/cron-service.ts +163 -0
  248. package/src/cron/cron-spec-parser.ts +489 -0
  249. package/src/cron/cron-watcher.ts +102 -0
  250. package/src/cron/index.ts +15 -0
  251. package/src/cron/resource-limiter.ts +46 -0
  252. package/src/cron/schedule-command-service.ts +193 -0
  253. package/src/cron/schedule-service.ts +703 -0
  254. package/src/cron/scheduler.ts +772 -0
  255. package/src/cron/sqlite-cron-store.ts +1286 -0
  256. package/src/cron/sqlite-schedule-store.ts +708 -0
  257. package/src/extensions/config/agent-config-loader.ts +17 -7
  258. package/src/extensions/config/runtime-commands.ts +6 -0
  259. package/src/extensions/config/user-instruction-config-loader.ts +1 -0
  260. package/src/extensions/context/agentic-compaction.ts +3 -3
  261. package/src/extensions/context/basic-compaction.ts +2 -2
  262. package/src/extensions/context/compaction-shared.ts +5 -4
  263. package/src/extensions/context/compaction.ts +3 -3
  264. package/src/extensions/plugin/plugin-config-loader.ts +37 -2
  265. package/src/extensions/plugin/plugin-loader.ts +69 -9
  266. package/src/extensions/plugin/plugin-module-import.ts +0 -2
  267. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +243 -39
  268. package/src/extensions/plugin/plugin-sandbox.ts +173 -29
  269. package/src/extensions/plugin/plugin-targeting.ts +32 -0
  270. package/src/extensions/tools/constants.ts +2 -0
  271. package/src/extensions/tools/definitions.ts +61 -71
  272. package/src/extensions/tools/executors/apply-patch.ts +69 -80
  273. package/src/extensions/tools/executors/editor.ts +4 -3
  274. package/src/extensions/tools/executors/search.ts +195 -3
  275. package/src/extensions/tools/helpers.ts +24 -0
  276. package/src/extensions/tools/index.ts +11 -2
  277. package/src/extensions/tools/presets.ts +32 -47
  278. package/src/extensions/tools/runtime.ts +261 -0
  279. package/src/extensions/tools/schemas.ts +17 -20
  280. package/src/extensions/tools/team/delegated-agent.ts +8 -3
  281. package/src/extensions/tools/team/multi-agent.ts +135 -19
  282. package/src/extensions/tools/team/team-tools.ts +172 -91
  283. package/src/extensions/tools/types.ts +0 -6
  284. package/src/hooks/hook-bridge.ts +489 -0
  285. package/src/hooks/hook-file-hooks.ts +66 -5
  286. package/src/hooks/hook-registry.ts +257 -0
  287. package/src/hooks/index.ts +0 -7
  288. package/src/hooks/subprocess-runner.ts +1 -1
  289. package/src/hooks/subprocess.ts +9 -0
  290. package/src/hub/browser-websocket.ts +159 -0
  291. package/src/hub/client.ts +633 -0
  292. package/src/hub/connect.ts +156 -0
  293. package/src/hub/daemon-entry.ts +122 -0
  294. package/src/hub/daemon.ts +284 -0
  295. package/src/hub/defaults.ts +70 -0
  296. package/src/hub/discovery.ts +247 -0
  297. package/src/hub/index.ts +14 -0
  298. package/src/hub/native-transport.ts +31 -0
  299. package/src/hub/runtime-handlers.ts +141 -0
  300. package/src/hub/server.ts +2317 -0
  301. package/src/hub/session-client.ts +502 -0
  302. package/src/hub/start-shared-server.ts +61 -0
  303. package/src/hub/transport.ts +14 -0
  304. package/src/hub/ui-client.ts +126 -0
  305. package/src/hub/workspace.ts +19 -0
  306. package/src/index.ts +169 -68
  307. package/src/llms/cline-recommended-models.ts +167 -0
  308. package/src/llms/configured-provider-registry.ts +193 -0
  309. package/src/llms/handler-factory.ts +56 -0
  310. package/src/llms/provider-defaults.ts +653 -0
  311. package/src/llms/provider-settings.ts +310 -0
  312. package/src/llms/runtime-config.ts +43 -0
  313. package/src/llms/runtime-registry.ts +172 -0
  314. package/src/llms/runtime-types.ts +121 -0
  315. package/src/runtime/agent-config-adapter.ts +636 -0
  316. package/src/runtime/agent-runtime-config-builder.ts +205 -0
  317. package/src/runtime/error-feedback.ts +142 -0
  318. package/src/runtime/history.ts +137 -0
  319. package/src/runtime/host.ts +127 -267
  320. package/src/runtime/index.ts +1 -0
  321. package/src/runtime/loop-detection.ts +162 -0
  322. package/src/runtime/mistake-tracker.ts +221 -0
  323. package/src/runtime/rules.ts +12 -0
  324. package/src/runtime/runtime-builder.ts +85 -13
  325. package/src/runtime/runtime-event-adapter.ts +412 -0
  326. package/src/runtime/runtime-host.ts +134 -62
  327. package/src/runtime/runtime-oauth-token-manager.ts +11 -15
  328. package/src/runtime/session-runtime-orchestrator.ts +1253 -0
  329. package/src/runtime/session-runtime.ts +16 -26
  330. package/src/runtime/user-input-builder.ts +167 -0
  331. package/src/services/global-settings.ts +122 -0
  332. package/src/services/local-runtime-bootstrap.ts +175 -31
  333. package/src/services/plugin-tools.ts +86 -0
  334. package/src/services/providers/local-provider-registry.ts +277 -61
  335. package/src/services/providers/local-provider-service.ts +109 -44
  336. package/src/services/session-data.ts +18 -10
  337. package/src/services/session-telemetry.ts +6 -15
  338. package/src/services/storage/file-team-store.ts +1 -5
  339. package/src/services/storage/provider-settings-legacy-migration.ts +14 -51
  340. package/src/services/storage/provider-settings-manager.ts +17 -2
  341. package/src/services/storage/sqlite-team-store.ts +1 -5
  342. package/src/services/workspace-manifest.ts +18 -0
  343. package/src/session/conversation-store.ts +77 -0
  344. package/src/session/file-session-service.ts +1 -1
  345. package/src/session/index.ts +6 -27
  346. package/src/session/message-builder.ts +941 -0
  347. package/src/session/persistence-service.ts +119 -504
  348. package/src/session/session-manifest-store.ts +158 -0
  349. package/src/session/session-row.ts +199 -0
  350. package/src/session/session-service.ts +17 -376
  351. package/src/session/session-team-coordination.ts +1 -1
  352. package/src/session/subagent-session-manager.ts +397 -0
  353. package/src/session/team-persistence-store.ts +176 -0
  354. package/src/transports/hub.ts +1081 -0
  355. package/src/transports/local.ts +419 -93
  356. package/src/transports/remote.ts +27 -0
  357. package/src/transports/runtime-host-support.ts +63 -9
  358. package/src/types/chat-schema.ts +4 -5
  359. package/src/types/config.ts +17 -7
  360. package/src/types/events.ts +8 -6
  361. package/src/types/index.ts +3 -0
  362. package/src/types/provider-settings.ts +18 -7
  363. package/src/types/session.ts +7 -6
  364. package/src/types.ts +42 -2
  365. package/dist/hooks/persistent.d.ts +0 -64
  366. package/dist/hooks/persistent.d.ts.map +0 -1
  367. package/dist/runtime/rpc-runtime-ensure.d.ts +0 -65
  368. package/dist/runtime/rpc-runtime-ensure.d.ts.map +0 -1
  369. package/dist/runtime/rpc-spawn-lease.d.ts +0 -8
  370. package/dist/runtime/rpc-spawn-lease.d.ts.map +0 -1
  371. package/dist/services/telemetry/index.js +0 -15
  372. package/dist/session/rpc-session-service.d.ts +0 -16
  373. package/dist/session/rpc-session-service.d.ts.map +0 -1
  374. package/dist/session/sqlite-rpc-session-backend.d.ts +0 -31
  375. package/dist/session/sqlite-rpc-session-backend.d.ts.map +0 -1
  376. package/dist/transports/rpc.d.ts +0 -51
  377. package/dist/transports/rpc.d.ts.map +0 -1
  378. package/src/ClineCore.test.ts +0 -226
  379. package/src/account/cline-account-service.test.ts +0 -185
  380. package/src/account/featurebase-token.test.ts +0 -175
  381. package/src/account/rpc.test.ts +0 -63
  382. package/src/auth/bounded-ttl-cache.test.ts +0 -38
  383. package/src/auth/client.test.ts +0 -69
  384. package/src/auth/cline.test.ts +0 -267
  385. package/src/auth/codex.test.ts +0 -170
  386. package/src/auth/oca.test.ts +0 -340
  387. package/src/auth/server.test.ts +0 -287
  388. package/src/auth/utils.test.ts +0 -128
  389. package/src/extensions/config/agent-config-loader.test.ts +0 -236
  390. package/src/extensions/config/hooks-config-loader.test.ts +0 -20
  391. package/src/extensions/config/runtime-commands.test.ts +0 -115
  392. package/src/extensions/config/unified-config-file-watcher.test.ts +0 -196
  393. package/src/extensions/config/user-instruction-config-loader.test.ts +0 -246
  394. package/src/extensions/context/compaction.test.ts +0 -483
  395. package/src/extensions/mcp/config-loader.test.ts +0 -238
  396. package/src/extensions/mcp/manager.test.ts +0 -105
  397. package/src/extensions/plugin/plugin-config-loader.test.ts +0 -184
  398. package/src/extensions/plugin/plugin-loader.test.ts +0 -292
  399. package/src/extensions/plugin/plugin-sandbox.test.ts +0 -423
  400. package/src/extensions/tools/definitions.test.ts +0 -780
  401. package/src/extensions/tools/executors/bash.test.ts +0 -87
  402. package/src/extensions/tools/executors/editor.test.ts +0 -35
  403. package/src/extensions/tools/executors/file-read.test.ts +0 -125
  404. package/src/extensions/tools/model-tool-routing.test.ts +0 -86
  405. package/src/extensions/tools/presets.test.ts +0 -70
  406. package/src/extensions/tools/team/multi-agent.lifecycle.test.ts +0 -455
  407. package/src/extensions/tools/team/spawn-agent-tool.test.ts +0 -381
  408. package/src/extensions/tools/team/team-tools.test.ts +0 -918
  409. package/src/hooks/checkpoint-hooks.test.ts +0 -168
  410. package/src/hooks/hook-file-hooks.test.ts +0 -311
  411. package/src/hooks/persistent.ts +0 -661
  412. package/src/runtime/history.test.ts +0 -114
  413. package/src/runtime/host.test.ts +0 -230
  414. package/src/runtime/rpc-runtime-ensure.test.ts +0 -123
  415. package/src/runtime/rpc-runtime-ensure.ts +0 -659
  416. package/src/runtime/rpc-spawn-lease.test.ts +0 -81
  417. package/src/runtime/rpc-spawn-lease.ts +0 -156
  418. package/src/runtime/runtime-builder.team-persistence.test.ts +0 -245
  419. package/src/runtime/runtime-builder.test.ts +0 -615
  420. package/src/runtime/runtime-oauth-token-manager.test.ts +0 -137
  421. package/src/runtime/runtime-parity.test.ts +0 -143
  422. package/src/services/providers/local-provider-service.test.ts +0 -1062
  423. package/src/services/session-data.test.ts +0 -160
  424. package/src/services/storage/provider-settings-legacy-migration.test.ts +0 -424
  425. package/src/services/storage/provider-settings-manager.test.ts +0 -191
  426. package/src/services/telemetry/OpenTelemetryAdapter.test.ts +0 -157
  427. package/src/services/telemetry/OpenTelemetryProvider.test.ts +0 -326
  428. package/src/services/telemetry/TelemetryLoggerSink.test.ts +0 -42
  429. package/src/services/telemetry/TelemetryService.test.ts +0 -134
  430. package/src/services/telemetry/distinct-id.test.ts +0 -57
  431. package/src/services/workspace/file-indexer.d.ts +0 -11
  432. package/src/services/workspace/file-indexer.test.ts +0 -156
  433. package/src/services/workspace/mention-enricher.test.ts +0 -106
  434. package/src/session/persistence-service.test.ts +0 -300
  435. package/src/session/rpc-session-service.ts +0 -114
  436. package/src/session/session-service.team-persistence.test.ts +0 -48
  437. package/src/session/sqlite-rpc-session-backend.ts +0 -301
  438. package/src/transports/local.e2e.test.ts +0 -380
  439. package/src/transports/local.test.ts +0 -2559
  440. package/src/transports/rpc.test.ts +0 -82
  441. package/src/transports/rpc.ts +0 -665
@@ -0,0 +1,163 @@
1
+ import type { AutomationEventEnvelope, BasicLogger } from "@clinebot/shared";
2
+ import type { ResolveCronSpecsDirOptions } from "@clinebot/shared/storage";
3
+ import {
4
+ CronEventIngress,
5
+ type CronEventIngressResult,
6
+ } from "./cron-event-ingress";
7
+ import { CronMaterializer } from "./cron-materializer";
8
+ import { CronReconciler } from "./cron-reconciler";
9
+ import { CronRunner } from "./cron-runner";
10
+ import { CronWatcher } from "./cron-watcher";
11
+ import type { HubScheduleRuntimeHandlers } from "./schedule-service";
12
+ import type {
13
+ CronRunRecord,
14
+ CronSpecRecord,
15
+ ListEventLogsOptions,
16
+ ListRunsOptions,
17
+ ListSpecsOptions,
18
+ } from "./sqlite-cron-store";
19
+ import { SqliteCronStore } from "./sqlite-cron-store";
20
+
21
+ /**
22
+ * Top-level orchestrator for file-based cron automation.
23
+ *
24
+ * Wires together:
25
+ * - `SqliteCronStore` (cron.db)
26
+ * - `CronReconciler` (disk -> DB)
27
+ * - `CronWatcher` (cron specs directory filesystem events)
28
+ * - `CronMaterializer` (queue materialization)
29
+ * - `CronRunner` (claim + execute + report)
30
+ *
31
+ * This service is the forward path: the legacy `HubScheduleService`
32
+ * continues to serve programmatic schedules, while `CronService` handles
33
+ * everything sourced from the configured file-based cron directory.
34
+ */
35
+
36
+ export interface CronServiceOptions {
37
+ /** Default runtime workspace for the hub/daemon process. */
38
+ workspaceRoot: string;
39
+ /** Cron spec source/report location. Defaults to global `~/.cline/cron`. */
40
+ specs?: ResolveCronSpecsDirOptions;
41
+ runtimeHandlers: HubScheduleRuntimeHandlers;
42
+ dbPath?: string;
43
+ logger?: BasicLogger;
44
+ pollIntervalMs?: number;
45
+ claimLeaseSeconds?: number;
46
+ globalMaxConcurrency?: number;
47
+ watcherDebounceMs?: number;
48
+ }
49
+
50
+ export class CronService {
51
+ private readonly store: SqliteCronStore;
52
+ private readonly reconciler: CronReconciler;
53
+ private readonly watcher: CronWatcher;
54
+ private readonly eventIngress: CronEventIngress;
55
+ private readonly materializer: CronMaterializer;
56
+ private readonly runner: CronRunner;
57
+ private started = false;
58
+ private disposed = false;
59
+
60
+ constructor(options: CronServiceOptions) {
61
+ this.store = new SqliteCronStore({ dbPath: options.dbPath });
62
+ const specs = options.specs;
63
+ this.reconciler = new CronReconciler({
64
+ store: this.store,
65
+ specs,
66
+ });
67
+ this.materializer = new CronMaterializer({ store: this.store });
68
+ this.eventIngress = new CronEventIngress({
69
+ store: this.store,
70
+ logger: options.logger,
71
+ });
72
+ this.runner = new CronRunner({
73
+ store: this.store,
74
+ materializer: this.materializer,
75
+ runtimeHandlers: options.runtimeHandlers,
76
+ workspaceRoot: options.workspaceRoot,
77
+ specs,
78
+ logger: options.logger,
79
+ pollIntervalMs: options.pollIntervalMs,
80
+ claimLeaseSeconds: options.claimLeaseSeconds,
81
+ globalMaxConcurrency: options.globalMaxConcurrency,
82
+ });
83
+ this.watcher = new CronWatcher({
84
+ reconciler: this.reconciler,
85
+ debounceMs: options.watcherDebounceMs,
86
+ onReconciled: () => {
87
+ this.materializer.materializeAll();
88
+ },
89
+ onError: (err) => {
90
+ const log = options.logger;
91
+ if (log) {
92
+ if (log.error) log.error("cron.watcher.failed", { error: err });
93
+ else log.log("cron.watcher.failed", { error: err });
94
+ }
95
+ },
96
+ });
97
+ }
98
+
99
+ public async start(): Promise<void> {
100
+ if (this.disposed) throw new Error("CronService disposed");
101
+ if (this.started) return;
102
+ this.started = true;
103
+ await this.reconciler.reconcileAll();
104
+ this.materializer.materializeAll();
105
+ this.watcher.start();
106
+ await this.runner.start();
107
+ }
108
+
109
+ public async stop(): Promise<void> {
110
+ this.watcher.stop();
111
+ await this.runner.stop();
112
+ this.started = false;
113
+ }
114
+
115
+ public async dispose(): Promise<void> {
116
+ if (this.disposed) return;
117
+ this.disposed = true;
118
+ this.watcher.dispose();
119
+ await this.runner.dispose();
120
+ this.store.close();
121
+ }
122
+
123
+ public listSpecs(options?: ListSpecsOptions): CronSpecRecord[] {
124
+ return this.store.listSpecs(options);
125
+ }
126
+
127
+ public getSpec(specId: string): CronSpecRecord | undefined {
128
+ return this.store.getSpec(specId);
129
+ }
130
+
131
+ public listRuns(options?: ListRunsOptions): CronRunRecord[] {
132
+ return this.store.listRuns(options);
133
+ }
134
+
135
+ public getRun(runId: string): CronRunRecord | undefined {
136
+ return this.store.getRun(runId);
137
+ }
138
+
139
+ public listActiveRuns(): CronRunRecord[] {
140
+ return this.store.listRuns({ status: "running", limit: 200 });
141
+ }
142
+
143
+ public listUpcomingRuns(limit = 20): CronRunRecord[] {
144
+ return this.store.listRuns({ status: "queued", limit });
145
+ }
146
+
147
+ public async reconcileNow(): Promise<void> {
148
+ await this.reconciler.reconcileAll();
149
+ this.materializer.materializeAll();
150
+ }
151
+
152
+ public ingestEvent(event: AutomationEventEnvelope): CronEventIngressResult {
153
+ return this.eventIngress.ingestEvent(event);
154
+ }
155
+
156
+ public listEventLogs(options?: ListEventLogsOptions) {
157
+ return this.store.listEventLogs(options);
158
+ }
159
+
160
+ public getEventLog(eventId: string) {
161
+ return this.store.getEventLog(eventId);
162
+ }
163
+ }
@@ -0,0 +1,489 @@
1
+ import { createHash } from "node:crypto";
2
+ import type {
3
+ CronEventSpec,
4
+ CronOneOffSpec,
5
+ CronScheduleSpec,
6
+ CronSpec,
7
+ CronSpecExtensionKind,
8
+ CronSpecMode,
9
+ CronSpecParseResult,
10
+ CronTriggerKind,
11
+ } from "@clinebot/shared";
12
+ import YAML from "yaml";
13
+ import { ALL_DEFAULT_TOOL_NAMES } from "../extensions/tools/constants";
14
+ import { validateCronSchedule } from "./scheduler";
15
+
16
+ /**
17
+ * Markdown frontmatter parser for `.cline/cron/*.md` automation specs.
18
+ *
19
+ * Lives in @clinebot/core because it depends on `yaml`. The spec types
20
+ * themselves live in @clinebot/shared so other packages can consume them
21
+ * without pulling in a YAML parser.
22
+ *
23
+ * The parser never throws for a single bad file — it produces a
24
+ * `CronSpecParseResult` with an `error` message so the reconciler can record
25
+ * `parse_status='invalid'` durably instead of dropping state.
26
+ */
27
+
28
+ export function inferTriggerKindFromPath(
29
+ relativePath: string,
30
+ ): CronTriggerKind {
31
+ const normalized = relativePath.replace(/\\/g, "/");
32
+ if (normalized.startsWith("events/") && normalized.endsWith(".event.md")) {
33
+ return "event";
34
+ }
35
+ if (normalized.endsWith(".cron.md")) {
36
+ return "schedule";
37
+ }
38
+ return "one_off";
39
+ }
40
+
41
+ export function splitFrontmatter(raw: string): {
42
+ frontmatter: string | undefined;
43
+ body: string;
44
+ } {
45
+ const text = raw.replace(/\r\n/g, "\n");
46
+ if (!text.startsWith("---\n")) {
47
+ return { frontmatter: undefined, body: raw };
48
+ }
49
+ const afterOpen = text.slice(4);
50
+ const closeIdx = afterOpen.indexOf("\n---");
51
+ if (closeIdx === -1) {
52
+ return { frontmatter: undefined, body: raw };
53
+ }
54
+ const frontmatter = afterOpen.slice(0, closeIdx);
55
+ let rest = afterOpen.slice(closeIdx + 4);
56
+ if (rest.startsWith("\n")) rest = rest.slice(1);
57
+ return { frontmatter, body: rest };
58
+ }
59
+
60
+ function trimOrUndefined(value: unknown): string | undefined {
61
+ if (typeof value !== "string") return undefined;
62
+ const trimmed = value.trim();
63
+ return trimmed.length > 0 ? trimmed : undefined;
64
+ }
65
+
66
+ function normalizeTags(value: unknown): string[] | undefined {
67
+ if (!Array.isArray(value)) return undefined;
68
+ const tags = value
69
+ .map((item) => (typeof item === "string" ? item.trim() : ""))
70
+ .filter((item) => item.length > 0);
71
+ return tags.length > 0 ? tags : undefined;
72
+ }
73
+
74
+ function normalizeRecord(value: unknown): Record<string, unknown> | undefined {
75
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
76
+ return undefined;
77
+ }
78
+ return value as Record<string, unknown>;
79
+ }
80
+
81
+ function normalizeModelSelection(
82
+ value: unknown,
83
+ ): { providerId?: string; modelId?: string } | undefined {
84
+ const obj = normalizeRecord(value);
85
+ if (!obj) return undefined;
86
+ const providerId = trimOrUndefined(obj.providerId);
87
+ const modelId = trimOrUndefined(obj.modelId);
88
+ if (providerId === undefined && modelId === undefined) return undefined;
89
+ return { providerId, modelId };
90
+ }
91
+
92
+ function normalizeMode(value: unknown): CronSpecMode | undefined {
93
+ if (typeof value !== "string") return undefined;
94
+ const lower = value.trim().toLowerCase();
95
+ if (lower === "act" || lower === "plan" || lower === "yolo") return lower;
96
+ return undefined;
97
+ }
98
+
99
+ function normalizeStringList(
100
+ value: unknown,
101
+ options: { preserveEmptyArray?: boolean } = {},
102
+ ): string[] | undefined {
103
+ const raw = Array.isArray(value)
104
+ ? value
105
+ : typeof value === "string"
106
+ ? value.split(",")
107
+ : undefined;
108
+ if (!raw) return undefined;
109
+ const normalized = [
110
+ ...new Set(
111
+ raw
112
+ .map((item) => (typeof item === "string" ? item.trim() : ""))
113
+ .filter((item) => item.length > 0),
114
+ ),
115
+ ];
116
+ if (Array.isArray(value) && options.preserveEmptyArray) {
117
+ return normalized;
118
+ }
119
+ return normalized.length > 0 ? normalized : undefined;
120
+ }
121
+
122
+ const DEFAULT_TOOL_NAME_SET = new Set<string>(ALL_DEFAULT_TOOL_NAMES);
123
+
124
+ function normalizeToolList(value: unknown): string[] | undefined {
125
+ const tools = normalizeStringList(value, { preserveEmptyArray: true });
126
+ if (!tools) return undefined;
127
+ const invalid = tools.filter((tool) => !DEFAULT_TOOL_NAME_SET.has(tool));
128
+ if (invalid.length > 0) {
129
+ throw new Error(`unknown tool(s): ${invalid.join(", ")}`);
130
+ }
131
+ return tools;
132
+ }
133
+
134
+ const CRON_EXTENSION_KINDS = new Set<CronSpecExtensionKind>([
135
+ "rules",
136
+ "skills",
137
+ "plugins",
138
+ ]);
139
+
140
+ function normalizeExtensions(
141
+ value: unknown,
142
+ ): CronSpecExtensionKind[] | undefined {
143
+ const extensions = normalizeStringList(value, { preserveEmptyArray: true });
144
+ if (!extensions) return undefined;
145
+ const invalid = extensions.filter(
146
+ (extension) =>
147
+ !CRON_EXTENSION_KINDS.has(extension as CronSpecExtensionKind),
148
+ );
149
+ if (invalid.length > 0) {
150
+ throw new Error(`unknown extension(s): ${invalid.join(", ")}`);
151
+ }
152
+ return extensions as CronSpecExtensionKind[];
153
+ }
154
+
155
+ function asPositiveInt(value: unknown): number | undefined {
156
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
157
+ return undefined;
158
+ }
159
+ return Math.floor(value);
160
+ }
161
+
162
+ function asNonNegativeInt(value: unknown): number | undefined {
163
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
164
+ return undefined;
165
+ }
166
+ return Math.floor(value);
167
+ }
168
+
169
+ function stableStringify(value: unknown): string {
170
+ if (value === null || typeof value !== "object") {
171
+ return JSON.stringify(value ?? null);
172
+ }
173
+ if (Array.isArray(value)) {
174
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
175
+ }
176
+ const entries = Object.entries(value as Record<string, unknown>).filter(
177
+ ([, v]) => v !== undefined,
178
+ );
179
+ entries.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
180
+ return `{${entries
181
+ .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)
182
+ .join(",")}}`;
183
+ }
184
+
185
+ export function computeContentHash(
186
+ frontmatterJson: unknown,
187
+ body: string,
188
+ ): string {
189
+ const hash = createHash("sha256");
190
+ hash.update(stableStringify(frontmatterJson));
191
+ hash.update("\n");
192
+ hash.update(body);
193
+ return hash.digest("hex");
194
+ }
195
+
196
+ function filenameStem(relativePath: string): string {
197
+ const base = relativePath.split("/").pop() ?? relativePath;
198
+ return base
199
+ .replace(/\.event\.md$/, "")
200
+ .replace(/\.cron\.md$/, "")
201
+ .replace(/\.md$/, "");
202
+ }
203
+
204
+ const SCHEDULE_ONLY_FIELDS = ["schedule", "timezone"] as const;
205
+ const EVENT_ONLY_FIELDS = [
206
+ "event",
207
+ "filters",
208
+ "debounceSeconds",
209
+ "dedupeWindowSeconds",
210
+ "cooldownSeconds",
211
+ "maxParallel",
212
+ ] as const;
213
+ const REMOVED_FIELDS = ["cwd"] as const;
214
+
215
+ export interface ParseCronSpecInput {
216
+ relativePath: string;
217
+ raw: string;
218
+ }
219
+
220
+ function invalid(
221
+ relativePath: string,
222
+ triggerKind: CronTriggerKind,
223
+ body: string,
224
+ frontmatter: Record<string, unknown>,
225
+ error: string,
226
+ ): CronSpecParseResult {
227
+ return {
228
+ externalId: relativePath,
229
+ relativePath,
230
+ triggerKind,
231
+ body,
232
+ contentHash: computeContentHash(frontmatter, body),
233
+ error,
234
+ };
235
+ }
236
+
237
+ function invalidWithHash(
238
+ externalId: string,
239
+ relativePath: string,
240
+ triggerKind: CronTriggerKind,
241
+ body: string,
242
+ contentHash: string,
243
+ error: string,
244
+ ): CronSpecParseResult {
245
+ return {
246
+ externalId,
247
+ relativePath,
248
+ triggerKind,
249
+ body,
250
+ contentHash,
251
+ error,
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Parse a single cron spec file. Never throws; always returns a result.
257
+ */
258
+ export function parseCronSpecFile(
259
+ input: ParseCronSpecInput,
260
+ ): CronSpecParseResult {
261
+ const relativePath = input.relativePath.replace(/\\/g, "/");
262
+ const triggerKind = inferTriggerKindFromPath(relativePath);
263
+ const { frontmatter, body } = splitFrontmatter(input.raw);
264
+
265
+ let frontmatterData: Record<string, unknown> = {};
266
+ if (frontmatter !== undefined && frontmatter.trim().length > 0) {
267
+ try {
268
+ const parsed = YAML.parse(frontmatter) as unknown;
269
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
270
+ frontmatterData = parsed as Record<string, unknown>;
271
+ } else if (parsed !== null && parsed !== undefined) {
272
+ return invalid(
273
+ relativePath,
274
+ triggerKind,
275
+ body,
276
+ {},
277
+ "frontmatter must be a YAML mapping",
278
+ );
279
+ }
280
+ } catch (err) {
281
+ return invalid(
282
+ relativePath,
283
+ triggerKind,
284
+ body,
285
+ {},
286
+ err instanceof Error
287
+ ? `failed to parse frontmatter: ${err.message}`
288
+ : "failed to parse frontmatter",
289
+ );
290
+ }
291
+ }
292
+
293
+ const contentHash = computeContentHash(frontmatterData, body);
294
+ const externalIdRaw = trimOrUndefined(frontmatterData.id);
295
+ const externalId = externalIdRaw ?? relativePath;
296
+
297
+ if (triggerKind !== "schedule") {
298
+ for (const key of SCHEDULE_ONLY_FIELDS) {
299
+ if (frontmatterData[key] !== undefined) {
300
+ return invalidWithHash(
301
+ externalId,
302
+ relativePath,
303
+ triggerKind,
304
+ body,
305
+ contentHash,
306
+ `field "${key}" is only allowed on *.cron.md specs`,
307
+ );
308
+ }
309
+ }
310
+ }
311
+ for (const key of REMOVED_FIELDS) {
312
+ if (frontmatterData[key] !== undefined) {
313
+ return invalidWithHash(
314
+ externalId,
315
+ relativePath,
316
+ triggerKind,
317
+ body,
318
+ contentHash,
319
+ `field "${key}" is no longer supported; cron specs use workspaceRoot as cwd`,
320
+ );
321
+ }
322
+ }
323
+ if (triggerKind !== "event") {
324
+ for (const key of EVENT_ONLY_FIELDS) {
325
+ if (frontmatterData[key] !== undefined) {
326
+ return invalidWithHash(
327
+ externalId,
328
+ relativePath,
329
+ triggerKind,
330
+ body,
331
+ contentHash,
332
+ `field "${key}" is only allowed on .event.md specs`,
333
+ );
334
+ }
335
+ }
336
+ }
337
+
338
+ const frontmatterPrompt = trimOrUndefined(frontmatterData.prompt);
339
+ const bodyTrimmed = body.trim();
340
+ const prompt =
341
+ frontmatterPrompt ?? (bodyTrimmed.length > 0 ? bodyTrimmed : undefined);
342
+ if (!prompt) {
343
+ return invalidWithHash(
344
+ externalId,
345
+ relativePath,
346
+ triggerKind,
347
+ body,
348
+ contentHash,
349
+ "prompt is required (frontmatter `prompt` or markdown body)",
350
+ );
351
+ }
352
+
353
+ const workspaceRoot = trimOrUndefined(frontmatterData.workspaceRoot);
354
+ if (!workspaceRoot) {
355
+ return invalidWithHash(
356
+ externalId,
357
+ relativePath,
358
+ triggerKind,
359
+ body,
360
+ contentHash,
361
+ "workspaceRoot is required",
362
+ );
363
+ }
364
+
365
+ let tools: string[] | undefined;
366
+ let extensions: CronSpecExtensionKind[] | undefined;
367
+ try {
368
+ tools = normalizeToolList(frontmatterData.tools);
369
+ extensions = normalizeExtensions(frontmatterData.extensions);
370
+ } catch (err) {
371
+ return invalidWithHash(
372
+ externalId,
373
+ relativePath,
374
+ triggerKind,
375
+ body,
376
+ contentHash,
377
+ err instanceof Error ? err.message : String(err),
378
+ );
379
+ }
380
+
381
+ const mode = normalizeMode(frontmatterData.mode);
382
+ if (frontmatterData.mode !== undefined && mode === undefined) {
383
+ return invalidWithHash(
384
+ externalId,
385
+ relativePath,
386
+ triggerKind,
387
+ body,
388
+ contentHash,
389
+ "mode must be one of: act, plan, yolo",
390
+ );
391
+ }
392
+
393
+ const common = {
394
+ id: externalIdRaw,
395
+ title:
396
+ trimOrUndefined(frontmatterData.title) ??
397
+ externalIdRaw ??
398
+ filenameStem(relativePath),
399
+ prompt,
400
+ workspaceRoot,
401
+ mode: mode ?? "yolo",
402
+ systemPrompt: trimOrUndefined(frontmatterData.systemPrompt),
403
+ modelSelection: normalizeModelSelection(frontmatterData.modelSelection),
404
+ maxIterations: asPositiveInt(frontmatterData.maxIterations),
405
+ timeoutSeconds: asPositiveInt(frontmatterData.timeoutSeconds),
406
+ tools,
407
+ notesDirectory: trimOrUndefined(frontmatterData.notesDirectory),
408
+ extensions,
409
+ source: trimOrUndefined(frontmatterData.source) ?? "user",
410
+ tags: normalizeTags(frontmatterData.tags),
411
+ enabled:
412
+ typeof frontmatterData.enabled === "boolean"
413
+ ? frontmatterData.enabled
414
+ : true,
415
+ metadata: normalizeRecord(frontmatterData.metadata),
416
+ };
417
+
418
+ let spec: CronSpec;
419
+ if (triggerKind === "schedule") {
420
+ const schedule = trimOrUndefined(frontmatterData.schedule);
421
+ if (!schedule) {
422
+ return invalidWithHash(
423
+ externalId,
424
+ relativePath,
425
+ triggerKind,
426
+ body,
427
+ contentHash,
428
+ "schedule is required for *.cron.md specs",
429
+ );
430
+ }
431
+ const timezone = trimOrUndefined(frontmatterData.timezone);
432
+ try {
433
+ validateCronSchedule(schedule, timezone);
434
+ } catch (err) {
435
+ return invalidWithHash(
436
+ externalId,
437
+ relativePath,
438
+ triggerKind,
439
+ body,
440
+ contentHash,
441
+ err instanceof Error ? err.message : String(err),
442
+ );
443
+ }
444
+ const s: CronScheduleSpec = {
445
+ ...common,
446
+ triggerKind: "schedule",
447
+ schedule,
448
+ timezone,
449
+ };
450
+ spec = s;
451
+ } else if (triggerKind === "event") {
452
+ const event = trimOrUndefined(frontmatterData.event);
453
+ if (!event) {
454
+ return invalidWithHash(
455
+ externalId,
456
+ relativePath,
457
+ triggerKind,
458
+ body,
459
+ contentHash,
460
+ "event is required for .event.md specs",
461
+ );
462
+ }
463
+ const e: CronEventSpec = {
464
+ ...common,
465
+ triggerKind: "event",
466
+ event,
467
+ filters: normalizeRecord(frontmatterData.filters),
468
+ debounceSeconds: asNonNegativeInt(frontmatterData.debounceSeconds),
469
+ dedupeWindowSeconds: asNonNegativeInt(
470
+ frontmatterData.dedupeWindowSeconds,
471
+ ),
472
+ cooldownSeconds: asNonNegativeInt(frontmatterData.cooldownSeconds),
473
+ maxParallel: asPositiveInt(frontmatterData.maxParallel),
474
+ };
475
+ spec = e;
476
+ } else {
477
+ const o: CronOneOffSpec = { ...common, triggerKind: "one_off" };
478
+ spec = o;
479
+ }
480
+
481
+ return {
482
+ externalId,
483
+ relativePath,
484
+ triggerKind,
485
+ body,
486
+ contentHash,
487
+ spec,
488
+ };
489
+ }