@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,703 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type {
3
+ BasicLogger,
4
+ ChatRunTurnRequest,
5
+ ChatStartSessionArtifacts,
6
+ ChatStartSessionRequest,
7
+ HubScheduleCreateInput,
8
+ HubScheduleUpdateInput,
9
+ ScheduleExecutionRecord,
10
+ ScheduleExecutionStatus,
11
+ ScheduleRecord,
12
+ } from "@clinebot/shared";
13
+ import { nowIso } from "@clinebot/shared/db";
14
+ import { ResourceLimiter } from "./resource-limiter";
15
+ import { validateCronPattern } from "./scheduler";
16
+ import {
17
+ type ListScheduleExecutionsOptions,
18
+ type ListSchedulesOptions,
19
+ type ScheduleClaimRecord,
20
+ type ScheduleExecutionStats,
21
+ SqliteHubScheduleStore,
22
+ } from "./sqlite-schedule-store";
23
+
24
+ function toErrorMessage(error: unknown): string {
25
+ return error instanceof Error ? error.message : String(error);
26
+ }
27
+
28
+ type HubScheduleTurnResult = {
29
+ text: string;
30
+ usage?: {
31
+ inputTokens?: number;
32
+ outputTokens?: number;
33
+ cacheReadTokens?: number;
34
+ cacheWriteTokens?: number;
35
+ totalCost?: number;
36
+ };
37
+ inputTokens?: number;
38
+ outputTokens?: number;
39
+ iterations?: number;
40
+ finishReason?: string;
41
+ messages?: unknown[];
42
+ toolCalls?: Array<{
43
+ name: string;
44
+ input?: unknown;
45
+ output?: unknown;
46
+ error?: string;
47
+ durationMs?: number;
48
+ }>;
49
+ };
50
+
51
+ function parseTurnMetrics(result: HubScheduleTurnResult): {
52
+ iterations?: number;
53
+ tokensUsed?: number;
54
+ costUsd?: number;
55
+ } {
56
+ const inputTokens =
57
+ typeof result.inputTokens === "number" ? result.inputTokens : undefined;
58
+ const outputTokens =
59
+ typeof result.outputTokens === "number" ? result.outputTokens : undefined;
60
+ return {
61
+ iterations:
62
+ typeof result.iterations === "number" ? result.iterations : undefined,
63
+ tokensUsed:
64
+ inputTokens !== undefined && outputTokens !== undefined
65
+ ? inputTokens + outputTokens
66
+ : undefined,
67
+ costUsd:
68
+ typeof result.usage?.totalCost === "number"
69
+ ? result.usage.totalCost
70
+ : undefined,
71
+ };
72
+ }
73
+
74
+ interface AggregatedTurnMetrics {
75
+ iterations?: number;
76
+ tokensUsed?: number;
77
+ costUsd?: number;
78
+ }
79
+
80
+ function addTurnMetrics(
81
+ current: AggregatedTurnMetrics,
82
+ result: HubScheduleTurnResult,
83
+ ): AggregatedTurnMetrics {
84
+ const next = { ...current };
85
+ const metrics = parseTurnMetrics(result);
86
+ if (typeof metrics.iterations === "number") {
87
+ next.iterations = (next.iterations ?? 0) + metrics.iterations;
88
+ }
89
+ if (typeof metrics.tokensUsed === "number") {
90
+ next.tokensUsed = (next.tokensUsed ?? 0) + metrics.tokensUsed;
91
+ }
92
+ if (typeof metrics.costUsd === "number") {
93
+ next.costUsd = (next.costUsd ?? 0) + metrics.costUsd;
94
+ }
95
+ return next;
96
+ }
97
+
98
+ function optionsOrDefault(value: number | undefined, fallback: number): number {
99
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
100
+ }
101
+
102
+ function asPositiveSeconds(value: unknown, fallback: number): number {
103
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
104
+ return fallback;
105
+ }
106
+ return Math.max(1, Math.floor(value));
107
+ }
108
+
109
+ const DEFAULT_AUTONOMOUS_IDLE_TIMEOUT_SECONDS = 60;
110
+ const DEFAULT_AUTONOMOUS_POLL_INTERVAL_SECONDS = 5;
111
+ const AUTONOMOUS_IDLE_NOOP_TOKEN = "<idle-noop/>";
112
+
113
+ export interface ScheduleAutonomousOptions {
114
+ enabled?: boolean;
115
+ idleTimeoutSeconds?: number;
116
+ pollIntervalSeconds?: number;
117
+ }
118
+
119
+ function getAutonomousOptions(
120
+ schedule: ScheduleRecord,
121
+ ): ScheduleAutonomousOptions | undefined {
122
+ const metadata = schedule.metadata;
123
+ if (!metadata || typeof metadata !== "object") {
124
+ return undefined;
125
+ }
126
+ const raw =
127
+ metadata.autonomous &&
128
+ typeof metadata.autonomous === "object" &&
129
+ !Array.isArray(metadata.autonomous)
130
+ ? (metadata.autonomous as Record<string, unknown>)
131
+ : undefined;
132
+ if (!raw || raw.enabled !== true) {
133
+ return undefined;
134
+ }
135
+ return {
136
+ enabled: true,
137
+ idleTimeoutSeconds: asPositiveSeconds(
138
+ raw.idleTimeoutSeconds,
139
+ DEFAULT_AUTONOMOUS_IDLE_TIMEOUT_SECONDS,
140
+ ),
141
+ pollIntervalSeconds: asPositiveSeconds(
142
+ raw.pollIntervalSeconds,
143
+ DEFAULT_AUTONOMOUS_POLL_INTERVAL_SECONDS,
144
+ ),
145
+ };
146
+ }
147
+
148
+ function buildSchedulePrompt(
149
+ schedule: ScheduleRecord,
150
+ autonomous: ScheduleAutonomousOptions | undefined,
151
+ ): string {
152
+ if (!autonomous?.enabled) {
153
+ return schedule.prompt;
154
+ }
155
+ return `${schedule.prompt}
156
+
157
+ When you finish the immediate scheduled work, remain available for autonomous follow-up. During idle polling, inspect team mailbox and team tasks. Use team_task with action="list" to find ready unassigned work, claim it with team_task and action="claim", and resume execution when work exists. Reply exactly ${AUTONOMOUS_IDLE_NOOP_TOKEN} only when the poll finds no actionable work.`;
158
+ }
159
+
160
+ function buildAutonomousPollPrompt(
161
+ autonomous: ScheduleAutonomousOptions,
162
+ ): string {
163
+ return `Autonomous idle poll. Check team_read_mailbox for unread messages and use team_task with action="list" to find ready unassigned tasks. Claim and execute one task if actionable work exists. If there is nothing to do right now, reply exactly ${AUTONOMOUS_IDLE_NOOP_TOKEN} and nothing else. Poll cadence is ${autonomous.pollIntervalSeconds}s and the idle shutdown window is ${autonomous.idleTimeoutSeconds}s.`;
164
+ }
165
+
166
+ function isAutonomousNoop(result: HubScheduleTurnResult): boolean {
167
+ return result.text?.trim() === AUTONOMOUS_IDLE_NOOP_TOKEN;
168
+ }
169
+
170
+ function sleep(ms: number): Promise<void> {
171
+ return new Promise((resolve) => setTimeout(resolve, ms));
172
+ }
173
+
174
+ class TimeoutError extends Error {
175
+ constructor(message: string) {
176
+ super(message);
177
+ this.name = "TimeoutError";
178
+ }
179
+ }
180
+
181
+ async function withTimeout<T>(
182
+ promise: Promise<T>,
183
+ timeoutMs: number,
184
+ ): Promise<T> {
185
+ if (timeoutMs <= 0) {
186
+ return await promise;
187
+ }
188
+ let timeoutHandle: ReturnType<typeof setTimeout> | undefined;
189
+ const timeoutPromise = new Promise<never>((_, reject) => {
190
+ timeoutHandle = setTimeout(() => {
191
+ reject(new TimeoutError("scheduled execution timed out"));
192
+ }, timeoutMs);
193
+ });
194
+ try {
195
+ return await Promise.race([promise, timeoutPromise]);
196
+ } finally {
197
+ if (timeoutHandle) {
198
+ clearTimeout(timeoutHandle);
199
+ }
200
+ }
201
+ }
202
+
203
+ export interface HubScheduleRuntimeHandlers {
204
+ startSession(request: ChatStartSessionRequest): Promise<{
205
+ sessionId: string;
206
+ startResult?: ChatStartSessionArtifacts;
207
+ }>;
208
+ sendSession(
209
+ sessionId: string,
210
+ request: ChatRunTurnRequest,
211
+ ): Promise<{
212
+ result: HubScheduleTurnResult;
213
+ }>;
214
+ abortSession(sessionId: string): Promise<{ applied: boolean }>;
215
+ stopSession(sessionId: string): Promise<{ applied: boolean }>;
216
+ }
217
+
218
+ export interface ActiveScheduledExecution {
219
+ executionId: string;
220
+ scheduleId: string;
221
+ sessionId: string;
222
+ startedAt: string;
223
+ timeoutAt?: string;
224
+ }
225
+
226
+ export interface HubScheduleServiceOptions {
227
+ runtimeHandlers: HubScheduleRuntimeHandlers;
228
+ eventPublisher?: (eventType: string, payload: unknown) => void;
229
+ logger?: BasicLogger;
230
+ sessionsDbPath?: string;
231
+ pollIntervalMs?: number;
232
+ globalMaxConcurrency?: number;
233
+ claimLeaseSeconds?: number;
234
+ }
235
+
236
+ export class HubScheduleService {
237
+ private readonly store: SqliteHubScheduleStore;
238
+ private readonly resourceLimiter: ResourceLimiter;
239
+ private readonly options: HubScheduleServiceOptions;
240
+ private readonly claimLeaseMs: number;
241
+ private readonly activeExecutions = new Map<
242
+ string,
243
+ ActiveScheduledExecution
244
+ >();
245
+ private timer: ReturnType<typeof setInterval> | undefined;
246
+ private started = false;
247
+ private ticking = false;
248
+ private disposed = false;
249
+
250
+ constructor(options: HubScheduleServiceOptions) {
251
+ this.options = options;
252
+ this.store = new SqliteHubScheduleStore({
253
+ sessionsDbPath: options.sessionsDbPath,
254
+ });
255
+ this.resourceLimiter = new ResourceLimiter(
256
+ options.globalMaxConcurrency ?? 10,
257
+ );
258
+ this.claimLeaseMs = Math.max(
259
+ 5_000,
260
+ optionsOrDefault(options.claimLeaseSeconds, 90) * 1000,
261
+ );
262
+ }
263
+
264
+ public async start(): Promise<void> {
265
+ if (this.disposed) {
266
+ throw new Error("HubScheduleService has been disposed");
267
+ }
268
+ if (this.started) {
269
+ return;
270
+ }
271
+ this.started = true;
272
+ const intervalMs = Math.max(
273
+ 5_000,
274
+ optionsOrDefault(this.options.pollIntervalMs, 30_000),
275
+ );
276
+ this.options.logger?.log("hub.schedule.started", {
277
+ pollIntervalMs: intervalMs,
278
+ });
279
+ await this.tick();
280
+ this.timer = setInterval(() => {
281
+ void this.tick();
282
+ }, intervalMs);
283
+ }
284
+
285
+ public async stop(): Promise<void> {
286
+ const wasStarted = this.started;
287
+ this.started = false;
288
+ if (this.timer) {
289
+ clearInterval(this.timer);
290
+ this.timer = undefined;
291
+ }
292
+ if (wasStarted) {
293
+ this.options.logger?.log("hub.schedule.stopped", {});
294
+ }
295
+ const active = Array.from(this.activeExecutions.values());
296
+ await Promise.all(
297
+ active.map(async (execution) => {
298
+ try {
299
+ await this.options.runtimeHandlers.abortSession(execution.sessionId);
300
+ } catch {
301
+ // best effort
302
+ }
303
+ }),
304
+ );
305
+ }
306
+
307
+ public async dispose(): Promise<void> {
308
+ if (this.disposed) {
309
+ return;
310
+ }
311
+ this.disposed = true;
312
+ await this.stop();
313
+ this.store.close();
314
+ }
315
+
316
+ public createSchedule(input: HubScheduleCreateInput): ScheduleRecord {
317
+ validateCronPattern(input.cronPattern);
318
+ if (!input.workspaceRoot?.trim()) {
319
+ throw new Error("workspaceRoot is required for schedules");
320
+ }
321
+ return this.store.createSchedule(input);
322
+ }
323
+
324
+ public getSchedule(scheduleId: string): ScheduleRecord | undefined {
325
+ return this.store.getSchedule(scheduleId);
326
+ }
327
+
328
+ public listSchedules(options: ListSchedulesOptions = {}): ScheduleRecord[] {
329
+ return this.store.listSchedules(options);
330
+ }
331
+
332
+ public updateSchedule(
333
+ scheduleId: string,
334
+ updates: HubScheduleUpdateInput,
335
+ ): ScheduleRecord | undefined {
336
+ if (updates.cronPattern !== undefined) {
337
+ validateCronPattern(updates.cronPattern);
338
+ }
339
+ const current = this.store.getSchedule(scheduleId);
340
+ if (!current) {
341
+ return undefined;
342
+ }
343
+ const nextWorkspaceRoot =
344
+ updates.workspaceRoot !== undefined
345
+ ? updates.workspaceRoot.trim()
346
+ : current.workspaceRoot;
347
+ const nextEnabled = updates.enabled ?? current.enabled;
348
+ if (nextEnabled && !nextWorkspaceRoot) {
349
+ throw new Error("workspaceRoot is required for enabled schedules");
350
+ }
351
+ return this.store.updateSchedule(scheduleId, {
352
+ ...updates,
353
+ scheduleId,
354
+ });
355
+ }
356
+
357
+ public deleteSchedule(scheduleId: string): boolean {
358
+ return this.store.deleteSchedule(scheduleId);
359
+ }
360
+
361
+ public pauseSchedule(scheduleId: string): ScheduleRecord | undefined {
362
+ return this.updateSchedule(scheduleId, { scheduleId, enabled: false });
363
+ }
364
+
365
+ public resumeSchedule(scheduleId: string): ScheduleRecord | undefined {
366
+ return this.updateSchedule(scheduleId, { scheduleId, enabled: true });
367
+ }
368
+
369
+ public async triggerScheduleNow(
370
+ scheduleId: string,
371
+ ): Promise<ScheduleExecutionRecord | undefined> {
372
+ const schedule = this.store.getSchedule(scheduleId);
373
+ if (!schedule) {
374
+ return undefined;
375
+ }
376
+ return await this.executeSchedule(schedule, nowIso(), "manual");
377
+ }
378
+
379
+ public listScheduleExecutions(
380
+ options: ListScheduleExecutionsOptions,
381
+ ): ScheduleExecutionRecord[] {
382
+ return this.store.listExecutions(options);
383
+ }
384
+
385
+ public getScheduleStats(scheduleId: string): ScheduleExecutionStats {
386
+ return this.store.getExecutionStats(scheduleId);
387
+ }
388
+
389
+ public getActiveExecutions(): ActiveScheduledExecution[] {
390
+ return Array.from(this.activeExecutions.values());
391
+ }
392
+
393
+ public getUpcomingRuns(limit = 20): Array<{
394
+ scheduleId: string;
395
+ name: string;
396
+ nextRunAt: string;
397
+ }> {
398
+ return this.store.listUpcomingRuns(limit);
399
+ }
400
+
401
+ private async tick(): Promise<void> {
402
+ if (this.ticking) {
403
+ return;
404
+ }
405
+ this.ticking = true;
406
+ try {
407
+ const claims = this.store.claimDueSchedules(nowIso(), this.claimLeaseMs);
408
+ await Promise.allSettled(
409
+ claims.map((claim) => this.executeClaimedSchedule(claim)),
410
+ );
411
+ } catch (error) {
412
+ const logger = this.options.logger;
413
+ if (logger) {
414
+ if (logger.error) {
415
+ logger.error("hub.schedule.tick.failed", { error });
416
+ } else {
417
+ logger.log("hub.schedule.tick.failed", {
418
+ error,
419
+ severity: "error",
420
+ });
421
+ }
422
+ }
423
+ } finally {
424
+ this.ticking = false;
425
+ }
426
+ }
427
+
428
+ private async executeClaimedSchedule(
429
+ claim: ScheduleClaimRecord,
430
+ ): Promise<void> {
431
+ const releaseLeaseHeartbeat = this.startClaimLeaseHeartbeat(claim);
432
+ try {
433
+ const result = await this.executeSchedule(
434
+ claim.schedule,
435
+ new Date(claim.triggeredAt).toISOString(),
436
+ "scheduled",
437
+ );
438
+ const completedAt = result.startedAt ?? claim.triggeredAt;
439
+ this.store.completeScheduleClaim(
440
+ claim.schedule.scheduleId,
441
+ claim.claimToken,
442
+ new Date(completedAt).toISOString(),
443
+ );
444
+ } finally {
445
+ releaseLeaseHeartbeat();
446
+ }
447
+ }
448
+
449
+ private startClaimLeaseHeartbeat(claim: ScheduleClaimRecord): () => void {
450
+ const heartbeatMs = Math.max(1_000, Math.floor(this.claimLeaseMs / 2));
451
+ const interval = setInterval(() => {
452
+ const leaseUntilAt = new Date(
453
+ Date.now() + this.claimLeaseMs,
454
+ ).toISOString();
455
+ const renewed = this.store.renewScheduleClaim(
456
+ claim.schedule.scheduleId,
457
+ claim.claimToken,
458
+ leaseUntilAt,
459
+ );
460
+ if (!renewed) {
461
+ clearInterval(interval);
462
+ }
463
+ }, heartbeatMs);
464
+ return () => clearInterval(interval);
465
+ }
466
+
467
+ private buildStartRequest(schedule: ScheduleRecord): ChatStartSessionRequest {
468
+ const workspaceRoot = schedule.workspaceRoot.trim();
469
+ const provider = schedule.modelSelection?.providerId?.trim();
470
+ const model = schedule.modelSelection?.modelId?.trim();
471
+ if (!workspaceRoot) {
472
+ throw new Error("schedule requires workspaceRoot");
473
+ }
474
+ if (!provider || !model) {
475
+ throw new Error(
476
+ "schedule requires modelSelection.providerId and modelSelection.modelId",
477
+ );
478
+ }
479
+ return {
480
+ workspaceRoot,
481
+ cwd: schedule.cwd?.trim() || workspaceRoot,
482
+ provider,
483
+ model,
484
+ mode:
485
+ schedule.mode === "plan"
486
+ ? "plan"
487
+ : schedule.mode === "yolo"
488
+ ? "yolo"
489
+ : "act",
490
+ systemPrompt: schedule.systemPrompt,
491
+ maxIterations: schedule.maxIterations,
492
+ enableTools: schedule.runtimeOptions?.enableTools ?? true,
493
+ enableSpawn: schedule.runtimeOptions?.enableSpawn ?? true,
494
+ enableTeams: schedule.runtimeOptions?.enableTeams ?? true,
495
+ autoApproveTools: schedule.runtimeOptions?.autoApproveTools ?? true,
496
+ };
497
+ }
498
+
499
+ private async executeSchedule(
500
+ schedule: ScheduleRecord,
501
+ triggeredAt: string,
502
+ trigger: "scheduled" | "manual",
503
+ ): Promise<ScheduleExecutionRecord> {
504
+ const executionId = `exec_${randomUUID()}`;
505
+ const triggeredAtMs = new Date(triggeredAt).getTime();
506
+ const pending: ScheduleExecutionRecord = {
507
+ executionId,
508
+ scheduleId: schedule.scheduleId,
509
+ triggeredAt: triggeredAtMs,
510
+ status: "pending",
511
+ };
512
+ this.store.recordExecution(pending);
513
+
514
+ const acquired = this.resourceLimiter.acquire(
515
+ schedule.scheduleId,
516
+ executionId,
517
+ schedule.maxParallel ?? 1,
518
+ );
519
+ if (!acquired) {
520
+ const skipped: ScheduleExecutionRecord = {
521
+ ...pending,
522
+ status: "failed",
523
+ endedAt: Date.now(),
524
+ errorMessage: "concurrency limit reached",
525
+ };
526
+ this.store.recordExecution(skipped);
527
+ return skipped;
528
+ }
529
+
530
+ let sessionId: string | undefined;
531
+ let startedAt: number | undefined;
532
+ let timeoutAt: string | undefined;
533
+ let executionDeadlineMs: number | undefined;
534
+
535
+ try {
536
+ const startRequest = this.buildStartRequest(schedule);
537
+ const startResponse =
538
+ await this.options.runtimeHandlers.startSession(startRequest);
539
+ sessionId = startResponse.sessionId.trim();
540
+ if (!sessionId) {
541
+ throw new Error("runtime start returned empty sessionId");
542
+ }
543
+
544
+ startedAt = Date.now();
545
+ timeoutAt =
546
+ typeof schedule.timeoutSeconds === "number" &&
547
+ schedule.timeoutSeconds > 0
548
+ ? new Date(startedAt + schedule.timeoutSeconds * 1000).toISOString()
549
+ : undefined;
550
+ executionDeadlineMs = timeoutAt
551
+ ? new Date(timeoutAt).getTime()
552
+ : undefined;
553
+
554
+ const runningState: ScheduleExecutionRecord = {
555
+ ...pending,
556
+ sessionId,
557
+ startedAt,
558
+ status: "running",
559
+ };
560
+ this.store.recordExecution(runningState);
561
+ this.activeExecutions.set(executionId, {
562
+ executionId,
563
+ scheduleId: schedule.scheduleId,
564
+ sessionId,
565
+ startedAt: new Date(startedAt).toISOString(),
566
+ timeoutAt,
567
+ });
568
+ this.publishEvent("schedule.execution.started", {
569
+ scheduleId: schedule.scheduleId,
570
+ executionId,
571
+ sessionId,
572
+ trigger,
573
+ triggeredAt,
574
+ });
575
+
576
+ const turnRequest: ChatRunTurnRequest = {
577
+ config: startRequest,
578
+ prompt: buildSchedulePrompt(schedule, getAutonomousOptions(schedule)),
579
+ };
580
+ const sendTurn = async (
581
+ request: ChatRunTurnRequest,
582
+ ): Promise<HubScheduleTurnResult> => {
583
+ const sendPromise = this.options.runtimeHandlers.sendSession(
584
+ sessionId!,
585
+ request,
586
+ );
587
+ const timeoutMs = executionDeadlineMs
588
+ ? Math.max(1, executionDeadlineMs - Date.now())
589
+ : 0;
590
+ const sendResult = await withTimeout(sendPromise, timeoutMs);
591
+ return sendResult.result;
592
+ };
593
+
594
+ let metrics = addTurnMetrics({}, await sendTurn(turnRequest));
595
+ const autonomous = getAutonomousOptions(schedule);
596
+ if (autonomous?.enabled) {
597
+ metrics = await this.runAutonomousIdleLoop({
598
+ sessionId,
599
+ startRequest,
600
+ autonomous,
601
+ metrics,
602
+ sendTurn,
603
+ executionDeadlineMs,
604
+ });
605
+ }
606
+
607
+ const completed: ScheduleExecutionRecord = {
608
+ ...runningState,
609
+ status: "success",
610
+ endedAt: Date.now(),
611
+ iterations: metrics.iterations,
612
+ tokensUsed: metrics.tokensUsed,
613
+ costUsd: metrics.costUsd,
614
+ };
615
+ this.store.recordExecution(completed);
616
+ this.publishEvent("schedule.execution.completed", {
617
+ scheduleId: schedule.scheduleId,
618
+ executionId,
619
+ sessionId,
620
+ status: completed.status,
621
+ durationMs:
622
+ completed.startedAt && completed.endedAt
623
+ ? completed.endedAt - completed.startedAt
624
+ : undefined,
625
+ });
626
+ return completed;
627
+ } catch (error) {
628
+ const status: ScheduleExecutionStatus =
629
+ error instanceof TimeoutError ? "timeout" : "failed";
630
+ if (sessionId && status === "timeout") {
631
+ try {
632
+ await this.options.runtimeHandlers.abortSession(sessionId);
633
+ } catch {
634
+ // best effort
635
+ }
636
+ }
637
+ const failed: ScheduleExecutionRecord = {
638
+ executionId,
639
+ scheduleId: schedule.scheduleId,
640
+ sessionId,
641
+ triggeredAt: triggeredAtMs,
642
+ startedAt,
643
+ endedAt: Date.now(),
644
+ status,
645
+ errorMessage: toErrorMessage(error),
646
+ };
647
+ this.store.recordExecution(failed);
648
+ this.publishEvent("schedule.execution.completed", {
649
+ scheduleId: schedule.scheduleId,
650
+ executionId,
651
+ sessionId,
652
+ status: failed.status,
653
+ errorMessage: failed.errorMessage,
654
+ });
655
+ return failed;
656
+ } finally {
657
+ if (sessionId) {
658
+ try {
659
+ await this.options.runtimeHandlers.stopSession(sessionId);
660
+ } catch {
661
+ // best effort
662
+ }
663
+ }
664
+ this.activeExecutions.delete(executionId);
665
+ this.resourceLimiter.release(schedule.scheduleId, executionId);
666
+ }
667
+ }
668
+
669
+ private publishEvent(eventType: string, payload: unknown): void {
670
+ this.options.eventPublisher?.(eventType, payload);
671
+ }
672
+
673
+ private async runAutonomousIdleLoop(options: {
674
+ sessionId: string;
675
+ startRequest: ChatStartSessionRequest;
676
+ autonomous: ScheduleAutonomousOptions;
677
+ metrics: AggregatedTurnMetrics;
678
+ sendTurn: (request: ChatRunTurnRequest) => Promise<HubScheduleTurnResult>;
679
+ executionDeadlineMs?: number;
680
+ }): Promise<AggregatedTurnMetrics> {
681
+ let metrics = options.metrics;
682
+ const idleDeadline =
683
+ Date.now() + options.autonomous.idleTimeoutSeconds! * 1000;
684
+ while (Date.now() < idleDeadline) {
685
+ if (
686
+ options.executionDeadlineMs !== undefined &&
687
+ Date.now() >= options.executionDeadlineMs
688
+ ) {
689
+ throw new TimeoutError("scheduled execution timed out");
690
+ }
691
+ await sleep(options.autonomous.pollIntervalSeconds! * 1000);
692
+ const result = await options.sendTurn({
693
+ config: options.startRequest,
694
+ prompt: buildAutonomousPollPrompt(options.autonomous),
695
+ });
696
+ metrics = addTurnMetrics(metrics, result);
697
+ if (isAutonomousNoop(result)) {
698
+ break;
699
+ }
700
+ }
701
+ return metrics;
702
+ }
703
+ }