@wjarka/cezarion 0.15.1 → 0.16.0

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 (462) hide show
  1. package/README.md +167 -46
  2. package/dist/agent-config/catalog.d.ts +6 -2
  3. package/dist/agent-config/catalog.js +78 -3
  4. package/dist/agent-config/catalog.js.map +1 -1
  5. package/dist/agent-config/model-settings/shared.js +6 -3
  6. package/dist/agent-config/model-settings/shared.js.map +1 -1
  7. package/dist/agent-config/models.js +4 -0
  8. package/dist/agent-config/models.js.map +1 -1
  9. package/dist/agent-config/validate.js +6 -0
  10. package/dist/agent-config/validate.js.map +1 -1
  11. package/dist/artifacts/cli.js +10 -2
  12. package/dist/artifacts/cli.js.map +1 -1
  13. package/dist/automations/coordinator.d.ts +7 -0
  14. package/dist/automations/coordinator.js +22 -2
  15. package/dist/automations/coordinator.js.map +1 -1
  16. package/dist/automations/github-poller.d.ts +4 -4
  17. package/dist/automations/github-poller.js.map +1 -1
  18. package/dist/automations/schedule-runner.d.ts +130 -0
  19. package/dist/automations/schedule-runner.js +326 -0
  20. package/dist/automations/schedule-runner.js.map +1 -0
  21. package/dist/automations/scheduler.d.ts +38 -7
  22. package/dist/automations/scheduler.js +90 -22
  23. package/dist/automations/scheduler.js.map +1 -1
  24. package/dist/automations/store.d.ts +80 -3
  25. package/dist/automations/store.js +208 -16
  26. package/dist/automations/store.js.map +1 -1
  27. package/dist/automations/task-template.d.ts +42 -6
  28. package/dist/automations/task-template.js +152 -24
  29. package/dist/automations/task-template.js.map +1 -1
  30. package/dist/automations/types.d.ts +142 -6
  31. package/dist/automations/types.js +64 -6
  32. package/dist/automations/types.js.map +1 -1
  33. package/dist/autosave-holders.js +8 -12
  34. package/dist/autosave-holders.js.map +1 -1
  35. package/dist/ci-wait/client.d.ts +8 -1
  36. package/dist/ci-wait/client.js +43 -1
  37. package/dist/ci-wait/client.js.map +1 -1
  38. package/dist/ci-wait/controller.d.ts +83 -4
  39. package/dist/ci-wait/controller.js +76 -11
  40. package/dist/ci-wait/controller.js.map +1 -1
  41. package/dist/ci-wait/errors.d.ts +7 -1
  42. package/dist/ci-wait/errors.js +36 -0
  43. package/dist/ci-wait/errors.js.map +1 -1
  44. package/dist/ci-wait/github.d.ts +2 -0
  45. package/dist/ci-wait/github.js +3 -1
  46. package/dist/ci-wait/github.js.map +1 -1
  47. package/dist/ci-wait/mcp.d.ts +2 -98
  48. package/dist/ci-wait/mcp.js +11 -25
  49. package/dist/ci-wait/mcp.js.map +1 -1
  50. package/dist/ci-wait/supervisor.d.ts +2 -1
  51. package/dist/ci-wait/supervisor.js +2 -1
  52. package/dist/ci-wait/supervisor.js.map +1 -1
  53. package/dist/ci-wait/tools.d.ts +307 -0
  54. package/dist/ci-wait/tools.js +63 -0
  55. package/dist/ci-wait/tools.js.map +1 -0
  56. package/dist/config.d.ts +3 -0
  57. package/dist/config.js +7 -0
  58. package/dist/config.js.map +1 -1
  59. package/dist/contract/agent-config.d.ts +5 -0
  60. package/dist/contract/agent-profiles.d.ts +15 -0
  61. package/dist/contract/automation-schedule.d.ts +60 -0
  62. package/dist/contract/automations.d.ts +208 -36
  63. package/dist/contract/delegation.d.ts +96 -0
  64. package/dist/contract/discovery.d.ts +7 -0
  65. package/dist/contract/github.d.ts +1 -0
  66. package/dist/contract/health.d.ts +6 -0
  67. package/dist/contract/index.d.ts +3 -0
  68. package/dist/contract/index.js +1445 -745
  69. package/dist/contract/preview.d.ts +508 -0
  70. package/dist/contract/runs.d.ts +716 -15
  71. package/dist/contract/skills.d.ts +39 -0
  72. package/dist/contract/workflows.d.ts +6 -0
  73. package/dist/contract/workspace.d.ts +65 -0
  74. package/dist/contract/zoned-time.d.ts +35 -0
  75. package/dist/core/agent-env.d.ts +11 -0
  76. package/dist/core/agent-env.js +27 -5
  77. package/dist/core/agent-env.js.map +1 -1
  78. package/dist/core/agent-profiles.js +7 -0
  79. package/dist/core/agent-profiles.js.map +1 -1
  80. package/dist/core/agent-runner.d.ts +49 -1
  81. package/dist/core/agent-runner.js +2 -1
  82. package/dist/core/agent-runner.js.map +1 -1
  83. package/dist/core/backend-detect.d.ts +3 -2
  84. package/dist/core/backend-detect.js +27 -1
  85. package/dist/core/backend-detect.js.map +1 -1
  86. package/dist/core/claude-cli-runner.d.ts +1 -0
  87. package/dist/core/claude-cli-runner.js +69 -19
  88. package/dist/core/claude-cli-runner.js.map +1 -1
  89. package/dist/core/codex-app-server-runner.d.ts +1 -0
  90. package/dist/core/codex-app-server-runner.js +200 -25
  91. package/dist/core/codex-app-server-runner.js.map +1 -1
  92. package/dist/core/codex-app-server-transport.d.ts +7 -3
  93. package/dist/core/codex-app-server-transport.js +11 -9
  94. package/dist/core/codex-app-server-transport.js.map +1 -1
  95. package/dist/core/cursor-acp-runner.d.ts +1 -0
  96. package/dist/core/cursor-acp-runner.js +24 -9
  97. package/dist/core/cursor-acp-runner.js.map +1 -1
  98. package/dist/core/host-model-catalog.js +2 -0
  99. package/dist/core/host-model-catalog.js.map +1 -1
  100. package/dist/core/managed-session.js +2 -0
  101. package/dist/core/managed-session.js.map +1 -1
  102. package/dist/core/model-identity.js +2 -0
  103. package/dist/core/model-identity.js.map +1 -1
  104. package/dist/core/model-presets.js +3 -0
  105. package/dist/core/model-presets.js.map +1 -1
  106. package/dist/core/omp-model-catalog.d.ts +43 -0
  107. package/dist/core/omp-model-catalog.js +205 -0
  108. package/dist/core/omp-model-catalog.js.map +1 -0
  109. package/dist/core/omp-runner.d.ts +73 -0
  110. package/dist/core/omp-runner.js +990 -0
  111. package/dist/core/omp-runner.js.map +1 -0
  112. package/dist/core/omp-ui-mapper.d.ts +106 -0
  113. package/dist/core/omp-ui-mapper.js +882 -0
  114. package/dist/core/omp-ui-mapper.js.map +1 -0
  115. package/dist/core/opencode-server-runner.d.ts +18 -4
  116. package/dist/core/opencode-server-runner.js +337 -96
  117. package/dist/core/opencode-server-runner.js.map +1 -1
  118. package/dist/core/opencode-session-error.d.ts +11 -0
  119. package/dist/core/opencode-session-error.js +26 -0
  120. package/dist/core/opencode-session-error.js.map +1 -0
  121. package/dist/core/opencode-ui-mapper.js +4 -36
  122. package/dist/core/opencode-ui-mapper.js.map +1 -1
  123. package/dist/core/pi-runner.d.ts +1 -0
  124. package/dist/core/pi-runner.js +75 -12
  125. package/dist/core/pi-runner.js.map +1 -1
  126. package/dist/core/provider-auth.d.ts +9 -2
  127. package/dist/core/provider-auth.js +43 -6
  128. package/dist/core/provider-auth.js.map +1 -1
  129. package/dist/core/runner-factory.js +3 -0
  130. package/dist/core/runner-factory.js.map +1 -1
  131. package/dist/core/runner-model-catalog.js +1 -0
  132. package/dist/core/runner-model-catalog.js.map +1 -1
  133. package/dist/core/runner-stderr.d.ts +2 -0
  134. package/dist/core/runner-stderr.js +20 -0
  135. package/dist/core/runner-stderr.js.map +1 -0
  136. package/dist/core/session-process.d.ts +22 -0
  137. package/dist/core/session-process.js +202 -0
  138. package/dist/core/session-process.js.map +1 -0
  139. package/dist/core/ui-events.d.ts +1 -1
  140. package/dist/core/usage-limit.js +3 -60
  141. package/dist/core/usage-limit.js.map +1 -1
  142. package/dist/data-gitignore.d.ts +6 -0
  143. package/dist/data-gitignore.js +57 -0
  144. package/dist/data-gitignore.js.map +1 -0
  145. package/dist/delegation/capacity.d.ts +19 -0
  146. package/dist/delegation/capacity.js +34 -0
  147. package/dist/delegation/capacity.js.map +1 -0
  148. package/dist/delegation/cli.js +13 -4
  149. package/dist/delegation/cli.js.map +1 -1
  150. package/dist/delegation/conversations.d.ts +4 -2
  151. package/dist/delegation/conversations.js +8 -12
  152. package/dist/delegation/conversations.js.map +1 -1
  153. package/dist/delegation/credentials.d.ts +2 -0
  154. package/dist/delegation/credentials.js +10 -0
  155. package/dist/delegation/credentials.js.map +1 -1
  156. package/dist/delegation/destroy-observation.d.ts +42 -0
  157. package/dist/delegation/destroy-observation.js +115 -0
  158. package/dist/delegation/destroy-observation.js.map +1 -0
  159. package/dist/delegation/execution-identity.d.ts +6 -0
  160. package/dist/delegation/execution-identity.js +1 -1
  161. package/dist/delegation/execution-identity.js.map +1 -1
  162. package/dist/delegation/policy.d.ts +3 -2
  163. package/dist/delegation/policy.js +7 -5
  164. package/dist/delegation/policy.js.map +1 -1
  165. package/dist/delegation/process-liveness.d.ts +57 -20
  166. package/dist/delegation/process-liveness.js +114 -92
  167. package/dist/delegation/process-liveness.js.map +1 -1
  168. package/dist/delegation/provision.js +6 -6
  169. package/dist/delegation/provision.js.map +1 -1
  170. package/dist/delegation/results.js +4 -2
  171. package/dist/delegation/results.js.map +1 -1
  172. package/dist/delegation/retry-backoff.d.ts +23 -0
  173. package/dist/delegation/retry-backoff.js +18 -0
  174. package/dist/delegation/retry-backoff.js.map +1 -0
  175. package/dist/delegation/routes.d.ts +64 -58
  176. package/dist/delegation/scratch-cleanup.d.ts +29 -0
  177. package/dist/delegation/scratch-cleanup.js +143 -0
  178. package/dist/delegation/scratch-cleanup.js.map +1 -0
  179. package/dist/delegation/service.d.ts +20 -1
  180. package/dist/delegation/service.js +233 -70
  181. package/dist/delegation/service.js.map +1 -1
  182. package/dist/delegation/transport.d.ts +12 -6
  183. package/dist/delegation/workspace.d.ts +23 -4
  184. package/dist/delegation/workspace.js +147 -31
  185. package/dist/delegation/workspace.js.map +1 -1
  186. package/dist/git-worktree-lock-helper.js +8 -3
  187. package/dist/git-worktree-lock-helper.js.map +1 -1
  188. package/dist/git-worktree-lock.d.ts +6 -1
  189. package/dist/git-worktree-lock.js +10 -4
  190. package/dist/git-worktree-lock.js.map +1 -1
  191. package/dist/git-worktree-release.d.ts +20 -0
  192. package/dist/git-worktree-release.js +27 -0
  193. package/dist/git-worktree-release.js.map +1 -0
  194. package/dist/git-worktree.d.ts +8 -2
  195. package/dist/git-worktree.js +19 -2
  196. package/dist/git-worktree.js.map +1 -1
  197. package/dist/handoff.d.ts +2 -2
  198. package/dist/handoff.js +1 -1
  199. package/dist/index.js +109 -76
  200. package/dist/index.js.map +1 -1
  201. package/dist/paths.d.ts +1 -1
  202. package/dist/paths.js +5 -1
  203. package/dist/paths.js.map +1 -1
  204. package/dist/preview/cdp.d.ts +13 -0
  205. package/dist/preview/cdp.js +69 -0
  206. package/dist/preview/cdp.js.map +1 -0
  207. package/dist/preview/chromium.d.ts +75 -0
  208. package/dist/preview/chromium.js +394 -0
  209. package/dist/preview/chromium.js.map +1 -0
  210. package/dist/preview/dev-server.d.ts +68 -0
  211. package/dist/preview/dev-server.js +341 -0
  212. package/dist/preview/dev-server.js.map +1 -0
  213. package/dist/preview/host.d.ts +154 -0
  214. package/dist/preview/host.js +681 -0
  215. package/dist/preview/host.js.map +1 -0
  216. package/dist/preview/registration.d.ts +63 -0
  217. package/dist/preview/registration.js +109 -0
  218. package/dist/preview/registration.js.map +1 -0
  219. package/dist/preview/session.d.ts +73 -0
  220. package/dist/preview/session.js +347 -0
  221. package/dist/preview/session.js.map +1 -0
  222. package/dist/preview/url.d.ts +6 -0
  223. package/dist/preview/url.js +17 -0
  224. package/dist/preview/url.js.map +1 -0
  225. package/dist/runs/agent-tmpdir-removal.d.ts +15 -0
  226. package/dist/runs/agent-tmpdir-removal.js +60 -0
  227. package/dist/runs/agent-tmpdir-removal.js.map +1 -0
  228. package/dist/runs/agent-tmpdir.d.ts +12 -1
  229. package/dist/runs/agent-tmpdir.js +123 -34
  230. package/dist/runs/agent-tmpdir.js.map +1 -1
  231. package/dist/runs/delegation-state.d.ts +5 -1
  232. package/dist/runs/delegation-state.js +9 -0
  233. package/dist/runs/delegation-state.js.map +1 -1
  234. package/dist/runs/event-history.d.ts +4 -4
  235. package/dist/runs/event-history.js +97 -117
  236. package/dist/runs/event-history.js.map +1 -1
  237. package/dist/runs/history-compressor.d.ts +29 -0
  238. package/dist/runs/history-compressor.js +116 -0
  239. package/dist/runs/history-compressor.js.map +1 -0
  240. package/dist/runs/history-file.d.ts +36 -0
  241. package/dist/runs/history-file.js +463 -0
  242. package/dist/runs/history-file.js.map +1 -0
  243. package/dist/runs/human-ask-summary.js +18 -13
  244. package/dist/runs/human-ask-summary.js.map +1 -1
  245. package/dist/runs/legacy-index.d.ts +62 -0
  246. package/dist/runs/legacy-index.js +168 -0
  247. package/dist/runs/legacy-index.js.map +1 -0
  248. package/dist/runs/raw-record.d.ts +52 -0
  249. package/dist/runs/raw-record.js +145 -0
  250. package/dist/runs/raw-record.js.map +1 -0
  251. package/dist/runs/retention.d.ts +13 -6
  252. package/dist/runs/retention.js +42 -13
  253. package/dist/runs/retention.js.map +1 -1
  254. package/dist/runs/run-claims.d.ts +23 -0
  255. package/dist/runs/run-claims.js +24 -0
  256. package/dist/runs/run-claims.js.map +1 -0
  257. package/dist/runs/run-database.d.ts +385 -0
  258. package/dist/runs/run-database.js +930 -0
  259. package/dist/runs/run-database.js.map +1 -0
  260. package/dist/runs/run-index.d.ts +35 -9
  261. package/dist/runs/run-index.js +200 -25
  262. package/dist/runs/run-index.js.map +1 -1
  263. package/dist/runs/run-row.d.ts +44 -0
  264. package/dist/runs/run-row.js +84 -0
  265. package/dist/runs/run-row.js.map +1 -0
  266. package/dist/runs/run-search.d.ts +29 -0
  267. package/dist/runs/run-search.js +63 -0
  268. package/dist/runs/run-search.js.map +1 -0
  269. package/dist/runs/store-open-error.d.ts +24 -0
  270. package/dist/runs/store-open-error.js +61 -0
  271. package/dist/runs/store-open-error.js.map +1 -0
  272. package/dist/runs/store.d.ts +667 -32
  273. package/dist/runs/store.js +2153 -324
  274. package/dist/runs/store.js.map +1 -1
  275. package/dist/runs/transcript-facts.d.ts +77 -0
  276. package/dist/runs/transcript-facts.js +302 -0
  277. package/dist/runs/transcript-facts.js.map +1 -0
  278. package/dist/runs/webhook.js +5 -4
  279. package/dist/runs/webhook.js.map +1 -1
  280. package/dist/runs/worker-execution.d.ts +22 -0
  281. package/dist/runs/worker-execution.js +30 -0
  282. package/dist/runs/worker-execution.js.map +1 -0
  283. package/dist/server/capabilities.d.ts +1 -0
  284. package/dist/server/capabilities.js +2 -0
  285. package/dist/server/capabilities.js.map +1 -1
  286. package/dist/server/cockpit-ownership.d.ts +8 -0
  287. package/dist/server/cockpit-ownership.js +19 -0
  288. package/dist/server/cockpit-ownership.js.map +1 -1
  289. package/dist/server/forge/github.d.ts +1 -4
  290. package/dist/server/forge/github.js +47 -23
  291. package/dist/server/forge/github.js.map +1 -1
  292. package/dist/server/git.js +1 -1
  293. package/dist/server/git.js.map +1 -1
  294. package/dist/server/open-in-app.js +1 -0
  295. package/dist/server/open-in-app.js.map +1 -1
  296. package/dist/server/preview-socket.d.ts +36 -0
  297. package/dist/server/preview-socket.js +126 -0
  298. package/dist/server/preview-socket.js.map +1 -0
  299. package/dist/server/project-context.d.ts +31 -4
  300. package/dist/server/project-context.js +73 -9
  301. package/dist/server/project-context.js.map +1 -1
  302. package/dist/server/provider-action-gate.js +1 -0
  303. package/dist/server/provider-action-gate.js.map +1 -1
  304. package/dist/server/repo-branches.d.ts +4 -3
  305. package/dist/server/repo-branches.js +5 -4
  306. package/dist/server/repo-branches.js.map +1 -1
  307. package/dist/server/server.d.ts +4500 -2727
  308. package/dist/server/server.js +651 -202
  309. package/dist/server/server.js.map +1 -1
  310. package/dist/server/upgrade-router.d.ts +23 -0
  311. package/dist/server/upgrade-router.js +53 -0
  312. package/dist/server/upgrade-router.js.map +1 -0
  313. package/dist/server/validators.d.ts +6 -1
  314. package/dist/server/validators.js +4 -4
  315. package/dist/server/validators.js.map +1 -1
  316. package/dist/server/ws.d.ts +16 -16
  317. package/dist/server/ws.js +56 -54
  318. package/dist/server/ws.js.map +1 -1
  319. package/dist/skills-remote.d.ts +14 -0
  320. package/dist/skills-remote.js +91 -15
  321. package/dist/skills-remote.js.map +1 -1
  322. package/dist/task-cli/cli.js +40 -16
  323. package/dist/task-cli/cli.js.map +1 -1
  324. package/dist/task-cli/discovery.d.ts +4 -3
  325. package/dist/task-cli/discovery.js +4 -3
  326. package/dist/task-cli/discovery.js.map +1 -1
  327. package/dist/task-cli/http.d.ts +2 -0
  328. package/dist/task-cli/http.js +10 -4
  329. package/dist/task-cli/http.js.map +1 -1
  330. package/dist/task-cli/projections.d.ts +5 -2
  331. package/dist/task-cli/projections.js +13 -0
  332. package/dist/task-cli/projections.js.map +1 -1
  333. package/dist/task-cli/watch.d.ts +15 -2
  334. package/dist/task-cli/watch.js +31 -9
  335. package/dist/task-cli/watch.js.map +1 -1
  336. package/dist/ui-state.d.ts +4 -3
  337. package/dist/ui-state.js +8 -3
  338. package/dist/ui-state.js.map +1 -1
  339. package/dist/workflows/grouped-command.d.ts +31 -0
  340. package/dist/workflows/grouped-command.js +143 -0
  341. package/dist/workflows/grouped-command.js.map +1 -0
  342. package/dist/workflows/run.d.ts +223 -42
  343. package/dist/workflows/run.js +1316 -398
  344. package/dist/workflows/run.js.map +1 -1
  345. package/dist/workflows/types.d.ts +12 -0
  346. package/dist/workflows/types.js +20 -0
  347. package/dist/workflows/types.js.map +1 -1
  348. package/dist/workspace/agent-accounts.d.ts +5 -1
  349. package/dist/workspace/agent-accounts.js +1 -0
  350. package/dist/workspace/agent-accounts.js.map +1 -1
  351. package/dist/workspace/agent-profiles.js +1 -1
  352. package/dist/workspace/agent-profiles.js.map +1 -1
  353. package/dist/workspace/config.d.ts +3 -1
  354. package/dist/workspace/config.js +1 -0
  355. package/dist/workspace/config.js.map +1 -1
  356. package/dist/worktree-setup.d.ts +85 -0
  357. package/dist/worktree-setup.js +164 -0
  358. package/dist/worktree-setup.js.map +1 -0
  359. package/package.json +7 -5
  360. package/scripts/benchmark-run-store-fixture.ts +428 -0
  361. package/scripts/benchmark-run-store.ts +743 -0
  362. package/scripts/benchmark-stuck-destroys.ts +143 -0
  363. package/scripts/mock-autonomous.mjs +11 -0
  364. package/scripts/mock-ci-tool.mjs +20 -5
  365. package/scripts/mock-claude.mjs +110 -1
  366. package/scripts/mock-codex-app-server.mjs +117 -2
  367. package/scripts/mock-codex-coalesce-steer.mjs +59 -0
  368. package/scripts/mock-codex-reverse-steer.mjs +130 -0
  369. package/scripts/mock-cursor-acp.mjs +75 -1
  370. package/scripts/mock-omp-rpc.mjs +605 -0
  371. package/scripts/mock-opencode-serve.mjs +312 -22
  372. package/scripts/mock-pi-rpc.mjs +109 -3
  373. package/scripts/mock-runner-crash.mjs +42 -0
  374. package/scripts/mock-silent-tail.mjs +78 -0
  375. package/scripts/mock-turn-messages.mjs +5 -0
  376. package/scripts/omp-ci-wait.mjs +29 -0
  377. package/scripts/omp-restrict-delegation.yml +4 -0
  378. package/scripts/pi-ci-wait.mjs +12 -9
  379. package/scripts/seed-archive-profile.ts +3 -3
  380. package/web/dist/assets/agent-accounts-CFOBMVHc.js +1 -0
  381. package/web/dist/assets/alert-dialog-BrpNUwMt.js +1 -0
  382. package/web/dist/assets/app-window-CSHwDX9N.js +1 -0
  383. package/web/dist/assets/button-C_rd7CPp.js +43 -0
  384. package/web/dist/assets/compare-variants-D6WXhvXA.js +1 -0
  385. package/web/dist/assets/diff-DrEARXTV.js +3 -0
  386. package/web/dist/assets/diff-controls-B1-j7nFg.js +1 -0
  387. package/web/dist/assets/{diff-view-DPn6bQ5W.js → diff-view-DvGLjdTk.js} +3 -3
  388. package/web/dist/assets/dropdown-menu-BegOZFrj.js +1 -0
  389. package/web/dist/assets/format-DpNe3S0A.js +1 -0
  390. package/web/dist/assets/git-toolbar-Cw4ljmhB.js +1 -0
  391. package/web/dist/assets/github-CfV5sqL0.js +1 -0
  392. package/web/dist/assets/{image-preview-DJ8cgb1Z.js → image-preview-FOEfqpZP.js} +1 -1
  393. package/web/dist/assets/index-DgWWlOLy.js +13 -0
  394. package/web/dist/assets/index-fBFnuvxu.css +1 -0
  395. package/web/dist/assets/{nav-row-styles-3j64kH5s.js → nav-row-styles-vp2JbhuJ.js} +1 -1
  396. package/web/dist/assets/play-CmVAj_fu.js +1 -0
  397. package/web/dist/assets/popover-BohP6WTx.js +1 -0
  398. package/web/dist/assets/preview-pane-connected-qTA5KNoJ.js +3 -0
  399. package/web/dist/assets/preview-state-vuMviq6q.js +1 -0
  400. package/web/dist/assets/prompt-templates-Cubdut_C.js +15 -0
  401. package/web/dist/assets/repo-git-Cf4t5PD0.js +1 -0
  402. package/web/dist/assets/{run-diff-5-RRdcVz.js → run-diff-BpkUW37Z.js} +3 -3
  403. package/web/dist/assets/run-header-68WHf9wV.js +1 -0
  404. package/web/dist/assets/skills-DiVIgKeU.js +1 -0
  405. package/web/dist/assets/square-terminal-B6RYYieR.js +1 -0
  406. package/web/dist/assets/status-dot-CqTJHSP9.js +1 -0
  407. package/web/dist/assets/{tab-link-K0hjzEXR.js → tab-link-B07Hu4QX.js} +1 -1
  408. package/web/dist/assets/task-changes--lQF6EYf.js +1 -0
  409. package/web/dist/assets/task-commits-Cx0qy4DN.js +1 -0
  410. package/web/dist/assets/task-files-D50s-gKW.js +2 -0
  411. package/web/dist/assets/task-github-item-DaqmSwYT.js +1 -0
  412. package/web/dist/assets/task-thread-BPQ64lui.js +7 -0
  413. package/web/dist/assets/{task-thread-Bw_nQuTx.css → task-thread-zNE2Q9E-.css} +1 -1
  414. package/web/dist/assets/textarea-D20O4Pw0.js +1 -0
  415. package/web/dist/assets/thread-state-DWcFMrvb.js +4 -0
  416. package/web/dist/assets/use-hand-to-agent-state-BLIGmwbd.css +1 -0
  417. package/web/dist/assets/use-hand-to-agent-state-Cy9eyyfL.js +1 -0
  418. package/web/dist/assets/{utils-fzNfbPzA.js → utils-JsL3ZsJf.js} +1 -1
  419. package/web/dist/assets/workflows-jwG7uxqi.js +11 -0
  420. package/web/dist/assets/{zoomable-image-CDmZ_Rtl.js → zoomable-image-BJJ64KGc.js} +1 -1
  421. package/web/dist/cezarion-lockup-dark.svg +1 -13
  422. package/web/dist/cezarion-lockup-light.svg +1 -13
  423. package/web/dist/cezarion-mark-dark.svg +1 -12
  424. package/web/dist/cezarion-mark-light.svg +1 -12
  425. package/web/dist/index.html +16 -21
  426. package/web/dist/assets/agent-accounts-CU2ZDv24.js +0 -1
  427. package/web/dist/assets/alert-dialog-C-xYE_dg.js +0 -43
  428. package/web/dist/assets/chevron-right-BENZ-1ZN.js +0 -1
  429. package/web/dist/assets/collapsible-DD9J91Iv.js +0 -1
  430. package/web/dist/assets/compare-variants-5FmqpFSN.js +0 -1
  431. package/web/dist/assets/diff-controls-Bj0YrioE.js +0 -1
  432. package/web/dist/assets/diff-rE8rm75J2.js +0 -3
  433. package/web/dist/assets/diff-stat-BKDCSVfJ.js +0 -1
  434. package/web/dist/assets/dropdown-menu-Ch5BYQh_.js +0 -1
  435. package/web/dist/assets/format-dBiNDNVe.js +0 -1
  436. package/web/dist/assets/git-toolbar-ClVvf5iF.js +0 -1
  437. package/web/dist/assets/github-BkNOyour.css +0 -1
  438. package/web/dist/assets/github-DeZMeMwJ.js +0 -1
  439. package/web/dist/assets/github-item-detail-W5F6GVjF.js +0 -1
  440. package/web/dist/assets/github-sidebar-model-DcMu-IK2.js +0 -1
  441. package/web/dist/assets/highlighter-CdHqIwFr.js +0 -3
  442. package/web/dist/assets/index-CatemBEL.js +0 -8
  443. package/web/dist/assets/index-MvfD8bZJ.css +0 -1
  444. package/web/dist/assets/markdown-zdKeLIYA.js +0 -2
  445. package/web/dist/assets/mobile-run-bar-BCfmFi8V.js +0 -1
  446. package/web/dist/assets/prompt-templates-CBPp39IU.js +0 -15
  447. package/web/dist/assets/reference-chip-D6owncJT.js +0 -1
  448. package/web/dist/assets/repo-git-CtdkZFey.js +0 -1
  449. package/web/dist/assets/run-header-BcjoDi0W.js +0 -1
  450. package/web/dist/assets/sheet-ChnYVrp1.js +0 -1
  451. package/web/dist/assets/skills-C8YKp2vr.js +0 -1
  452. package/web/dist/assets/task-changes-BW8YdWG8.js +0 -1
  453. package/web/dist/assets/task-commits-q2kB2y6L.js +0 -1
  454. package/web/dist/assets/task-files-pPL6_3Cr.js +0 -2
  455. package/web/dist/assets/task-github-item-BXF5R52U.js +0 -1
  456. package/web/dist/assets/task-thread-DtkFL3EC.js +0 -10
  457. package/web/dist/assets/textarea-DxlkE-Yd.js +0 -1
  458. package/web/dist/assets/token-metrics-DIAjrPlM.js +0 -1
  459. package/web/dist/assets/use-desktop-CrDny2uG.js +0 -1
  460. package/web/dist/assets/use-submit-shortcut-KWJsC906.js +0 -1
  461. package/web/dist/assets/workflows-TmcPEj2K.js +0 -11
  462. /package/web/dist/assets/{lib-BQXq3kEf2.js → lib-BQXq3kEf.js} +0 -0
@@ -0,0 +1,326 @@
1
+ import { nextOccurrence, occurrencesBetween } from '../contract/index.js';
2
+ import { isScheduleAutomation } from './types.js';
3
+ /**
4
+ * The schedule kind's evaluator (spec 2026-10-02-scheduled-automations § Lifecycle): what fires
5
+ * when a scheduled automation's occurrence comes due, by the timer or by hand.
6
+ *
7
+ * The one rule that matters is the AGE rule in `fire`: how late the occurrence is decides what
8
+ * happens — on time (within the grace window) it is `launched`; late but within a day, the
9
+ * LATEST missed occurrence fires once as `catch-up`; older, nothing fires and the log says how
10
+ * many were skipped. The same rule applies whether the timer fired on time, the laptop slept, or
11
+ * cezar just booted, and `nextRunAt` always advances from `max(occurrence, now)` — which is what
12
+ * makes a burst impossible: a daily that slept three days fires one catch-up, not three.
13
+ *
14
+ * Everything runs under the #651 project lease. A held (or lost) lease is the one case that
15
+ * must NOT advance `nextRunAt`: the state file is shared, so the loser moving it on would make
16
+ * the winner — firing from the same on-disk state — skip the occurrence entirely. The loser logs
17
+ * `skipped` and throws `ScheduleLeaseHeldError`, so the workspace floor retries it; by then the
18
+ * winner's receipt turns the retry into a `duplicate`, never a second launch. Held leases and
19
+ * duplicates are not failures and do not count towards the three-strike auto-pause.
20
+ */
21
+ export const SCHEDULE_GRACE_MS = 10 * 60_000;
22
+ export const SCHEDULE_CATCH_UP_MS = 24 * 60 * 60_000;
23
+ export const SCHEDULE_AUTO_PAUSE_AFTER = 3;
24
+ /** The cap the missed-occurrence count runs under: a count that reaches it is a lower bound. */
25
+ const OCCURRENCE_LIMIT = 1_000;
26
+ export const SCHEDULE_LEASE_HELD_REASON = 'automation lease is held by another process; retrying shortly';
27
+ /** `fire` met a held or non-current lease; the workspace timer re-arms it at the retry floor. */
28
+ export class ScheduleLeaseHeldError extends Error {
29
+ constructor() { super(SCHEDULE_LEASE_HELD_REASON); }
30
+ }
31
+ /** The project cannot launch a task now: its run store cannot open (#779). Not a launch failure,
32
+ * so it never counts towards the auto-pause or a poll's backoff; the timer retries at its floor. */
33
+ export class AutomationProjectUnavailableError extends Error {
34
+ constructor(message, options = {}) {
35
+ super(message, options);
36
+ this.name = 'AutomationProjectUnavailableError';
37
+ }
38
+ }
39
+ export class ScheduleRunner {
40
+ handle;
41
+ constructor(handle) {
42
+ this.handle = handle;
43
+ }
44
+ now() {
45
+ return this.handle.now?.() ?? Date.now();
46
+ }
47
+ /**
48
+ * When the timer should next fire this definition: the stored `nextRunAt`, or — for a
49
+ * definition never armed, or whose schedule was edited (the PUT clears `nextRunAt`) — the next
50
+ * occurrence after now, which is then persisted so every process agrees on it.
51
+ */
52
+ dueAt(definition) {
53
+ const state = this.handle.store.state(definition.id) ?? {};
54
+ if (state.nextRunAt)
55
+ return Date.parse(state.nextRunAt);
56
+ const next = nextOccurrence(definition.schedule, this.now(), this.handle.timeZone);
57
+ if (next === null)
58
+ return null;
59
+ this.handle.store.setState(definition.id, (current) => ({ ...current, revision: definition.revision, nextRunAt: new Date(next).toISOString() }));
60
+ return next;
61
+ }
62
+ /** The timer fired (or boot found a past-due occurrence): apply the age rule and launch. */
63
+ async fire(definition) {
64
+ const outcome = await this.underLease(async () => {
65
+ // The timer captured `definition` from this process's view; another cockpit may have
66
+ // paused, edited or deleted it since. Re-read it under the lease and fire only the
67
+ // revision that is still on disk. Anything else launches nothing and moves nothing —
68
+ // the process that changed it owns `nextRunAt` — and `onChange` re-arms from the fresh view.
69
+ this.handle.store.reload();
70
+ const current = this.handle.store.get(definition.id);
71
+ if (!current?.enabled || !isScheduleAutomation(current) || current.revision !== definition.revision) {
72
+ this.handle.onChange?.(definition.id, current?.revision ?? definition.revision);
73
+ return { result: 'skipped' };
74
+ }
75
+ const now = this.now();
76
+ const due = this.dueAt(definition);
77
+ if (due === null)
78
+ return { result: 'skipped' };
79
+ const advance = { armedAt: this.handle.store.state(definition.id)?.nextRunAt };
80
+ // Not due yet: another cockpit (or a PUT) moved `nextRunAt` after this fire was armed.
81
+ if (due > now)
82
+ return { result: 'skipped', occurrenceAt: new Date(due).toISOString() };
83
+ if (now - due <= SCHEDULE_GRACE_MS) {
84
+ await this.handle.ready?.();
85
+ return this.launch(definition, { at: new Date(due).toISOString(), trigger: 'schedule' }, now, advance);
86
+ }
87
+ // Late. Every occurrence from the due one up to now was missed; the newest may catch up.
88
+ const missed = this.missed(definition, due, now);
89
+ const latest = missed.latest;
90
+ if (now - latest <= SCHEDULE_CATCH_UP_MS) {
91
+ await this.handle.ready?.();
92
+ if (missed.count > 1)
93
+ await this.logSkipped(definition, missed.count - 1, missed.atLeast, true);
94
+ return this.launch(definition, { at: new Date(latest).toISOString(), trigger: 'catch-up' }, now, advance);
95
+ }
96
+ await this.logSkipped(definition, missed.count, missed.atLeast, false);
97
+ this.advance(definition, now, now, advance);
98
+ return { result: 'skipped', occurrenceAt: new Date(latest).toISOString() };
99
+ });
100
+ if (outcome)
101
+ return outcome;
102
+ await this.handle.store.appendLog({ automationId: definition.id, revision: definition.revision, result: 'skipped', reason: SCHEDULE_LEASE_HELD_REASON });
103
+ this.handle.onChange?.(definition.id, definition.revision);
104
+ throw new ScheduleLeaseHeldError();
105
+ }
106
+ /** `POST /automations/:id/run`: fire now, by hand, paused or not; `nextRunAt` is untouched. */
107
+ async runNow(definition) {
108
+ const outcome = await this.underLease(async () => {
109
+ const current = this.currentUnderLease(definition);
110
+ if (!current)
111
+ return { result: 'skipped' };
112
+ const now = this.now();
113
+ return this.launch(current, { at: new Date(now).toISOString(), trigger: 'manual' }, now, null);
114
+ });
115
+ return outcome ?? { result: 'lease-held' };
116
+ }
117
+ /** Retry a `launch-error` receipt of this kind: the same receipt, fired again by hand. */
118
+ async retry(definition, receipt) {
119
+ const occurrenceAt = receipt.occurrenceAt ?? new Date(this.now()).toISOString();
120
+ const outcome = await this.underLease(async () => {
121
+ const current = this.currentUnderLease(definition);
122
+ if (!current)
123
+ return { result: 'skipped', occurrenceAt };
124
+ const now = this.now();
125
+ // Re-checked under the lease: another retry may have relaunched it since the caller read it.
126
+ if (this.handle.store.latestReceipts().get(receipt.receiptKey)?.status !== 'launch-error') {
127
+ return { result: 'duplicate', occurrenceAt };
128
+ }
129
+ const reserved = { ...receipt, status: 'reserved', error: undefined, updatedAt: new Date(now).toISOString() };
130
+ this.handle.store.appendReceipt(reserved);
131
+ return this.launchReserved(current, { at: occurrenceAt, trigger: 'manual' }, reserved, now, null);
132
+ });
133
+ return outcome ?? { result: 'lease-held', occurrenceAt };
134
+ }
135
+ /**
136
+ * Run now and Retry act on this process's cached definition, which another cockpit may have
137
+ * edited or deleted since. Re-read it under the lease: the fresh schedule definition (paused is
138
+ * fine, those are manual actions), or `undefined` after notifying when it is gone or no longer
139
+ * a schedule, so the caller launches and writes nothing.
140
+ */
141
+ currentUnderLease(definition) {
142
+ this.handle.store.reload();
143
+ const current = this.handle.store.get(definition.id);
144
+ if (current && isScheduleAutomation(current))
145
+ return current;
146
+ this.handle.onChange?.(definition.id, current?.revision ?? definition.revision);
147
+ return undefined;
148
+ }
149
+ /** Runs `operation` under the project lease; `undefined` when the lease is held or not current. */
150
+ async underLease(operation) {
151
+ const { store } = this.handle;
152
+ let lease = store.acquireLease();
153
+ if (lease && !lease.isCurrent()) {
154
+ lease.release();
155
+ lease = undefined;
156
+ }
157
+ if (!lease)
158
+ return undefined;
159
+ try {
160
+ return await operation();
161
+ }
162
+ finally {
163
+ try {
164
+ await store.maybeCompact();
165
+ }
166
+ catch { /* append-only state remains readable; next fire retries */ }
167
+ lease.release();
168
+ }
169
+ }
170
+ async launch(definition, occurrence, now, advance) {
171
+ const { store } = this.handle;
172
+ const eventId = occurrence.trigger === 'manual' ? `manual:${occurrence.at}` : `schedule:${occurrence.at}`;
173
+ const receipt = store.reserveReceipt({ automationId: definition.id, revision: definition.revision, eventId, occurrenceAt: occurrence.at });
174
+ if (!receipt) {
175
+ // Under the lease nobody else is launching, so a `reserved` receipt this process is not
176
+ // running is a crash leftover: settle it first (see `reconcile`). One in flight here is a
177
+ // live launch its launcher settles, and is left alone.
178
+ const existing = store.latestReceipts().get(`${definition.id}:${eventId}`);
179
+ if (existing?.status === 'reserved' && !store.isReservationInFlight(existing.receiptId))
180
+ await this.handle.reconcile?.();
181
+ await store.appendLog({ automationId: definition.id, revision: definition.revision, result: 'duplicate', reason: `A durable receipt already exists for the ${occurrence.at} occurrence.` });
182
+ if (advance)
183
+ this.advance(definition, Date.parse(occurrence.at), now, advance);
184
+ return { result: 'duplicate', occurrenceAt: occurrence.at };
185
+ }
186
+ return this.launchReserved(definition, occurrence, receipt, now, advance);
187
+ }
188
+ async launchReserved(definition, occurrence, receipt, now, advance) {
189
+ const { store } = this.handle;
190
+ if (!this.handle.launch) {
191
+ store.appendReceipt({ ...receipt, status: 'launch-error', error: 'This cockpit cannot launch tasks.', updatedAt: new Date(now).toISOString() });
192
+ if (advance)
193
+ this.advance(definition, Date.parse(occurrence.at), now, advance);
194
+ return { result: 'detection-only', occurrenceAt: occurrence.at };
195
+ }
196
+ const started = Date.now();
197
+ const result = occurrence.trigger === 'schedule' ? 'launched' : occurrence.trigger;
198
+ let runId;
199
+ try {
200
+ ({ runId } = await this.handle.launch(definition, occurrence, receipt.receiptId));
201
+ }
202
+ catch (error) {
203
+ const message = error instanceof Error ? error.message : String(error);
204
+ store.appendReceipt({ ...receipt, status: 'launch-error', error: message, updatedAt: new Date(this.now()).toISOString() });
205
+ await store.appendLog({ automationId: definition.id, revision: definition.revision, result: 'failed', reason: message, receiptId: receipt.receiptId, durationMs: Date.now() - started });
206
+ // Only the timer counts towards the auto-pause: Run now and Retry leave `enabled` alone.
207
+ if (advance)
208
+ await this.recordFailure(definition, occurrence, now, advance);
209
+ else
210
+ this.handle.onChange?.(definition.id, definition.revision);
211
+ return { result: 'failed', occurrenceAt: occurrence.at };
212
+ }
213
+ store.appendReceipt({ ...receipt, status: 'launched', runId, updatedAt: new Date(this.now()).toISOString() });
214
+ await store.appendLog({
215
+ automationId: definition.id, revision: definition.revision, result,
216
+ reason: reasonFor(occurrence, this.handle.timeZone),
217
+ receiptId: receipt.receiptId, runId, durationMs: Date.now() - started,
218
+ });
219
+ store.setState(definition.id, (current) => ({
220
+ ...current,
221
+ ...(advance ? { ...this.advanced(current, definition, Date.parse(occurrence.at), now, advance), lastRunAt: occurrence.at } : { revision: Math.max(current.revision ?? 0, definition.revision) }),
222
+ lastSuccessAt: new Date(this.now()).toISOString(),
223
+ consecutiveFailures: 0,
224
+ }));
225
+ this.handle.onChange?.(definition.id, definition.revision);
226
+ return { result, runId, occurrenceAt: occurrence.at };
227
+ }
228
+ async recordFailure(definition, occurrence, now, advance) {
229
+ const { store } = this.handle;
230
+ const next = store.setState(definition.id, (current) => ({
231
+ ...current,
232
+ ...this.advanced(current, definition, Date.parse(occurrence.at), now, advance),
233
+ consecutiveFailures: (current.consecutiveFailures ?? 0) + 1,
234
+ }));
235
+ if ((next.consecutiveFailures ?? 0) >= SCHEDULE_AUTO_PAUSE_AFTER) {
236
+ const paused = this.pause(definition.id);
237
+ if (paused) {
238
+ await store.appendLog({ automationId: paused.id, revision: paused.revision, result: 'failed', reason: `Paused after ${SCHEDULE_AUTO_PAUSE_AFTER} consecutive launch failures; fix the task and enable it again.` });
239
+ this.handle.onChange?.(paused.id, paused.revision);
240
+ return;
241
+ }
242
+ }
243
+ this.handle.onChange?.(definition.id, definition.revision);
244
+ }
245
+ /**
246
+ * Pauses the CURRENT revision, not the one this fire started with: the definition may have been
247
+ * edited while the launch ran — here or in another cockpit, hence the re-read — and the failure
248
+ * count belongs to the automation, not to a revision. Pausing the stale copy would either
249
+ * conflict or revert the edit. Already paused, deleted or no longer a schedule: nothing to do.
250
+ */
251
+ pause(id) {
252
+ this.handle.store.reload();
253
+ const current = this.handle.store.get(id);
254
+ if (!current?.enabled || current.kind !== 'schedule')
255
+ return undefined;
256
+ const { revision, createdAt: _c, updatedAt: _u, id: _id, ...editable } = current;
257
+ try {
258
+ return this.handle.store.update(id, revision, { ...editable, enabled: false }, () => ({ nextRunAt: undefined }));
259
+ }
260
+ catch {
261
+ // Edited or deleted in between; the next failure pauses whatever is current then.
262
+ return undefined;
263
+ }
264
+ }
265
+ advance(definition, fromMs, now, advance) {
266
+ this.handle.store.setState(definition.id, (current) => ({
267
+ ...current,
268
+ ...this.advanced(current, definition, fromMs, now, advance),
269
+ }));
270
+ this.handle.onChange?.(definition.id, definition.revision);
271
+ }
272
+ /**
273
+ * The `revision`/`nextRunAt` pair a timer fire writes. An edit that landed meanwhile already
274
+ * bumped the state's revision (never moved back) and, when it changed the schedule or resumed
275
+ * the definition, re-armed `nextRunAt` — which then stands. An edit that left `nextRunAt`
276
+ * alone (a rename) left the schedule alone too, so advancing from the captured one is right.
277
+ */
278
+ advanced(current, definition, fromMs, now, advance) {
279
+ const revision = Math.max(current.revision ?? 0, definition.revision);
280
+ if (current.nextRunAt !== advance.armedAt)
281
+ return { revision, nextRunAt: current.nextRunAt };
282
+ return { revision, nextRunAt: nextIso(definition, Math.max(fromMs, now), this.handle.timeZone) };
283
+ }
284
+ /**
285
+ * The occurrences in `[due, now]`: the latest one and how many there are. `occurrencesBetween`
286
+ * stops at its cap EARLIEST-first, so the latest is searched for on its own — in the catch-up
287
+ * window, else in the week before it (every shape recurs within 7 days; 9 covers a DST week) —
288
+ * and a count that reached the cap is reported as a lower bound, never as an exact number.
289
+ */
290
+ missed(definition, due, now) {
291
+ const { schedule } = definition;
292
+ const { timeZone } = this.handle;
293
+ const windowStart = Math.max(due, now - SCHEDULE_CATCH_UP_MS);
294
+ const recent = occurrencesBetween(schedule, windowStart, now + 1, timeZone);
295
+ const older = occurrencesBetween(schedule, due, windowStart, timeZone, OCCURRENCE_LIMIT);
296
+ const latest = recent.at(-1)
297
+ ?? occurrencesBetween(schedule, Math.max(due, windowStart - 9 * 86_400_000), windowStart, timeZone).at(-1)
298
+ ?? due;
299
+ return { latest, count: recent.length + older.length, atLeast: older.length >= OCCURRENCE_LIMIT };
300
+ }
301
+ async logSkipped(definition, total, atLeast, latestCaughtUp) {
302
+ const count = atLeast ? `at least ${total}` : String(total);
303
+ const plural = total === 1 ? '' : 's';
304
+ await this.handle.store.appendLog({
305
+ automationId: definition.id,
306
+ revision: definition.revision,
307
+ result: 'skipped',
308
+ reason: latestCaughtUp
309
+ ? `Missed ${count} older occurrence${plural} while cezar was not running or the machine was asleep; only the latest one caught up.`
310
+ : `Missed ${count} occurrence${plural} while cezar was not running or the machine was asleep; nothing was launched for them.`,
311
+ });
312
+ }
313
+ }
314
+ function nextIso(definition, afterMs, timeZone) {
315
+ const next = nextOccurrence(definition.schedule, afterMs, timeZone);
316
+ return next === null ? undefined : new Date(next).toISOString();
317
+ }
318
+ function reasonFor(occurrence, timeZone) {
319
+ const when = new Intl.DateTimeFormat('en-GB', { timeZone, weekday: 'short', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }).format(new Date(occurrence.at));
320
+ switch (occurrence.trigger) {
321
+ case 'schedule': return `Scheduled run at ${when}.`;
322
+ case 'catch-up': return `Caught up the ${when} occurrence missed while cezar was not running or the machine was asleep.`;
323
+ case 'manual': return `Started by hand at ${when}.`;
324
+ }
325
+ }
326
+ //# sourceMappingURL=schedule-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-runner.js","sourceRoot":"","sources":["../../src/automations/schedule-runner.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,35 @@
1
1
  import type { AutomationCoordinator } from './coordinator.ts';
2
2
  import type { GithubCandidate, GithubPoller, GithubPollResult } from './github-poller.ts';
3
+ import { type ScheduleLauncher } from './schedule-runner.ts';
3
4
  import type { AutomationStore } from './store.ts';
4
- import type { AutomationDefinition } from './types.ts';
5
+ import { type GithubAutomationDefinition } from './types.ts';
5
6
  export interface AutomationLaunchResult {
6
7
  runId: string;
7
8
  }
8
- export type AutomationLauncher = (definition: AutomationDefinition, candidate: GithubCandidate, receiptId: string) => Promise<AutomationLaunchResult>;
9
+ export type AutomationLauncher = (definition: GithubAutomationDefinition, candidate: GithubCandidate, receiptId: string) => Promise<AutomationLaunchResult>;
10
+ /**
11
+ * Everything one project needs on the workspace timer. Every registered project gets one; only a
12
+ * project with a github.com remote carries `github`, so its polls can fire — a schedule needs no
13
+ * remote (spec 2026-10-02-scheduled-automations § Architecture).
14
+ */
9
15
  export interface ProjectAutomationHandle {
10
16
  projectId: string;
11
- owner: string;
12
- repo: string;
13
17
  store: AutomationStore;
14
- poller: GithubPoller;
18
+ /** The zone schedules are evaluated in — the server's own (`localTimeZone()`). */
19
+ timeZone: string;
20
+ github?: {
21
+ owner: string;
22
+ repo: string;
23
+ poller: GithubPoller;
24
+ };
15
25
  launch?: AutomationLauncher;
26
+ launchSchedule?: ScheduleLauncher;
16
27
  onChange?: (automationId: string, revision: number) => void;
28
+ now?: () => number;
29
+ /** See `ScheduleRunnerHandle.reconcile`. */
30
+ reconcileReceipts?: () => Promise<void>;
31
+ /** See `ScheduleRunnerHandle.ready`; a poll asks it before it launches what it found. */
32
+ ready?: () => Promise<void>;
17
33
  }
18
34
  /** A different process currently owns this project's poll lock. */
19
35
  export declare class LeaseHeldError extends Error {
@@ -22,17 +38,32 @@ export declare class LeaseHeldError extends Error {
22
38
  export declare class ProjectAutomationScheduler {
23
39
  private readonly handle;
24
40
  constructor(handle: ProjectAutomationHandle);
25
- check(definition: AutomationDefinition, mode?: 'preview' | 'execute'): Promise<GithubPollResult>;
41
+ check(definition: GithubAutomationDefinition, mode?: 'preview' | 'execute'): Promise<GithubPollResult>;
26
42
  private launch;
27
43
  private recordSkip;
28
44
  private recordFailure;
29
45
  }
46
+ /**
47
+ * The longest the workspace timer sleeps before it looks at the wall clock again. Node timers
48
+ * count on a monotonic clock that stops while the machine is suspended, so one timer armed for
49
+ * the whole distance to a weekly occurrence would wake days late after a laptop slept. A capped
50
+ * wake that is not yet due re-arms without firing; the cap also keeps every delay far below
51
+ * `setTimeout`'s 2^31 ms overflow.
52
+ */
53
+ export declare const WORKSPACE_TIMER_CAP_MS = 60000;
30
54
  export interface WorkspaceAutomationSchedulerOptions {
31
55
  coordinator: AutomationCoordinator;
32
56
  handle: (projectId: string, store: AutomationStore) => ProjectAutomationHandle | undefined;
33
57
  now?: () => number;
34
58
  }
35
- /** One workspace timer, created only while at least one enabled definition exists. */
59
+ /**
60
+ * One workspace timer, running only while the scheduler is started (automations are opt-in) and at
61
+ * least one project is registered with the coordinator. With nothing enabled it is an idle wake
62
+ * at the cap, even before any project has a definitions file: every wake goes through
63
+ * `reschedule`, whose coordinator refresh re-reads a store another cockpit changed and opens a
64
+ * project whose definitions file appeared, so their edits arm here within one cap. No registered
65
+ * project: no timer.
66
+ */
36
67
  export declare class WorkspaceAutomationScheduler {
37
68
  private readonly options;
38
69
  private timer?;
@@ -1,3 +1,5 @@
1
+ import { AutomationProjectUnavailableError, ScheduleRunner } from './schedule-runner.js';
2
+ import { isGithubAutomation, isScheduleAutomation } from './types.js';
1
3
  /** One request chain process-wide. The promise tail also prevents a failed request from
2
4
  * poisoning later projects. */
3
5
  class GithubRequestArbiter {
@@ -19,6 +21,9 @@ export class ProjectAutomationScheduler {
19
21
  this.handle = handle;
20
22
  }
21
23
  async check(definition, mode = 'execute') {
24
+ const { github } = this.handle;
25
+ if (!github)
26
+ throw new Error('No GitHub remote is configured');
22
27
  const detectionOnly = mode === 'execute' && !this.handle.launch;
23
28
  if (detectionOnly)
24
29
  mode = 'preview';
@@ -38,7 +43,7 @@ export class ProjectAutomationScheduler {
38
43
  const overlapSince = since
39
44
  ? new Date(Date.parse(since) - 120_000).toISOString()
40
45
  : undefined;
41
- const result = await githubRequests.run(() => this.handle.poller.poll(this.handle.owner, this.handle.repo, definition, { since: overlapSince }));
46
+ const result = await githubRequests.run(() => github.poller.poll(github.owner, github.repo, definition, { since: overlapSince }));
42
47
  const eligible = result.candidates.filter((candidate) => {
43
48
  if (state.baselineAt && candidate.timestamp <= state.baselineAt)
44
49
  return false;
@@ -48,14 +53,16 @@ export class ProjectAutomationScheduler {
48
53
  return Date.parse(candidate.timestamp) >= overlap;
49
54
  });
50
55
  if (mode === 'execute' && this.handle.launch) {
56
+ if (eligible.length > 0)
57
+ await this.handle.ready?.();
51
58
  for (const candidate of eligible)
52
59
  await this.launch(definition, candidate);
53
60
  }
54
61
  if (mode === 'execute') {
55
62
  const now = new Date().toISOString();
56
63
  const cursor = laterCursor(state.cursor, result.cursor);
57
- store.setState(definition.id, {
58
- ...state,
64
+ store.setState(definition.id, (current) => ({
65
+ ...current,
59
66
  revision: definition.revision,
60
67
  cursor,
61
68
  frozenHighWatermark: result.truncated && cursor?.tieBreaker
@@ -65,14 +72,14 @@ export class ProjectAutomationScheduler {
65
72
  nextCheckAt: new Date(Date.now() + definition.intervalSeconds * 1_000).toISOString(),
66
73
  consecutiveFailures: 0,
67
74
  backoffUntil: undefined,
68
- });
75
+ }));
69
76
  }
70
77
  else if (detectionOnly) {
71
- store.setState(definition.id, {
72
- ...state,
78
+ store.setState(definition.id, (current) => ({
79
+ ...current,
73
80
  revision: definition.revision,
74
81
  nextCheckAt: new Date(Date.now() + definition.intervalSeconds * 1_000).toISOString(),
75
- });
82
+ }));
76
83
  }
77
84
  this.handle.onChange?.(definition.id, definition.revision);
78
85
  completion = mode === 'preview'
@@ -83,6 +90,8 @@ export class ProjectAutomationScheduler {
83
90
  catch (error) {
84
91
  if (error instanceof LeaseHeldError)
85
92
  await this.recordSkip(definition, error);
93
+ // Not a failure: nothing was launched or moved, and the timer retries at its floor.
94
+ else if (error instanceof AutomationProjectUnavailableError) { /* see above */ }
86
95
  else if (mode === 'execute')
87
96
  await this.recordFailure(definition, error);
88
97
  else
@@ -128,14 +137,15 @@ export class ProjectAutomationScheduler {
128
137
  this.handle.onChange?.(definition.id, definition.revision);
129
138
  }
130
139
  async recordFailure(definition, error) {
131
- const state = this.handle.store.state(definition.id) ?? {};
132
- const failures = (state.consecutiveFailures ?? 0) + 1;
133
- const delay = Math.min(6 * 60 * 60_000, 60_000 * 2 ** (failures - 1));
134
- this.handle.store.setState(definition.id, {
135
- ...state,
136
- consecutiveFailures: failures,
137
- backoffUntil: new Date(Date.now() + delay).toISOString(),
138
- nextCheckAt: new Date(Date.now() + delay).toISOString(),
140
+ this.handle.store.setState(definition.id, (current) => {
141
+ const failures = (current.consecutiveFailures ?? 0) + 1;
142
+ const delay = Math.min(6 * 60 * 60_000, 60_000 * 2 ** (failures - 1));
143
+ return {
144
+ ...current,
145
+ consecutiveFailures: failures,
146
+ backoffUntil: new Date(Date.now() + delay).toISOString(),
147
+ nextCheckAt: new Date(Date.now() + delay).toISOString(),
148
+ };
139
149
  });
140
150
  await this.handle.store.appendLog({ automationId: definition.id, revision: definition.revision, result: 'error', reason: error instanceof Error ? error.message : String(error) });
141
151
  this.handle.onChange?.(definition.id, definition.revision);
@@ -151,7 +161,22 @@ function laterCursor(current, observed) {
151
161
  return order > 0 ? observed : current;
152
162
  }
153
163
  const MIN_RETRY_MS = 60_000;
154
- /** One workspace timer, created only while at least one enabled definition exists. */
164
+ /**
165
+ * The longest the workspace timer sleeps before it looks at the wall clock again. Node timers
166
+ * count on a monotonic clock that stops while the machine is suspended, so one timer armed for
167
+ * the whole distance to a weekly occurrence would wake days late after a laptop slept. A capped
168
+ * wake that is not yet due re-arms without firing; the cap also keeps every delay far below
169
+ * `setTimeout`'s 2^31 ms overflow.
170
+ */
171
+ export const WORKSPACE_TIMER_CAP_MS = 60_000;
172
+ /**
173
+ * One workspace timer, running only while the scheduler is started (automations are opt-in) and at
174
+ * least one project is registered with the coordinator. With nothing enabled it is an idle wake
175
+ * at the cap, even before any project has a definitions file: every wake goes through
176
+ * `reschedule`, whose coordinator refresh re-reads a store another cockpit changed and opens a
177
+ * project whose definitions file appeared, so their edits arm here within one cap. No registered
178
+ * project: no timer.
179
+ */
155
180
  export class WorkspaceAutomationScheduler {
156
181
  options;
157
182
  timer;
@@ -197,24 +222,67 @@ export class WorkspaceAutomationScheduler {
197
222
  const handle = this.options.handle(projectId, store);
198
223
  if (!handle)
199
224
  continue;
200
- for (const definition of store.list().filter((item) => item.enabled)) {
225
+ const enabled = store.list().filter((item) => item.enabled);
226
+ // A poll needs the project's GitHub remote; without one it is never armed, not armed to fail.
227
+ if (handle.github) {
228
+ const scheduler = new ProjectAutomationScheduler(handle);
229
+ for (const definition of enabled.filter(isGithubAutomation)) {
230
+ const key = `${projectId}:${definition.id}`;
231
+ live.add(key);
232
+ const at = Date.parse(store.state(definition.id)?.nextCheckAt ?? new Date().toISOString());
233
+ due.push({ key, at: Math.max(at, this.retryAfter.get(key) ?? 0), retryAfterMs: Math.max(definition.intervalSeconds * 1_000, MIN_RETRY_MS), fire: () => scheduler.check(definition) });
234
+ }
235
+ }
236
+ const runner = new ScheduleRunner({
237
+ projectId,
238
+ store,
239
+ timeZone: handle.timeZone,
240
+ ...(handle.launchSchedule ? { launch: handle.launchSchedule } : {}),
241
+ ...(handle.onChange ? { onChange: handle.onChange } : {}),
242
+ ...(handle.now ? { now: handle.now } : {}),
243
+ ...(handle.reconcileReceipts ? { reconcile: handle.reconcileReceipts } : {}),
244
+ ...(handle.ready ? { ready: handle.ready } : {}),
245
+ });
246
+ for (const definition of enabled.filter(isScheduleAutomation)) {
201
247
  const key = `${projectId}:${definition.id}`;
248
+ let at;
249
+ // A throwing `dueAt` (an unknown zone, an unwritable state file) skips this item rather
250
+ // than stalling the one timer every other automation shares.
251
+ try {
252
+ at = runner.dueAt(definition);
253
+ }
254
+ catch {
255
+ continue;
256
+ }
257
+ if (at === null)
258
+ continue;
202
259
  live.add(key);
203
- const at = Date.parse(store.state(definition.id)?.nextCheckAt ?? new Date().toISOString());
204
- due.push({ key, at: Math.max(at, this.retryAfter.get(key) ?? 0), retryAfterMs: Math.max(definition.intervalSeconds * 1_000, MIN_RETRY_MS), definition, scheduler: new ProjectAutomationScheduler(handle) });
260
+ // A rejected fire (a held lease included) re-arms at the floor; the schedule's own next
261
+ // occurrence is the runner's business, not the timer's.
262
+ due.push({ key, at: Math.max(at, this.retryAfter.get(key) ?? 0), retryAfterMs: MIN_RETRY_MS, fire: () => runner.fire(definition) });
205
263
  }
206
264
  }
207
265
  for (const key of this.retryAfter.keys())
208
266
  if (!live.has(key))
209
267
  this.retryAfter.delete(key);
210
- if (!due.length)
268
+ if (!due.length) {
269
+ if (this.options.coordinator.hasProjects()) {
270
+ this.timer = setTimeout(() => { this.timer = undefined; void this.reschedule(); }, WORKSPACE_TIMER_CAP_MS);
271
+ }
211
272
  return;
273
+ }
212
274
  due.sort((a, b) => a.at - b.at);
213
275
  const next = due[0];
276
+ const clock = () => this.options.now?.() ?? Date.now();
214
277
  this.timer = setTimeout(() => {
215
278
  this.timer = undefined;
216
- void next.scheduler.check(next.definition).then(() => { this.retryAfter.delete(next.key); }, () => { this.retryAfter.set(next.key, (this.options.now?.() ?? Date.now()) + next.retryAfterMs); }).finally(() => this.schedule());
217
- }, Math.max(0, next.at - (this.options.now?.() ?? Date.now())));
279
+ // A capped wake short of the due instant fires nothing: look again from fresh state.
280
+ if (clock() < next.at) {
281
+ void this.reschedule();
282
+ return;
283
+ }
284
+ void next.fire().then(() => { this.retryAfter.delete(next.key); }, () => { this.retryAfter.set(next.key, clock() + next.retryAfterMs); }).finally(() => this.reschedule());
285
+ }, Math.min(WORKSPACE_TIMER_CAP_MS, Math.max(0, next.at - clock())));
218
286
  }
219
287
  }
220
288
  //# sourceMappingURL=scheduler.js.map