@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,708 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { join } from "node:path";
3
+ import type {
4
+ HubScheduleCreateInput,
5
+ HubScheduleUpdateInput,
6
+ ScheduleExecutionRecord,
7
+ ScheduleExecutionStatus,
8
+ ScheduleRecord,
9
+ } from "@clinebot/shared";
10
+ import {
11
+ asOptionalString,
12
+ asString,
13
+ ensureSessionSchema,
14
+ loadSqliteDb,
15
+ nowIso,
16
+ type SqliteDb,
17
+ } from "@clinebot/shared/db";
18
+ import { resolveDbDataDir } from "@clinebot/shared/storage";
19
+ import { getNextCronTime } from "./scheduler";
20
+
21
+ function defaultSessionsDbPath(): string {
22
+ return join(resolveDbDataDir(), "sessions.db");
23
+ }
24
+
25
+ function parseJsonObject(
26
+ value: string | undefined,
27
+ ): Record<string, unknown> | undefined {
28
+ if (!value) {
29
+ return undefined;
30
+ }
31
+ try {
32
+ const parsed = JSON.parse(value) as unknown;
33
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
34
+ return parsed as Record<string, unknown>;
35
+ }
36
+ } catch {
37
+ // Ignore malformed persisted JSON.
38
+ }
39
+ return undefined;
40
+ }
41
+
42
+ function parseJsonArray(value: string | undefined): string[] | undefined {
43
+ if (!value) {
44
+ return undefined;
45
+ }
46
+ try {
47
+ const parsed = JSON.parse(value) as unknown;
48
+ if (!Array.isArray(parsed)) {
49
+ return undefined;
50
+ }
51
+ const tags = parsed
52
+ .map((item) => (typeof item === "string" ? item.trim() : ""))
53
+ .filter((item) => item.length > 0);
54
+ return tags.length > 0 ? tags : undefined;
55
+ } catch {
56
+ return undefined;
57
+ }
58
+ }
59
+
60
+ function normalizeExecutionStatus(
61
+ value: string | undefined,
62
+ ): ScheduleExecutionStatus {
63
+ if (
64
+ value === "pending" ||
65
+ value === "running" ||
66
+ value === "success" ||
67
+ value === "completed" ||
68
+ value === "failed" ||
69
+ value === "timeout" ||
70
+ value === "aborted"
71
+ ) {
72
+ return value;
73
+ }
74
+ return "failed";
75
+ }
76
+
77
+ export interface HubScheduleStoreOptions {
78
+ sessionsDbPath?: string;
79
+ }
80
+
81
+ export interface ScheduleClaimRecord {
82
+ schedule: ScheduleRecord;
83
+ claimToken: string;
84
+ triggeredAt: number;
85
+ leaseUntilAt: number;
86
+ }
87
+
88
+ export interface ListSchedulesOptions {
89
+ enabled?: boolean;
90
+ limit?: number;
91
+ tags?: string[];
92
+ }
93
+
94
+ export interface ListScheduleExecutionsOptions {
95
+ scheduleId?: string;
96
+ status?: ScheduleExecutionStatus;
97
+ limit?: number;
98
+ }
99
+
100
+ export interface ScheduleExecutionStats {
101
+ totalRuns: number;
102
+ successRate: number;
103
+ avgDurationSeconds: number;
104
+ lastFailure?: ScheduleExecutionRecord;
105
+ }
106
+
107
+ export class SqliteHubScheduleStore {
108
+ private readonly db: SqliteDb;
109
+
110
+ constructor(options: HubScheduleStoreOptions = {}) {
111
+ const path = options.sessionsDbPath ?? defaultSessionsDbPath();
112
+ this.db = loadSqliteDb(path);
113
+ ensureSessionSchema(this.db, { includeLegacyMigrations: true });
114
+ }
115
+
116
+ public close(): void {
117
+ this.db.close?.();
118
+ }
119
+
120
+ public createSchedule(input: HubScheduleCreateInput): ScheduleRecord {
121
+ const now = nowIso();
122
+ const scheduleId = `sched_${randomUUID()}`;
123
+ const cronPattern = input.cronPattern.trim();
124
+ const nextRunAt =
125
+ input.enabled === false
126
+ ? undefined
127
+ : getNextCronTime(cronPattern, Date.now());
128
+ const record: ScheduleRecord = {
129
+ scheduleId,
130
+ name: input.name.trim(),
131
+ cronPattern,
132
+ prompt: input.prompt,
133
+ workspaceRoot: input.workspaceRoot.trim(),
134
+ cwd: input.cwd?.trim() || undefined,
135
+ modelSelection: input.modelSelection
136
+ ? JSON.parse(JSON.stringify(input.modelSelection))
137
+ : undefined,
138
+ enabled: input.enabled !== false,
139
+ mode: input.mode ?? "act",
140
+ systemPrompt: input.systemPrompt,
141
+ maxIterations:
142
+ typeof input.maxIterations === "number"
143
+ ? Math.floor(input.maxIterations)
144
+ : undefined,
145
+ timeoutSeconds:
146
+ typeof input.timeoutSeconds === "number"
147
+ ? Math.floor(input.timeoutSeconds)
148
+ : undefined,
149
+ maxParallel:
150
+ typeof input.maxParallel === "number"
151
+ ? Math.max(1, Math.floor(input.maxParallel))
152
+ : 1,
153
+ createdAt: new Date(now).getTime(),
154
+ updatedAt: new Date(now).getTime(),
155
+ lastRunAt: undefined,
156
+ nextRunAt,
157
+ createdBy: input.createdBy?.trim() || undefined,
158
+ tags: input.tags?.filter((tag) => tag.trim().length > 0),
159
+ runtimeOptions: input.runtimeOptions
160
+ ? JSON.parse(JSON.stringify(input.runtimeOptions))
161
+ : undefined,
162
+ metadata: input.metadata
163
+ ? JSON.parse(JSON.stringify(input.metadata))
164
+ : undefined,
165
+ };
166
+ this.db
167
+ .prepare(
168
+ `INSERT INTO schedules (
169
+ schedule_id, name, cron_pattern, prompt,
170
+ provider, model, mode, workspace_root, cwd, system_prompt,
171
+ max_iterations, timeout_seconds, max_parallel,
172
+ enabled, created_at, updated_at, last_run_at, next_run_at,
173
+ claim_token, claim_started_at, claim_until_at,
174
+ created_by, tags, metadata_json
175
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
176
+ )
177
+ .run(
178
+ record.scheduleId,
179
+ record.name,
180
+ record.cronPattern,
181
+ record.prompt,
182
+ record.modelSelection?.providerId ?? "",
183
+ record.modelSelection?.modelId ?? "",
184
+ record.mode ?? "act",
185
+ record.workspaceRoot,
186
+ record.cwd ?? null,
187
+ record.systemPrompt ?? null,
188
+ record.maxIterations ?? null,
189
+ record.timeoutSeconds ?? null,
190
+ record.maxParallel ?? 1,
191
+ record.enabled ? 1 : 0,
192
+ now,
193
+ now,
194
+ null,
195
+ record.nextRunAt ? new Date(record.nextRunAt).toISOString() : null,
196
+ null,
197
+ null,
198
+ null,
199
+ record.createdBy ?? null,
200
+ record.tags ? JSON.stringify(record.tags) : null,
201
+ JSON.stringify({
202
+ ...(record.metadata ?? {}),
203
+ ...(record.runtimeOptions
204
+ ? { __hubRuntimeOptions: record.runtimeOptions }
205
+ : {}),
206
+ }),
207
+ );
208
+ return record;
209
+ }
210
+
211
+ public getSchedule(scheduleId: string): ScheduleRecord | undefined {
212
+ const row = this.db
213
+ .prepare("SELECT * FROM schedules WHERE schedule_id = ?")
214
+ .get(scheduleId);
215
+ return row ? this.toScheduleRecord(row) : undefined;
216
+ }
217
+
218
+ public listSchedules(options: ListSchedulesOptions = {}): ScheduleRecord[] {
219
+ const whereClauses: string[] = [];
220
+ const params: unknown[] = [];
221
+ if (typeof options.enabled === "boolean") {
222
+ whereClauses.push("enabled = ?");
223
+ params.push(options.enabled ? 1 : 0);
224
+ }
225
+ if (options.tags && options.tags.length > 0) {
226
+ for (const tag of options.tags) {
227
+ whereClauses.push("tags LIKE ?");
228
+ params.push(`%"${tag.trim()}"%`);
229
+ }
230
+ }
231
+ const where =
232
+ whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
233
+ const limit =
234
+ typeof options.limit === "number" && options.limit > 0
235
+ ? Math.floor(options.limit)
236
+ : 200;
237
+ const rows = this.db
238
+ .prepare(
239
+ `SELECT * FROM schedules ${where} ORDER BY created_at DESC LIMIT ?`,
240
+ )
241
+ .all(...params, limit);
242
+ return rows.map((row) => this.toScheduleRecord(row));
243
+ }
244
+
245
+ public updateSchedule(
246
+ scheduleId: string,
247
+ updates: HubScheduleUpdateInput,
248
+ ): ScheduleRecord | undefined {
249
+ const current = this.getSchedule(scheduleId);
250
+ if (!current) {
251
+ return undefined;
252
+ }
253
+ const next: ScheduleRecord = {
254
+ ...current,
255
+ name: updates.name?.trim() ?? current.name,
256
+ cronPattern: updates.cronPattern?.trim() ?? current.cronPattern,
257
+ prompt: updates.prompt ?? current.prompt,
258
+ workspaceRoot:
259
+ updates.workspaceRoot !== undefined
260
+ ? updates.workspaceRoot.trim()
261
+ : current.workspaceRoot,
262
+ cwd:
263
+ updates.cwd !== undefined
264
+ ? updates.cwd.trim() || undefined
265
+ : current.cwd,
266
+ modelSelection:
267
+ updates.modelSelection !== undefined
268
+ ? JSON.parse(JSON.stringify(updates.modelSelection))
269
+ : current.modelSelection,
270
+ enabled: updates.enabled ?? current.enabled,
271
+ mode: updates.mode ?? current.mode,
272
+ systemPrompt:
273
+ updates.systemPrompt === null
274
+ ? undefined
275
+ : updates.systemPrompt !== undefined
276
+ ? updates.systemPrompt
277
+ : current.systemPrompt,
278
+ maxIterations:
279
+ updates.maxIterations === null
280
+ ? undefined
281
+ : updates.maxIterations !== undefined
282
+ ? Math.floor(updates.maxIterations)
283
+ : current.maxIterations,
284
+ timeoutSeconds:
285
+ updates.timeoutSeconds === null
286
+ ? undefined
287
+ : updates.timeoutSeconds !== undefined
288
+ ? Math.floor(updates.timeoutSeconds)
289
+ : current.timeoutSeconds,
290
+ maxParallel:
291
+ updates.maxParallel !== undefined
292
+ ? Math.max(1, Math.floor(updates.maxParallel))
293
+ : current.maxParallel,
294
+ updatedAt: Date.now(),
295
+ createdBy:
296
+ updates.createdBy === null
297
+ ? undefined
298
+ : updates.createdBy !== undefined
299
+ ? updates.createdBy.trim() || undefined
300
+ : current.createdBy,
301
+ tags: updates.tags ?? current.tags,
302
+ runtimeOptions:
303
+ updates.runtimeOptions !== undefined
304
+ ? JSON.parse(JSON.stringify(updates.runtimeOptions))
305
+ : current.runtimeOptions,
306
+ metadata:
307
+ updates.metadata !== undefined
308
+ ? JSON.parse(JSON.stringify(updates.metadata))
309
+ : current.metadata,
310
+ };
311
+
312
+ const cronChanged = next.cronPattern !== current.cronPattern;
313
+ const enabledChanged = next.enabled !== current.enabled;
314
+ if (cronChanged || enabledChanged) {
315
+ next.nextRunAt = next.enabled
316
+ ? getNextCronTime(next.cronPattern, Date.now())
317
+ : undefined;
318
+ }
319
+
320
+ const updatedAtIso = new Date(next.updatedAt).toISOString();
321
+ this.db
322
+ .prepare(
323
+ `UPDATE schedules SET
324
+ name = ?, cron_pattern = ?, prompt = ?,
325
+ provider = ?, model = ?, mode = ?, workspace_root = ?, cwd = ?, system_prompt = ?,
326
+ max_iterations = ?, timeout_seconds = ?, max_parallel = ?,
327
+ enabled = ?, updated_at = ?, last_run_at = ?, next_run_at = ?,
328
+ created_by = ?, tags = ?, metadata_json = ?
329
+ WHERE schedule_id = ?`,
330
+ )
331
+ .run(
332
+ next.name,
333
+ next.cronPattern,
334
+ next.prompt,
335
+ next.modelSelection?.providerId ?? "",
336
+ next.modelSelection?.modelId ?? "",
337
+ next.mode ?? "act",
338
+ next.workspaceRoot,
339
+ next.cwd ?? null,
340
+ next.systemPrompt ?? null,
341
+ next.maxIterations ?? null,
342
+ next.timeoutSeconds ?? null,
343
+ next.maxParallel ?? 1,
344
+ next.enabled ? 1 : 0,
345
+ updatedAtIso,
346
+ next.lastRunAt ? new Date(next.lastRunAt).toISOString() : null,
347
+ next.nextRunAt ? new Date(next.nextRunAt).toISOString() : null,
348
+ next.createdBy ?? null,
349
+ next.tags ? JSON.stringify(next.tags) : null,
350
+ JSON.stringify({
351
+ ...(next.metadata ?? {}),
352
+ ...(next.runtimeOptions
353
+ ? { __hubRuntimeOptions: next.runtimeOptions }
354
+ : {}),
355
+ }),
356
+ next.scheduleId,
357
+ );
358
+ return next;
359
+ }
360
+
361
+ public claimDueSchedules(
362
+ referenceTimeIso: string,
363
+ leaseDurationMs: number,
364
+ limit = 50,
365
+ ): ScheduleClaimRecord[] {
366
+ const claimed: ScheduleClaimRecord[] = [];
367
+ const boundedLimit = Math.max(1, Math.floor(limit));
368
+ const boundedLeaseMs = Math.max(1_000, Math.floor(leaseDurationMs));
369
+ const leaseUntilIso = new Date(
370
+ new Date(referenceTimeIso).getTime() + boundedLeaseMs,
371
+ ).toISOString();
372
+ const dueRowsSql = `SELECT * FROM schedules
373
+ WHERE enabled = 1
374
+ AND next_run_at IS NOT NULL
375
+ AND next_run_at <= ?
376
+ AND (claim_until_at IS NULL OR claim_until_at <= ?)
377
+ ORDER BY next_run_at ASC
378
+ LIMIT ?`;
379
+ const claimSql = `UPDATE schedules SET
380
+ claim_token = ?, claim_started_at = ?, claim_until_at = ?, updated_at = ?
381
+ WHERE schedule_id = ?
382
+ AND enabled = 1
383
+ AND next_run_at = ?
384
+ AND (claim_until_at IS NULL OR claim_until_at <= ?)`;
385
+ const claimStatement = this.db.prepare(claimSql);
386
+ this.db.exec("BEGIN IMMEDIATE;");
387
+ try {
388
+ const rows = this.db
389
+ .prepare(dueRowsSql)
390
+ .all(referenceTimeIso, referenceTimeIso, boundedLimit);
391
+ for (const row of rows) {
392
+ const scheduleId = asString(row.schedule_id);
393
+ const triggeredAtIso = asString(row.next_run_at);
394
+ if (!scheduleId || !triggeredAtIso) {
395
+ continue;
396
+ }
397
+ const claimToken = `claim_${randomUUID()}`;
398
+ const changes =
399
+ claimStatement.run(
400
+ claimToken,
401
+ referenceTimeIso,
402
+ leaseUntilIso,
403
+ referenceTimeIso,
404
+ scheduleId,
405
+ triggeredAtIso,
406
+ referenceTimeIso,
407
+ ).changes ?? 0;
408
+ if (changes !== 1) {
409
+ continue;
410
+ }
411
+ claimed.push({
412
+ schedule: this.toScheduleRecord(row),
413
+ claimToken,
414
+ triggeredAt: new Date(triggeredAtIso).getTime(),
415
+ leaseUntilAt: new Date(leaseUntilIso).getTime(),
416
+ });
417
+ }
418
+ this.db.exec("COMMIT;");
419
+ return claimed;
420
+ } catch (error) {
421
+ this.db.exec("ROLLBACK;");
422
+ throw error;
423
+ }
424
+ }
425
+
426
+ public renewScheduleClaim(
427
+ scheduleId: string,
428
+ claimToken: string,
429
+ leaseUntilAt: string,
430
+ ): boolean {
431
+ const changes =
432
+ this.db
433
+ .prepare(
434
+ `UPDATE schedules
435
+ SET claim_until_at = ?, updated_at = ?
436
+ WHERE schedule_id = ? AND claim_token = ?`,
437
+ )
438
+ .run(leaseUntilAt, nowIso(), scheduleId, claimToken).changes ?? 0;
439
+ return changes === 1;
440
+ }
441
+
442
+ public completeScheduleClaim(
443
+ scheduleId: string,
444
+ claimToken: string,
445
+ triggeredAtIso: string,
446
+ ): boolean {
447
+ const row = this.db
448
+ .prepare(
449
+ `SELECT cron_pattern, enabled
450
+ FROM schedules
451
+ WHERE schedule_id = ? AND claim_token = ?`,
452
+ )
453
+ .get(scheduleId, claimToken);
454
+ if (!row) {
455
+ return false;
456
+ }
457
+ const nextRunAt =
458
+ Number(row.enabled ?? 0) === 1
459
+ ? new Date(
460
+ getNextCronTime(
461
+ asString(row.cron_pattern),
462
+ new Date(triggeredAtIso).getTime(),
463
+ ),
464
+ ).toISOString()
465
+ : undefined;
466
+ const changes =
467
+ this.db
468
+ .prepare(
469
+ `UPDATE schedules SET
470
+ last_run_at = ?, next_run_at = ?, claim_token = NULL, claim_started_at = NULL, claim_until_at = NULL, updated_at = ?
471
+ WHERE schedule_id = ? AND claim_token = ?`,
472
+ )
473
+ .run(
474
+ triggeredAtIso,
475
+ nextRunAt ?? null,
476
+ nowIso(),
477
+ scheduleId,
478
+ claimToken,
479
+ ).changes ?? 0;
480
+ return changes === 1;
481
+ }
482
+
483
+ public releaseScheduleClaim(scheduleId: string, claimToken: string): boolean {
484
+ const changes =
485
+ this.db
486
+ .prepare(
487
+ `UPDATE schedules
488
+ SET claim_token = NULL, claim_started_at = NULL, claim_until_at = NULL, updated_at = ?
489
+ WHERE schedule_id = ? AND claim_token = ?`,
490
+ )
491
+ .run(nowIso(), scheduleId, claimToken).changes ?? 0;
492
+ return changes === 1;
493
+ }
494
+
495
+ public deleteSchedule(scheduleId: string): boolean {
496
+ const changes =
497
+ this.db
498
+ .prepare("DELETE FROM schedules WHERE schedule_id = ?")
499
+ .run(scheduleId).changes ?? 0;
500
+ return changes > 0;
501
+ }
502
+
503
+ public recordExecution(execution: ScheduleExecutionRecord): void {
504
+ const persistedSessionId =
505
+ execution.sessionId && this.sessionExists(execution.sessionId)
506
+ ? execution.sessionId
507
+ : null;
508
+ this.db
509
+ .prepare(
510
+ `INSERT OR REPLACE INTO schedule_executions (
511
+ execution_id, schedule_id, session_id,
512
+ triggered_at, started_at, ended_at, status,
513
+ exit_code, error_message, iterations, tokens_used, cost_usd
514
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
515
+ )
516
+ .run(
517
+ execution.executionId,
518
+ execution.scheduleId,
519
+ persistedSessionId,
520
+ new Date(execution.triggeredAt).toISOString(),
521
+ execution.startedAt
522
+ ? new Date(execution.startedAt).toISOString()
523
+ : null,
524
+ execution.endedAt ? new Date(execution.endedAt).toISOString() : null,
525
+ execution.status,
526
+ execution.exitCode ?? null,
527
+ execution.errorMessage ?? null,
528
+ execution.iterations ?? null,
529
+ execution.tokensUsed ?? null,
530
+ execution.costUsd ?? null,
531
+ );
532
+ }
533
+
534
+ private sessionExists(sessionId: string): boolean {
535
+ const row = this.db
536
+ .prepare("SELECT session_id FROM sessions WHERE session_id = ?")
537
+ .get(sessionId);
538
+ return !!row;
539
+ }
540
+
541
+ public listExecutions(
542
+ options: ListScheduleExecutionsOptions,
543
+ ): ScheduleExecutionRecord[] {
544
+ const where: string[] = [];
545
+ const params: unknown[] = [];
546
+ if (options.scheduleId) {
547
+ where.push("schedule_id = ?");
548
+ params.push(options.scheduleId);
549
+ }
550
+ if (options.status) {
551
+ where.push("status = ?");
552
+ params.push(options.status);
553
+ }
554
+ const whereClause = where.length > 0 ? `WHERE ${where.join(" AND ")}` : "";
555
+ const limit =
556
+ typeof options.limit === "number" && options.limit > 0
557
+ ? Math.floor(options.limit)
558
+ : 50;
559
+ const rows = this.db
560
+ .prepare(
561
+ `SELECT * FROM schedule_executions ${whereClause}
562
+ ORDER BY triggered_at DESC LIMIT ?`,
563
+ )
564
+ .all(...params, limit);
565
+ return rows.map((row) => this.toScheduleExecutionRecord(row));
566
+ }
567
+
568
+ public getExecutionStats(scheduleId: string): ScheduleExecutionStats {
569
+ const all = this.listExecutions({ scheduleId, limit: 10_000 });
570
+ if (all.length === 0) {
571
+ return { totalRuns: 0, successRate: 0, avgDurationSeconds: 0 };
572
+ }
573
+ let success = 0;
574
+ let withDuration = 0;
575
+ let durationMsTotal = 0;
576
+ let lastFailure: ScheduleExecutionRecord | undefined;
577
+ for (const execution of all) {
578
+ if (execution.status === "success" || execution.status === "completed") {
579
+ success += 1;
580
+ }
581
+ if (
582
+ !lastFailure &&
583
+ execution.status !== "success" &&
584
+ execution.status !== "completed"
585
+ ) {
586
+ lastFailure = execution;
587
+ }
588
+ if (execution.startedAt && execution.endedAt) {
589
+ const durationMs = execution.endedAt - execution.startedAt;
590
+ if (Number.isFinite(durationMs) && durationMs >= 0) {
591
+ durationMsTotal += durationMs;
592
+ withDuration += 1;
593
+ }
594
+ }
595
+ }
596
+ return {
597
+ totalRuns: all.length,
598
+ successRate: success / all.length,
599
+ avgDurationSeconds:
600
+ withDuration > 0 ? durationMsTotal / withDuration / 1000 : 0,
601
+ lastFailure,
602
+ };
603
+ }
604
+
605
+ public listUpcomingRuns(limit = 20): Array<{
606
+ scheduleId: string;
607
+ name: string;
608
+ nextRunAt: string;
609
+ }> {
610
+ const rows = this.db
611
+ .prepare(
612
+ `SELECT schedule_id, name, next_run_at FROM schedules
613
+ WHERE enabled = 1 AND next_run_at IS NOT NULL
614
+ ORDER BY next_run_at ASC LIMIT ?`,
615
+ )
616
+ .all(Math.max(1, Math.floor(limit)));
617
+ return rows
618
+ .map((row) => ({
619
+ scheduleId: asString(row.schedule_id),
620
+ name: asString(row.name),
621
+ nextRunAt: asString(row.next_run_at),
622
+ }))
623
+ .filter((item) => item.scheduleId && item.nextRunAt);
624
+ }
625
+
626
+ private toScheduleRecord(row: Record<string, unknown>): ScheduleRecord {
627
+ const metadata = parseJsonObject(asOptionalString(row.metadata_json));
628
+ const runtimeOptions =
629
+ metadata?.__hubRuntimeOptions &&
630
+ typeof metadata.__hubRuntimeOptions === "object" &&
631
+ !Array.isArray(metadata.__hubRuntimeOptions)
632
+ ? (metadata.__hubRuntimeOptions as ScheduleRecord["runtimeOptions"])
633
+ : undefined;
634
+ if (metadata && "__hubRuntimeOptions" in metadata) {
635
+ delete metadata.__hubRuntimeOptions;
636
+ }
637
+ return {
638
+ scheduleId: asString(row.schedule_id),
639
+ name: asString(row.name),
640
+ cronPattern: asString(row.cron_pattern),
641
+ prompt: asString(row.prompt),
642
+ workspaceRoot: asString(row.workspace_root),
643
+ cwd: asOptionalString(row.cwd),
644
+ modelSelection:
645
+ asOptionalString(row.provider) || asOptionalString(row.model)
646
+ ? {
647
+ providerId: asOptionalString(row.provider) ?? "",
648
+ modelId: asOptionalString(row.model) ?? "",
649
+ }
650
+ : undefined,
651
+ enabled: Number(row.enabled ?? 0) === 1,
652
+ mode:
653
+ asOptionalString(row.mode) === "plan"
654
+ ? "plan"
655
+ : asOptionalString(row.mode) === "yolo"
656
+ ? "yolo"
657
+ : "act",
658
+ systemPrompt: asOptionalString(row.system_prompt),
659
+ maxIterations:
660
+ typeof row.max_iterations === "number" ? row.max_iterations : undefined,
661
+ timeoutSeconds:
662
+ typeof row.timeout_seconds === "number"
663
+ ? row.timeout_seconds
664
+ : undefined,
665
+ maxParallel:
666
+ typeof row.max_parallel === "number" && row.max_parallel > 0
667
+ ? row.max_parallel
668
+ : 1,
669
+ createdAt: new Date(asString(row.created_at)).getTime(),
670
+ updatedAt: new Date(asString(row.updated_at)).getTime(),
671
+ lastRunAt: asOptionalString(row.last_run_at)
672
+ ? new Date(asString(row.last_run_at)).getTime()
673
+ : undefined,
674
+ nextRunAt: asOptionalString(row.next_run_at)
675
+ ? new Date(asString(row.next_run_at)).getTime()
676
+ : undefined,
677
+ createdBy: asOptionalString(row.created_by),
678
+ tags: parseJsonArray(asOptionalString(row.tags)),
679
+ runtimeOptions,
680
+ metadata: metadata as ScheduleRecord["metadata"],
681
+ };
682
+ }
683
+
684
+ private toScheduleExecutionRecord(
685
+ row: Record<string, unknown>,
686
+ ): ScheduleExecutionRecord {
687
+ return {
688
+ executionId: asString(row.execution_id),
689
+ scheduleId: asString(row.schedule_id),
690
+ sessionId: asOptionalString(row.session_id),
691
+ triggeredAt: new Date(asString(row.triggered_at)).getTime(),
692
+ startedAt: asOptionalString(row.started_at)
693
+ ? new Date(asString(row.started_at)).getTime()
694
+ : undefined,
695
+ endedAt: asOptionalString(row.ended_at)
696
+ ? new Date(asString(row.ended_at)).getTime()
697
+ : undefined,
698
+ status: normalizeExecutionStatus(asOptionalString(row.status)),
699
+ exitCode: typeof row.exit_code === "number" ? row.exit_code : undefined,
700
+ errorMessage: asOptionalString(row.error_message),
701
+ iterations:
702
+ typeof row.iterations === "number" ? row.iterations : undefined,
703
+ tokensUsed:
704
+ typeof row.tokens_used === "number" ? row.tokens_used : undefined,
705
+ costUsd: typeof row.cost_usd === "number" ? row.cost_usd : undefined,
706
+ };
707
+ }
708
+ }