@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
@@ -120,14 +120,14 @@ var applicationUpdateInputSchema = z4.record(z4.string(), z4.never());
120
120
  var applicationUpdateResponseSchema = z4.object({ state: applicationUpdateStateSchema });
121
121
 
122
122
  // ../contract/src/health.ts
123
- var runnerSchema = z5.enum(["claude", "codex", "opencode", "pi", "cursor"]);
123
+ var runnerSchema = z5.enum(["claude", "codex", "opencode", "pi", "cursor", "omp"]);
124
124
  var repoInfoSchema = z5.object({
125
125
  root: z5.string(),
126
126
  branch: z5.string(),
127
127
  remote: z5.string().optional()
128
128
  });
129
129
  var backendCheckSchema = z5.object({
130
- name: z5.enum(["claude", "codex", "opencode", "pi", "cursor", "gh", "git"]),
130
+ name: z5.enum(["claude", "codex", "opencode", "pi", "cursor", "omp", "gh", "git"]),
131
131
  available: z5.boolean(),
132
132
  version: z5.string().optional(),
133
133
  hint: z5.string().optional()
@@ -156,6 +156,14 @@ var capabilitiesSchema = z5.object({
156
156
  * REQUIRED for the same reason as `tokenMetrics` below: this server always sends it.
157
157
  */
158
158
  automations: z5.boolean(),
159
+ /**
160
+ * `true` means `CEZ_PREVIEW=1` opted this server into live preview (#781): the `cezar_preview_serve`
161
+ * tool is listed, its route answers, the preview WebSocket upgrades and the cockpit offers the
162
+ * pane. Off — the default — every one of those is absent.
163
+ *
164
+ * REQUIRED for the same reason as `tokenMetrics` below: this server always sends it.
165
+ */
166
+ preview: z5.boolean(),
159
167
  /**
160
168
  * `false` means `CEZ_HIDE_TOKEN_METRICS=1` asks the browser to omit token counts and monetary
161
169
  * cost (#481). The telemetry itself still rides in run/event payloads — this is presentation
@@ -232,7 +240,8 @@ var workspaceConfigResponseSchema = z6.object({
232
240
  codex: z6.string().optional(),
233
241
  opencode: z6.string().optional(),
234
242
  pi: z6.string().optional(),
235
- cursor: z6.string().optional()
243
+ cursor: z6.string().optional(),
244
+ omp: z6.string().optional()
236
245
  }).optional()
237
246
  })
238
247
  });
@@ -253,7 +262,8 @@ var setWorkspaceConfigInputSchema = z6.object({
253
262
  codex: z6.string().trim().min(1).max(200).nullable().optional(),
254
263
  opencode: z6.string().trim().min(1).max(200).nullable().optional(),
255
264
  pi: z6.string().trim().min(1).max(200).nullable().optional(),
256
- cursor: z6.string().trim().min(1).max(200).nullable().optional()
265
+ cursor: z6.string().trim().min(1).max(200).nullable().optional(),
266
+ omp: z6.string().trim().min(1).max(200).nullable().optional()
257
267
  }).optional()
258
268
  }).optional(),
259
269
  resources: z6.object({
@@ -274,7 +284,23 @@ var taskTableUiStateSchema = z6.looseObject({
274
284
  /** Explicit user choices only. Missing ids keep the registry-owned default. */
275
285
  expandedColumns: z6.record(z6.string(), z6.boolean()).optional()
276
286
  });
287
+ var sidebarLimitsSchema = z6.object({
288
+ overall: z6.number().int().positive().nullable().optional(),
289
+ needsYou: z6.number().int().positive().nullable().optional(),
290
+ finished: z6.number().int().positive().nullable().optional(),
291
+ working: z6.number().int().positive().nullable().optional()
292
+ });
293
+ function normalizeSidebarLimits(value) {
294
+ const defaults = { overall: 10, needsYou: null, finished: null, working: null };
295
+ const input = value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
296
+ for (const key of Object.keys(defaults)) {
297
+ const parsed = sidebarLimitsSchema.shape[key].safeParse(input[key]);
298
+ if (parsed.success && parsed.data !== void 0) defaults[key] = parsed.data;
299
+ }
300
+ return defaults;
301
+ }
277
302
  var uiStateSchema = z6.looseObject({
303
+ sidebarLimits: sidebarLimitsSchema.optional(),
278
304
  /** What the last started run used. `null` is a VALUE, not an absence: it records a run that
279
305
  * chose neither a skill nor a workflow (the plain built-in `quick-task`), which the composer
280
306
  * can now express since the source picker grew an empty state. Absent still means "no
@@ -332,7 +358,8 @@ var workspaceUiStateSchema = z6.looseObject({
332
358
  codex: z6.string().optional(),
333
359
  opencode: z6.string().optional(),
334
360
  pi: z6.string().optional(),
335
- cursor: z6.string().optional()
361
+ cursor: z6.string().optional(),
362
+ omp: z6.string().optional()
336
363
  }).optional(),
337
364
  /** Settings → Appearance, GLOBAL since step 3.5: accent + density describe the person at the
338
365
  * keyboard, not a repo. */
@@ -366,7 +393,8 @@ var setWorkspaceUiStateInputSchema = z6.looseObject({
366
393
  codex: z6.string().min(1).max(128).optional(),
367
394
  opencode: z6.string().min(1).max(128).optional(),
368
395
  pi: z6.string().min(1).max(128).optional(),
369
- cursor: z6.string().min(1).max(128).optional()
396
+ cursor: z6.string().min(1).max(128).optional(),
397
+ omp: z6.string().min(1).max(128).optional()
370
398
  }).optional(),
371
399
  importedSkills: z6.array(z6.string().min(1).max(200)).max(WORKSPACE_UI_STATE_MAX_KEYS).optional(),
372
400
  taskTable: taskTableUiStateSchema.extend({
@@ -387,8 +415,18 @@ var runnerModelsSchema = z6.object({
387
415
  codex: z6.string().optional(),
388
416
  opencode: z6.string().optional(),
389
417
  pi: z6.string().optional(),
390
- cursor: z6.string().optional()
391
- });
418
+ cursor: z6.string().optional(),
419
+ omp: z6.string().optional()
420
+ });
421
+ var WORKTREE_SETUP_MAX_COMMANDS = 20;
422
+ var WORKTREE_SETUP_MAX_COMMAND_LENGTH = 4e3;
423
+ var WORKTREE_SETUP_DEFAULT_TIMEOUT_SECONDS = 900;
424
+ var WORKTREE_SETUP_MAX_TIMEOUT_SECONDS = 7200;
425
+ var worktreeSetupConfigSchema = z6.object({
426
+ commands: z6.array(z6.string().trim().min(1).max(WORKTREE_SETUP_MAX_COMMAND_LENGTH)).max(WORKTREE_SETUP_MAX_COMMANDS),
427
+ /** Per command. Absent = `WORKTREE_SETUP_DEFAULT_TIMEOUT_SECONDS`. */
428
+ timeoutSeconds: z6.number().int().min(1).max(WORKTREE_SETUP_MAX_TIMEOUT_SECONDS).optional()
429
+ }).strict();
392
430
  var configResponseSchema = z6.object({
393
431
  baseBranch: z6.string().nullable(),
394
432
  defaultRunner: runnerSchema,
@@ -407,7 +445,12 @@ var configResponseSchema = z6.object({
407
445
  liveTitleUpdates: z6.boolean().nullable(),
408
446
  /** Optional review gate (#489): null = no config key, the `CEZ_REVIEW_GATE` env default (OFF)
409
447
  * decides. */
410
- reviewGate: z6.boolean().nullable()
448
+ reviewGate: z6.boolean().nullable(),
449
+ /** Worktree setup (#917): the commands that prepare a new task or worker worktree, with the
450
+ * timeout filled in. null = no setup, or an invalid value (then `worktreeSetupIssue` says why). */
451
+ worktreeSetup: z6.object({ commands: z6.array(z6.string()), timeoutSeconds: z6.number() }).nullable(),
452
+ /** Why `config.json`'s `worktreeSetup` is invalid; null when it is valid or absent. */
453
+ worktreeSetupIssue: z6.string().nullable()
411
454
  });
412
455
  var setConfigResponseSchema = configResponseSchema;
413
456
  var setConfigInputSchema = z6.object({
@@ -419,7 +462,8 @@ var setConfigInputSchema = z6.object({
419
462
  codex: z6.string().trim().max(200).nullable().optional(),
420
463
  opencode: z6.string().trim().max(200).nullable().optional(),
421
464
  pi: z6.string().trim().max(200).nullable().optional(),
422
- cursor: z6.string().trim().max(200).nullable().optional()
465
+ cursor: z6.string().trim().max(200).nullable().optional(),
466
+ omp: z6.string().trim().max(200).nullable().optional()
423
467
  }).optional(),
424
468
  maxParallel: z6.number().int().min(1).max(16).optional(),
425
469
  /** null or 0 clears the ceiling back to "no limit". */
@@ -429,7 +473,10 @@ var setConfigInputSchema = z6.object({
429
473
  /** null clears the key back to the env-default behavior. */
430
474
  liveTitleUpdates: z6.boolean().nullable().optional(),
431
475
  /** null clears the key back to the env-default behavior (OFF). */
432
- reviewGate: z6.boolean().nullable().optional()
476
+ reviewGate: z6.boolean().nullable().optional(),
477
+ /** Worktree setup (#917). null or an empty command list deletes the key. Refused with 409 by a
478
+ * hosted cockpit: these are commands the host runs. */
479
+ worktreeSetup: worktreeSetupConfigSchema.nullable().optional()
433
480
  });
434
481
  var skillsUpdateStatusSchema = z6.enum([
435
482
  "idle",
@@ -485,7 +532,7 @@ var providerConnectResponseSchema = z6.discriminatedUnion("opened", [
485
532
  z6.object({ opened: z6.literal(true), command: z6.string() }),
486
533
  z6.object({ opened: z6.literal(false), connected: z6.literal(true), command: z6.string() })
487
534
  ]);
488
- var modelDiscoveryRunnerSchema = z6.enum(["claude", "codex", "opencode", "pi", "cursor"]);
535
+ var modelDiscoveryRunnerSchema = z6.enum(["claude", "codex", "opencode", "pi", "cursor", "omp"]);
489
536
  var MODEL_DISCOVERY_RUNNERS = modelDiscoveryRunnerSchema.options;
490
537
  function runnerDiscoversModels(runner) {
491
538
  return MODEL_DISCOVERY_RUNNERS.includes(runner);
@@ -579,12 +626,18 @@ var workerWaitSchema = z8.object({
579
626
  outcomes: z8.array(workerOutcomeSchema).max(32),
580
627
  wakeId: z8.uuid().optional()
581
628
  }).strict();
629
+ var workerDestroyRetrySchema = z8.object({
630
+ attempts: z8.number().int().positive(),
631
+ nextAt: z8.iso.datetime(),
632
+ needsAttention: z8.literal(true).optional()
633
+ }).strict();
582
634
  var workerDestroySchema = z8.object({
583
635
  requestedAt: z8.iso.datetime(),
584
636
  phase: z8.enum(["requested", "terminating", "cleaning", "complete", "incomplete"]),
585
637
  remaining: remainingSchema,
586
638
  error: errorSchema.optional()
587
639
  }).strict();
640
+ var workerDestroyViewSchema = workerDestroySchema.extend({ retry: workerDestroyRetrySchema.optional() }).strict();
588
641
  var workerCreationReceiptSchema = z8.object({
589
642
  requestId: z8.uuid(),
590
643
  workerId: z8.uuid(),
@@ -592,7 +645,7 @@ var workerCreationReceiptSchema = z8.object({
592
645
  requestHash: requestHashSchema,
593
646
  deletion: z8.object({ phase: z8.enum(["pending", "complete"]), revision: z8.number().int().nonnegative(), resourceId: z8.uuid(), generation: z8.uuid() }).strict().optional()
594
647
  }).strict();
595
- var workerBackendSchema = z8.enum(["claude", "codex", "opencode", "pi", "cursor"]);
648
+ var workerBackendSchema = z8.enum(["claude", "codex", "opencode", "pi", "cursor", "omp"]);
596
649
  var relativeInputPath = z8.string().min(1).max(4096).refine((path) => !/[\\\u0000-\u001f\u007f:]/.test(path) && !path.startsWith("/") && path.split("/").every((part) => part !== "" && part !== "." && part !== ".."));
597
650
  var workerContextReferenceSchema = z8.discriminatedUnion("kind", [
598
651
  z8.object({ kind: z8.literal("baseline-file"), path: relativeInputPath }).strict(),
@@ -674,10 +727,11 @@ var delegationStateSchema = z8.discriminatedUnion("role", [
674
727
  role: z8.literal("root"),
675
728
  conversation: conversationStateSchema.optional(),
676
729
  permissions: permissionsSchema,
677
- receipts: z8.array(workerCreationReceiptSchema).max(32).refine((receipts) => new Set(receipts.map((receipt) => receipt.requestId)).size === receipts.length && new Set(receipts.map((receipt) => receipt.workerId)).size === receipts.length),
730
+ // #816: bounded by the creation ceiling (WORKER_CREATION_LIMIT), not by capacity.
731
+ receipts: z8.array(workerCreationReceiptSchema).max(1024).refine((receipts) => new Set(receipts.map((receipt) => receipt.requestId)).size === receipts.length && new Set(receipts.map((receipt) => receipt.workerId)).size === receipts.length),
678
732
  wait: workerWaitSchema.optional(),
679
733
  lastWait: workerWaitSchema.optional(),
680
- results: z8.array(workerResultReferenceSchema).max(32).refine((results) => new Set(results.map((result) => result.workerId)).size === results.length).optional(),
734
+ results: z8.array(workerResultReferenceSchema).max(1024).refine((results) => new Set(results.map((result) => result.workerId)).size === results.length).optional(),
681
735
  finishRequestedAt: z8.iso.datetime().optional(),
682
736
  historyDeletion: z8.literal("pending").optional(),
683
737
  completion: z8.object({ phase: z8.enum(["waiting", "attention"]), waitId: z8.uuid().optional() }).strict().optional()
@@ -699,9 +753,15 @@ var delegationStateSchema = z8.discriminatedUnion("role", [
699
753
  ]);
700
754
  var runDelegationSummarySchema = z8.discriminatedUnion("role", [
701
755
  delegationStateSchema.options[0].pick({ role: true }).strip().extend({
702
- wait: workerWaitSchema.pick({ phase: true, requestIds: true }).strip().optional()
756
+ // The awaited worker ids and which of them reported (ids only) keep a list's counted label,
757
+ // "waiting on 2 workers" (#617), now that lists read summaries instead of records (#817).
758
+ wait: workerWaitSchema.pick({ phase: true, requestIds: true, workerIds: true }).partial({ workerIds: true }).strip().extend({
759
+ outcomes: z8.array(workerOutcomeSchema.pick({ workerId: true }).strip()).max(32).optional()
760
+ }).optional()
703
761
  }),
704
- delegationStateSchema.options[1].pick({ role: true }).strip().extend({
762
+ // `parentRunId` is the one worker field a list needs: the sidebar lights the parent's row for
763
+ // a worker URL, and `cez task list` hides workers by it (#817). Never paths or permissions.
764
+ delegationStateSchema.options[1].pick({ role: true, parentRunId: true }).strip().extend({
705
765
  wait: workerWaitSchema.pick({ phase: true, requestIds: true }).strip().optional()
706
766
  }),
707
767
  delegationStateSchema.options[2].strip()
@@ -714,9 +774,11 @@ var workerSpawnRequestSchema = z8.object({
714
774
  backend: workerBackendSchema.optional(),
715
775
  model: z8.string().trim().min(1).max(512).optional(),
716
776
  effort: effortFieldSchema,
717
- /** Catalog workflow name (built-in quick-task or `.ai/cezar/workflows/*.yaml`, #451). Absent means quick-task. */
718
- workflow: z8.string().trim().min(1).max(200).optional()
719
- }).strict().refine((request) => request.task.length + (request.context?.text?.length ?? 0) <= 1e5, { message: "Combined task and context exceed 100000 characters" });
777
+ /** Catalog workflow name (built-in quick-task or `.ai/cezar/workflows/*.yaml`, #451). Absent with no skill means quick-task. */
778
+ workflow: z8.string().trim().min(1).max(200).optional(),
779
+ /** Discovered skill to run as a one-step task, mutually exclusive with workflow (#778). */
780
+ skill: z8.string().trim().min(1).max(200).optional()
781
+ }).strict().refine((request) => request.skill === void 0 || request.workflow === void 0, { message: "--skill and --workflow cannot be used together" }).refine((request) => request.task.length + (request.context?.text?.length ?? 0) <= 1e5, { message: "Combined task and context exceed 100000 characters" });
720
782
  var workerSteerRequestSchema = z8.object({
721
783
  text: z8.string().max(1e5).refine((text) => text.trim().length > 0)
722
784
  }).strict();
@@ -760,7 +822,7 @@ var workerInspectionSchema = z8.object({
760
822
  model: z8.string().max(512).optional(),
761
823
  inputs: z8.array(workerInputSchema).max(32).optional(),
762
824
  wait: workerWaitSchema.optional(),
763
- destroy: workerDestroySchema.optional(),
825
+ destroy: workerDestroyViewSchema.optional(),
764
826
  outcome: workerOutcomeSchema.optional()
765
827
  });
766
828
  var workerDiffSchema = z8.object({
@@ -783,9 +845,25 @@ var workerDestroyResultSchema = z8.object({
783
845
  remaining: remainingSchema,
784
846
  error: errorSchema.optional()
785
847
  });
848
+ var workerCapacitySchema = z8.object({
849
+ outstanding: z8.number().int().nonnegative(),
850
+ limit: z8.number().int().nonnegative(),
851
+ created: z8.number().int().nonnegative(),
852
+ creationLimit: z8.number().int().nonnegative()
853
+ }).strict();
854
+ var relatedRunTitleSchema = z8.object({
855
+ id: z8.string(),
856
+ title: z8.string(),
857
+ titleSummary: z8.string().optional(),
858
+ titleOrigin: z8.enum(["user", "auto", "marker"]).optional()
859
+ });
786
860
  var runRelationshipsSchema = z8.object({
787
861
  parentRunId: z8.uuid().optional(),
788
- workers: z8.array(workerInspectionSchema).max(32)
862
+ workers: z8.array(workerInspectionSchema).max(1024),
863
+ /** The parent's title for a worker, each worker's for a parent; absent when there is none. */
864
+ titles: z8.array(relatedRunTitleSchema).max(1025).optional(),
865
+ /** Present for a delegation root only. */
866
+ capacity: workerCapacitySchema.optional()
789
867
  });
790
868
  var delegationErrorResponseSchema = z8.object({
791
869
  code: z8.enum([
@@ -992,7 +1070,7 @@ var ciWaitReceiptSchema = ciPrIdentitySchema.extend({
992
1070
  }).strict();
993
1071
 
994
1072
  // ../contract/src/runs.ts
995
- import { z as z13 } from "zod";
1073
+ import { z as z14 } from "zod";
996
1074
 
997
1075
  // ../contract/src/github.ts
998
1076
  import { z as z11 } from "zod";
@@ -1017,7 +1095,12 @@ var githubItemSchema = z11.object({
1017
1095
  checks: checksGlyphSchema.optional()
1018
1096
  });
1019
1097
  var githubItemResponseSchema = z11.discriminatedUnion("available", [
1020
- z11.object({ available: z11.literal(true), item: githubItemSchema.nullable() }),
1098
+ z11.object({
1099
+ available: z11.literal(true),
1100
+ item: githubItemSchema.nullable(),
1101
+ /** Label name → GitHub hex colour (without #), as in the list and search responses. */
1102
+ labelColors: z11.record(z11.string(), z11.string()).optional()
1103
+ }),
1021
1104
  z11.object({ available: z11.literal(false), reason: z11.string() })
1022
1105
  ]);
1023
1106
  var githubItemParamsSchema = z11.object({
@@ -1261,30 +1344,201 @@ var githubProjectsDataSchema = z11.discriminatedUnion("state", [
1261
1344
  })
1262
1345
  ]);
1263
1346
 
1264
- // ../contract/src/workflows.ts
1347
+ // ../contract/src/preview.ts
1265
1348
  import { z as z12 } from "zod";
1266
- var workflowStepDefSchema = z12.object({
1267
- id: z12.string().min(1),
1268
- name: z12.string().optional(),
1349
+ var previewServeRequestSchema = z12.object({
1350
+ command: z12.string().min(1).max(1024),
1351
+ port: z12.number().int().min(1).max(65535),
1352
+ cwd: z12.string().optional(),
1353
+ label: z12.string().min(1).max(48).optional(),
1354
+ path: z12.string().startsWith("/").optional()
1355
+ });
1356
+ var previewResultCodeSchema = z12.enum([
1357
+ "registered",
1358
+ "replaced",
1359
+ "invalid_input",
1360
+ "cwd_outside_worktree",
1361
+ "cezar_port",
1362
+ "port_held",
1363
+ "too_many",
1364
+ "preview_disabled",
1365
+ "headless",
1366
+ "worktree_missing",
1367
+ "unavailable"
1368
+ ]);
1369
+ var previewServeResultSchema = z12.object({
1370
+ ok: z12.boolean(),
1371
+ code: previewResultCodeSchema,
1372
+ message: z12.string(),
1373
+ hint: z12.string()
1374
+ });
1375
+ var previewStopRequestSchema = z12.object({
1376
+ port: z12.number().int().min(1).max(65535),
1377
+ restart: z12.boolean().optional()
1378
+ }).strict();
1379
+ var previewStopResultSchema = z12.object({
1380
+ ok: z12.boolean(),
1381
+ code: z12.enum(["stopped", "restarted", "approval_required", "adopted", "not_registered", "port_held", "port_in_use", "invalid_input", "preview_disabled", "headless", "worktree_missing", "unavailable"]),
1382
+ message: z12.string(),
1383
+ hint: z12.string()
1384
+ });
1385
+ var previewServerSchema = z12.object({
1386
+ port: z12.number().int().min(1).max(65535),
1387
+ command: z12.string(),
1388
+ cwd: z12.string().optional(),
1389
+ label: z12.string(),
1390
+ path: z12.string().optional(),
1391
+ registeredAt: z12.iso.datetime(),
1392
+ answeredAtRegistration: z12.boolean()
1393
+ });
1394
+ var previewServerStateSchema = z12.enum([
1395
+ "registered",
1396
+ "starting",
1397
+ "up",
1398
+ "stalled",
1399
+ "exited",
1400
+ "stopped",
1401
+ "adopted",
1402
+ "unavailable"
1403
+ ]);
1404
+ var port = z12.number().int().min(1).max(65535);
1405
+ var clampViewport = (value) => Math.min(4e3, Math.max(100, Math.round(value)));
1406
+ var previewMouseTypeSchema = z12.enum(["mousePressed", "mouseReleased", "mouseMoved", "mouseWheel"]);
1407
+ var previewMouseButtonSchema = z12.enum(["left", "middle", "right", "none"]);
1408
+ var previewKeyTypeSchema = z12.enum(["keyDown", "rawKeyDown", "keyUp"]);
1409
+ var previewClientMessageSchema = z12.discriminatedUnion("t", [
1410
+ /** Never spawns anything: a silent port answers with `needs-approval`. */
1411
+ z12.object({
1412
+ t: z12.literal("open"),
1413
+ target: z12.union([z12.object({ port }), z12.object({ url: z12.string().min(1).max(2048) })])
1414
+ }),
1415
+ /** The owner's explicit approval; the only message that runs a registered command. */
1416
+ z12.object({ t: z12.literal("run"), port }),
1417
+ z12.object({ t: z12.literal("stop"), port }),
1418
+ z12.object({ t: z12.literal("keepWaiting"), port }),
1419
+ z12.object({
1420
+ t: z12.literal("resize"),
1421
+ w: z12.number().finite().transform(clampViewport),
1422
+ h: z12.number().finite().transform(clampViewport)
1423
+ }),
1424
+ z12.object({
1425
+ t: z12.literal("mouse"),
1426
+ type: previewMouseTypeSchema,
1427
+ x: z12.number().finite(),
1428
+ y: z12.number().finite(),
1429
+ button: previewMouseButtonSchema.optional(),
1430
+ buttons: z12.number().optional(),
1431
+ clickCount: z12.number().optional(),
1432
+ deltaX: z12.number().optional(),
1433
+ deltaY: z12.number().optional(),
1434
+ modifiers: z12.number().optional()
1435
+ }),
1436
+ z12.object({
1437
+ t: z12.literal("key"),
1438
+ type: previewKeyTypeSchema,
1439
+ key: z12.string().optional(),
1440
+ code: z12.string().optional(),
1441
+ text: z12.string().optional(),
1442
+ modifiers: z12.number().optional(),
1443
+ vk: z12.number().optional(),
1444
+ commands: z12.array(z12.string()).optional()
1445
+ }),
1446
+ z12.object({ t: z12.literal("insertText"), text: z12.string() }),
1447
+ z12.object({ t: z12.literal("nav"), url: z12.string().min(1).max(2048) }),
1448
+ z12.object({ t: z12.literal("back") }),
1449
+ z12.object({ t: z12.literal("forward") }),
1450
+ z12.object({ t: z12.literal("reload"), ignoreCache: z12.boolean().optional() }),
1451
+ z12.object({ t: z12.literal("dialogResult"), accept: z12.boolean(), text: z12.string().optional() }),
1452
+ z12.object({ t: z12.literal("ack") }),
1453
+ z12.object({ t: z12.literal("ping"), ts: z12.number() }),
1454
+ z12.object({ t: z12.literal("download") }),
1455
+ z12.object({ t: z12.literal("cancelDownload") }),
1456
+ z12.object({ t: z12.literal("retryBrowser") })
1457
+ ]);
1458
+ var previewStateMessageSchema = z12.discriminatedUnion("stage", [
1459
+ z12.object({ t: z12.literal("state"), stage: z12.literal("chromium-missing"), installCommand: z12.string(), canDownload: z12.boolean() }),
1460
+ z12.object({ t: z12.literal("state"), stage: z12.literal("downloading"), received: z12.number(), total: z12.number() }),
1461
+ z12.object({ t: z12.literal("state"), stage: z12.literal("download-failed"), error: z12.string(), installCommand: z12.string() }),
1462
+ z12.object({ t: z12.literal("state"), stage: z12.literal("sandbox-failed"), stderrTail: z12.string() }),
1463
+ z12.object({
1464
+ t: z12.literal("state"),
1465
+ stage: z12.literal("browser-exited"),
1466
+ signal: z12.string().optional(),
1467
+ stderrTail: z12.string(),
1468
+ serverUp: z12.boolean()
1469
+ }),
1470
+ z12.object({ t: z12.literal("state"), stage: z12.literal("needs-approval"), server: previewServerSchema, wasRunning: z12.boolean() }),
1471
+ /** Another task's cezar-owned server holds the port: never adopted, never spawned onto. Its title only, never its path. */
1472
+ z12.object({ t: z12.literal("state"), stage: z12.literal("port-held"), server: previewServerSchema, ownerTitle: z12.string() }),
1473
+ z12.object({
1474
+ t: z12.literal("state"),
1475
+ stage: z12.literal("server-starting"),
1476
+ server: previewServerSchema,
1477
+ attempt: z12.number().int(),
1478
+ startedAt: z12.iso.datetime(),
1479
+ /** The newest lines the command printed, oldest first; empty before it prints anything. */
1480
+ logTail: z12.array(z12.string())
1481
+ }),
1482
+ z12.object({ t: z12.literal("state"), stage: z12.literal("server-stalled"), server: previewServerSchema, logTail: z12.string() }),
1483
+ z12.object({
1484
+ t: z12.literal("state"),
1485
+ stage: z12.literal("server-exited"),
1486
+ server: previewServerSchema,
1487
+ /** `null` when a signal ended the process. */
1488
+ exitCode: z12.number().int().nullable(),
1489
+ logTail: z12.string()
1490
+ }),
1491
+ z12.object({
1492
+ t: z12.literal("state"),
1493
+ stage: z12.literal("server-stopped"),
1494
+ server: previewServerSchema,
1495
+ reason: z12.enum(["user", "idle"]),
1496
+ lastUrl: z12.string()
1497
+ }),
1498
+ z12.object({ t: z12.literal("state"), stage: z12.literal("worktree-removed"), server: previewServerSchema.optional() }),
1499
+ z12.object({ t: z12.literal("state"), stage: z12.literal("loading"), step: z12.enum(["browser", "page", "frame"]) }),
1500
+ z12.object({ t: z12.literal("state"), stage: z12.literal("streaming"), adopted: z12.boolean() })
1501
+ ]);
1502
+ var previewServerMessageSchema = z12.discriminatedUnion("t", [
1503
+ previewStateMessageSchema,
1504
+ z12.object({ t: z12.literal("url"), url: z12.string() }),
1505
+ z12.object({ t: z12.literal("cursor"), cursor: z12.string() }),
1506
+ z12.object({
1507
+ t: z12.literal("dialog"),
1508
+ type: z12.enum(["alert", "confirm", "prompt", "beforeunload"]),
1509
+ message: z12.string(),
1510
+ defaultPrompt: z12.string().optional(),
1511
+ origin: z12.string()
1512
+ }),
1513
+ z12.object({ t: z12.literal("replaced"), by: z12.string() }),
1514
+ z12.object({ t: z12.literal("pong"), ts: z12.number() }),
1515
+ z12.object({ t: z12.literal("downloadProgress"), received: z12.number(), total: z12.number() })
1516
+ ]);
1517
+
1518
+ // ../contract/src/workflows.ts
1519
+ import { z as z13 } from "zod";
1520
+ var workflowStepDefSchema = z13.object({
1521
+ id: z13.string().min(1),
1522
+ name: z13.string().optional(),
1269
1523
  // agent step
1270
- prompt: z12.string().optional(),
1271
- skill: z12.string().optional(),
1272
- model: z12.string().optional(),
1273
- effort: z12.string().max(32).optional(),
1524
+ prompt: z13.string().optional(),
1525
+ skill: z13.string().optional(),
1526
+ model: z13.string().optional(),
1527
+ effort: z13.string().max(32).optional(),
1274
1528
  /** Authored agent-step wall-clock limit in ms. Omitted or 0 means no limit.
1275
1529
  * Bound to Node's timer range so a larger value cannot become a 1ms kill. */
1276
- timeoutMs: z12.number().int().min(0).max(2147483647).optional(),
1530
+ timeoutMs: z13.number().int().min(0).max(2147483647).optional(),
1277
1531
  /** Per-step agent backend override (falls back to the task / config default). */
1278
1532
  runner: runnerSchema.optional(),
1279
1533
  /** Agent account id for this step (spec 2026-07-29-agent-profiles); resolved per step for owned workers (#452). */
1280
- agentProfile: z12.string().min(1).max(64).optional(),
1281
- allowedTools: z12.array(z12.string()).optional(),
1282
- bashAllowlist: z12.array(z12.string()).optional(),
1534
+ agentProfile: z13.string().min(1).max(64).optional(),
1535
+ allowedTools: z13.array(z13.string()).optional(),
1536
+ bashAllowlist: z13.array(z13.string()).optional(),
1283
1537
  // check step
1284
- command: z12.string().optional(),
1285
- onFail: z12.object({
1286
- retry: z12.string().min(1),
1287
- max: z12.number().int().positive().default(2)
1538
+ command: z13.string().optional(),
1539
+ onFail: z13.object({
1540
+ retry: z13.string().min(1),
1541
+ max: z13.number().int().positive().default(2)
1288
1542
  }).optional()
1289
1543
  }).refine((s) => Boolean(s.command) !== Boolean(s.prompt ?? s.skill), {
1290
1544
  message: "a step is either an agent step (prompt/skill) or a check step (command), not both"
@@ -1292,13 +1546,13 @@ var workflowStepDefSchema = z12.object({
1292
1546
  message: "timeoutMs applies only to agent steps",
1293
1547
  path: ["timeoutMs"]
1294
1548
  });
1295
- var workflowDefSchema = z12.object({
1296
- name: z12.string(),
1297
- description: z12.string().optional(),
1298
- steps: z12.array(workflowStepDefSchema),
1299
- source: z12.enum(["built-in", "file"]),
1549
+ var workflowDefSchema = z13.object({
1550
+ name: z13.string(),
1551
+ description: z13.string().optional(),
1552
+ steps: z13.array(workflowStepDefSchema),
1553
+ source: z13.enum(["built-in", "file"]),
1300
1554
  /** Absent on built-ins — which is exactly what makes them undeletable. */
1301
- path: z12.string().optional()
1555
+ path: z13.string().optional()
1302
1556
  });
1303
1557
  function providersRequiredByWorkflow(workflow, fallback) {
1304
1558
  const required = /* @__PURE__ */ new Set();
@@ -1307,46 +1561,46 @@ function providersRequiredByWorkflow(workflow, fallback) {
1307
1561
  }
1308
1562
  return runnerSchema.options.filter((provider) => required.has(provider));
1309
1563
  }
1310
- var workflowLoadIssueSchema = z12.object({
1311
- path: z12.string(),
1312
- message: z12.string()
1313
- });
1314
- var workflowsResponseSchema = z12.object({
1315
- workflows: z12.array(workflowDefSchema),
1316
- issues: z12.array(workflowLoadIssueSchema)
1317
- });
1318
- var saveWorkflowInputSchema = z12.object({
1319
- name: z12.string().trim().min(1).max(80),
1320
- description: z12.string().max(2e3, "must be at most 2000 characters").optional(),
1321
- steps: z12.array(workflowStepDefSchema).min(1).max(8).optional(),
1322
- skills: z12.array(z12.string().trim().min(1)).min(1).max(8).optional(),
1323
- overwrite: z12.boolean().optional()
1564
+ var workflowLoadIssueSchema = z13.object({
1565
+ path: z13.string(),
1566
+ message: z13.string()
1567
+ });
1568
+ var workflowsResponseSchema = z13.object({
1569
+ workflows: z13.array(workflowDefSchema),
1570
+ issues: z13.array(workflowLoadIssueSchema)
1571
+ });
1572
+ var saveWorkflowInputSchema = z13.object({
1573
+ name: z13.string().trim().min(1).max(80),
1574
+ description: z13.string().max(2e3, "must be at most 2000 characters").optional(),
1575
+ steps: z13.array(workflowStepDefSchema).min(1).max(8).optional(),
1576
+ skills: z13.array(z13.string().trim().min(1)).min(1).max(8).optional(),
1577
+ overwrite: z13.boolean().optional()
1324
1578
  }).refine((b) => Boolean(b.steps) !== Boolean(b.skills), {
1325
1579
  message: 'provide either "steps" or "skills", not both'
1326
1580
  });
1327
- var saveWorkflowResponseSchema = z12.object({
1328
- path: z12.string(),
1329
- name: z12.string()
1581
+ var saveWorkflowResponseSchema = z13.object({
1582
+ path: z13.string(),
1583
+ name: z13.string()
1330
1584
  });
1331
- var parsedWorkflowSchema = z12.object({
1332
- name: z12.string(),
1333
- description: z12.string().optional(),
1334
- steps: z12.array(workflowStepDefSchema)
1585
+ var parsedWorkflowSchema = z13.object({
1586
+ name: z13.string(),
1587
+ description: z13.string().optional(),
1588
+ steps: z13.array(workflowStepDefSchema)
1335
1589
  });
1336
- var deleteWorkflowResponseSchema = z12.object({
1337
- ok: z12.literal(true),
1338
- path: z12.string()
1590
+ var deleteWorkflowResponseSchema = z13.object({
1591
+ ok: z13.literal(true),
1592
+ path: z13.string()
1339
1593
  });
1340
- var planResponseSchema = z12.object({
1594
+ var planResponseSchema = z13.object({
1341
1595
  /** The kebab-case workflow title the planner proposed. Absent on the degraded fallback. */
1342
- name: z12.string().optional(),
1343
- steps: z12.array(workflowStepDefSchema),
1344
- rationale: z12.string(),
1345
- fallback: z12.boolean()
1596
+ name: z13.string().optional(),
1597
+ steps: z13.array(workflowStepDefSchema),
1598
+ rationale: z13.string(),
1599
+ fallback: z13.boolean()
1346
1600
  });
1347
1601
 
1348
1602
  // ../contract/src/runs.ts
1349
- var runStatusSchema = z13.enum([
1603
+ var runStatusSchema = z14.enum([
1350
1604
  "queued",
1351
1605
  "running",
1352
1606
  "waiting",
@@ -1355,8 +1609,8 @@ var runStatusSchema = z13.enum([
1355
1609
  "failed",
1356
1610
  "cancelled"
1357
1611
  ]);
1358
- var runActivitySchema = z13.enum(["monitoring"]);
1359
- var stepStatusSchema = z13.enum([
1612
+ var runActivitySchema = z14.enum(["monitoring"]);
1613
+ var stepStatusSchema = z14.enum([
1360
1614
  "pending",
1361
1615
  "running",
1362
1616
  "waiting",
@@ -1366,16 +1620,16 @@ var stepStatusSchema = z13.enum([
1366
1620
  "cancelled",
1367
1621
  "skipped"
1368
1622
  ]);
1369
- var usageCounterSchema = z13.number().finite().nonnegative();
1370
- var stepStateSchema = z13.object({
1371
- id: z13.string(),
1372
- name: z13.string(),
1373
- kind: z13.enum(["agent", "check"]),
1623
+ var usageCounterSchema = z14.number().finite().nonnegative();
1624
+ var stepStateSchema = z14.object({
1625
+ id: z14.string(),
1626
+ name: z14.string(),
1627
+ kind: z14.enum(["agent", "check"]),
1374
1628
  status: stepStatusSchema,
1375
- iterations: z13.number(),
1629
+ iterations: z14.number(),
1376
1630
  /** Durable count of onFail retry loops consumed by this check. */
1377
- retriesUsed: z13.number().int().nonnegative().optional(),
1378
- tokensUsed: z13.number(),
1631
+ retriesUsed: z14.number().int().nonnegative().optional(),
1632
+ tokensUsed: z14.number(),
1379
1633
  inputTokens: usageCounterSchema.optional(),
1380
1634
  outputTokens: usageCounterSchema.optional(),
1381
1635
  usageInvocationsStarted: usageCounterSchema.optional(),
@@ -1383,103 +1637,113 @@ var stepStateSchema = z13.object({
1383
1637
  usageTurnsStarted: usageCounterSchema.optional(),
1384
1638
  usageTurnsRecorded: usageCounterSchema.optional(),
1385
1639
  usageInvocationEpoch: usageCounterSchema.optional(),
1386
- startedAt: z13.string().optional(),
1387
- finishedAt: z13.string().optional(),
1388
- error: z13.string().optional(),
1640
+ startedAt: z14.string().optional(),
1641
+ finishedAt: z14.string().optional(),
1642
+ error: z14.string().optional(),
1389
1643
  /** Latest agent session id — `claude --resume <id>` and friends. */
1390
- sessionId: z13.string().optional(),
1644
+ sessionId: z14.string().optional(),
1391
1645
  /** Backend that owns `sessionId`; absent on records written before backend affinity. */
1392
1646
  backend: runnerSchema.optional(),
1393
1647
  /** Agent account (spec 2026-07-29-agent-profiles) that owns `sessionId` — `default`, or a
1394
1648
  * stored profile id. The two are a PAIR: a session id only resolves inside the config dir
1395
1649
  * that created it, so resume and Continue read this rather than the project's current
1396
1650
  * selection. Absent on records written before accounts existed. */
1397
- profileId: z13.string().optional(),
1398
- costUsd: z13.number().optional(),
1651
+ profileId: z14.string().optional(),
1652
+ costUsd: z14.number().optional(),
1399
1653
  /** Explicit provenance for engine-generated continuation steps. */
1400
- synthetic: z13.literal("continuation").optional()
1654
+ synthetic: z14.literal("continuation").optional()
1401
1655
  });
1402
- var diffStatSchema = z13.object({
1403
- adds: z13.number(),
1404
- dels: z13.number(),
1405
- files: z13.number(),
1656
+ var diffStatSchema = z14.object({
1657
+ adds: z14.number(),
1658
+ dels: z14.number(),
1659
+ files: z14.number(),
1406
1660
  /** Additive since #751, and present ONLY when true: the numbers were measured against a
1407
1661
  * branch the agent checked out into the task's worktree, as the run found it, because the
1408
1662
  * worktree's HEAD had been repointed off the task's own branch (every review/QA run does
1409
1663
  * this) and the merge-base anchor would otherwise have reported that branch's entire diff
1410
1664
  * as this task's. Absent on every normal run and on every record written before #751 — a
1411
1665
  * consumer that ignores it sees exactly the old shape. */
1412
- repointed: z13.boolean().optional()
1666
+ repointed: z14.boolean().optional()
1413
1667
  });
1414
- var queuedMessageSchema = z13.object({
1415
- id: z13.string(),
1416
- text: z13.string(),
1668
+ var queuedMessageSchema = z14.object({
1669
+ id: z14.string(),
1670
+ text: z14.string(),
1417
1671
  /** `/api/v1/runs/:id/images/…` URLs — attachments are persisted, never inlined. Images and
1418
1672
  * files share this one list; read `isImageAttachmentName` on the file name to tell them apart. */
1419
- images: z13.array(z13.string()).optional(),
1420
- createdAt: z13.string()
1673
+ images: z14.array(z14.string()).optional(),
1674
+ createdAt: z14.string()
1421
1675
  });
1422
1676
  var continuationMessageSchema = queuedMessageSchema.extend({
1423
- origin: z13.enum(["human", "lifecycle"]).optional(),
1677
+ origin: z14.enum(["human", "lifecycle"]).optional(),
1424
1678
  /** An attributed parent message used as the opening prompt, never a human answer. */
1425
- agentInputId: z13.uuid().optional()
1679
+ agentInputId: z14.uuid().optional()
1426
1680
  });
1427
- var processUsageSchema = z13.object({
1681
+ var processUsageSchema = z14.object({
1428
1682
  /** Sum of `%cpu` across the tree — can exceed 100 on multi-core work. */
1429
- cpuPct: z13.number(),
1430
- rssBytes: z13.number(),
1431
- procCount: z13.number()
1432
- });
1433
- var runWebhookOutcomeSchema = z13.object({
1434
- lastDeliveredAt: z13.string().optional(),
1435
- lastError: z13.string().max(512).optional()
1436
- });
1437
- var runRecordSchema = z13.object({
1438
- id: z13.string(),
1439
- title: z13.string(),
1683
+ cpuPct: z14.number(),
1684
+ rssBytes: z14.number(),
1685
+ procCount: z14.number()
1686
+ });
1687
+ var runWebhookOutcomeSchema = z14.object({
1688
+ lastDeliveredAt: z14.string().optional(),
1689
+ lastError: z14.string().max(512).optional()
1690
+ });
1691
+ var runWorktreeSetupSchema = z14.object({
1692
+ status: z14.enum(["running", "done", "failed"]),
1693
+ startedAt: z14.string(),
1694
+ finishedAt: z14.string().optional(),
1695
+ durationMs: z14.number().optional(),
1696
+ /** One line: "`npm ci` exited 1", "`npm ci` timed out after 900s", "invalid config: …". */
1697
+ error: z14.string().optional()
1698
+ });
1699
+ var runRecordSchema = z14.object({
1700
+ id: z14.string(),
1701
+ title: z14.string(),
1440
1702
  /** Display title (#389): auto-derived from the first agent turn, or the user's inline edit
1441
1703
  * (`PATCH /runs/:id` sets it together with `title`). Show `titleSummary ?? title`. */
1442
- titleSummary: z13.string().optional(),
1704
+ titleSummary: z14.string().optional(),
1443
1705
  /** Refreshed on every turn-end; absent until the first turn ends (and on worktree-less runs). */
1444
1706
  diffStat: diffStatSchema.optional(),
1445
- workflow: z13.string(),
1446
- task: z13.string(),
1707
+ workflow: z14.string(),
1708
+ task: z14.string(),
1447
1709
  /** Prompt messages stacked onto the run while it waited for a free agent slot (#472). Folded
1448
1710
  * into the prompt at dequeue — never delivered as their own turns. Absent on pre-#472 runs. */
1449
- queuedMessages: z13.array(queuedMessageSchema).optional(),
1711
+ queuedMessages: z14.array(queuedMessageSchema).optional(),
1450
1712
  /** Stop was accepted; execution termination is still pending. */
1451
- stopping: z13.boolean().optional(),
1713
+ stopping: z14.boolean().optional(),
1452
1714
  /** Opening Continue message, retained until its first completed turn for crash recovery. */
1453
1715
  continuationMessage: continuationMessageSchema.optional(),
1454
1716
  /** The last turn carried a malformed explicit structured question. */
1455
- invalidAsk: z13.boolean().optional(),
1717
+ invalidAsk: z14.boolean().optional(),
1456
1718
  /** Owned-run authority; absence is legacy, invalid is explicitly quarantined. */
1457
1719
  delegation: delegationStateSchema.optional(),
1458
1720
  /** Durable non-human input, kept separate from human prompt/answer queues. */
1459
- agentInputs: z13.array(agentInputSchema).optional(),
1721
+ agentInputs: z14.array(agentInputSchema).optional(),
1460
1722
  ciWait: ciWaitSchema.optional(),
1461
1723
  lastCiWait: ciWaitSchema.optional(),
1462
1724
  /** Retained recovery observation when previous CI metadata cannot be trusted. */
1463
- lastCiWaitError: z13.string().max(256).optional(),
1725
+ lastCiWaitError: z14.string().max(256).optional(),
1726
+ /** Dev servers the agent registered with `cezar_preview_serve` (#781). Salvaged per entry on load. */
1727
+ previewServers: z14.array(previewServerSchema).optional(),
1464
1728
  /** URLs of images and document attachments on the initial task prompt; branch on isImageAttachmentName. */
1465
- taskImages: z13.array(z13.string()).optional(),
1466
- model: z13.string().optional(),
1729
+ taskImages: z14.array(z14.string()).optional(),
1730
+ model: z14.string().optional(),
1467
1731
  /** Reasoning-effort pin (#45). Canonical `low`/`medium`/`high`/`xhigh`/`max`.
1468
1732
  * Absent = harness default. Additive: pre-#45 records omit it and still parse. */
1469
- effort: z13.string().max(32).optional(),
1733
+ effort: z14.string().max(32).optional(),
1470
1734
  /** Normalized provider/model identity used for attribution and reproducible replay. */
1471
- modelIdentity: z13.string().optional(),
1735
+ modelIdentity: z14.string().optional(),
1472
1736
  runner: runnerSchema.optional(),
1473
1737
  /** The composer's per-task agent account (spec 2026-07-29-agent-profiles), applying to steps
1474
1738
  * on `runner`. Absent = the run follows the project's own selection. */
1475
- agentProfile: z13.string().optional(),
1739
+ agentProfile: z14.string().optional(),
1476
1740
  /** Echo of the extra system prompt the run used (POST override or config default). */
1477
- systemPrompt: z13.string().optional(),
1741
+ systemPrompt: z14.string().optional(),
1478
1742
  /** false when the run deliberately disabled follow-up todo generation. Absent means enabled. */
1479
- generateFollowups: z13.boolean().optional(),
1743
+ generateFollowups: z14.boolean().optional(),
1480
1744
  /** Autonomous mode (#autonomous): the run never parks at `waiting` or the terminal `review`
1481
1745
  * gate. Absent = falsy = not autonomous. */
1482
- autonomous: z13.boolean().optional(),
1746
+ autonomous: z14.boolean().optional(),
1483
1747
  /**
1484
1748
  * Provenance for a task a project GitHub automation launched (#694). Absent on every ordinary
1485
1749
  * run, which is what makes it additive — the cockpit shows the "from automation" link only when
@@ -1489,17 +1753,34 @@ var runRecordSchema = z13.object({
1489
1753
  * launching definition matched, recorded on the run for the audit trail, and `src/runs/store.ts`
1490
1754
  * persists it as free text so an older cezar can still read a record written by a newer one.
1491
1755
  */
1492
- automation: z13.object({
1493
- automationId: z13.string(),
1494
- automationRevision: z13.number(),
1495
- receiptId: z13.string(),
1496
- event: z13.string(),
1497
- githubUrl: z13.string()
1756
+ automation: z14.object({
1757
+ automationId: z14.string(),
1758
+ automationRevision: z14.number(),
1759
+ receiptId: z14.string(),
1760
+ event: z14.string(),
1761
+ githubUrl: z14.string()
1498
1762
  }).optional(),
1763
+ /**
1764
+ * Provenance for a task a SCHEDULED automation launched. A separate optional key rather than a
1765
+ * loosened `automation`: `runs.json` is parsed as one array, so a downgraded cezar meeting a
1766
+ * record without `githubUrl` would drop every run, whereas an unknown key it simply strips.
1767
+ */
1768
+ automationTrigger: z14.object({
1769
+ automationId: z14.string(),
1770
+ automationRevision: z14.number(),
1771
+ receiptId: z14.string(),
1772
+ trigger: z14.enum(["schedule", "catch-up", "manual"]),
1773
+ /** The scheduled instant (UTC ISO); for `manual`, the launch time. */
1774
+ occurrenceAt: z14.string()
1775
+ }).optional(),
1776
+ /** A pending worker destroy's automatic retry state (hearsay-tools/cezarion#879). Here, not in
1777
+ * the strict worker `delegation`, so an older cezar strips it instead of quarantining the worker,
1778
+ * and keeps it across its own writes. The API shows it as the worker's `destroy.retry`. */
1779
+ destroyRetry: workerDestroyRetrySchema.optional(),
1499
1780
  /** Task webhook opt-in (#589): the project's webhook receives this run's status changes.
1500
1781
  * Absent = off. Changes after start through `POST /runs/:id/notify`, which is why it is not
1501
1782
  * part of the idempotent-start hash. */
1502
- notify: z13.boolean().optional(),
1783
+ notify: z14.boolean().optional(),
1503
1784
  /** The last webhook delivery's outcome (#589). Absent until a delivery was attempted. */
1504
1785
  webhook: runWebhookOutcomeSchema.optional(),
1505
1786
  status: runStatusSchema,
@@ -1508,88 +1789,90 @@ var runRecordSchema = z13.object({
1508
1789
  activity: runActivitySchema.optional(),
1509
1790
  /** Derived from valid human questions and matching delivery receipts in durable history.
1510
1791
  * List attention only; never authorization to deliver an answer or wake a worker. */
1511
- hasPendingHumanAsk: z13.boolean().optional(),
1792
+ hasPendingHumanAsk: z14.boolean().optional(),
1512
1793
  /** Exact ISO-8601 deadline for the next automatic monitoring check. */
1513
- monitoringWakeAt: z13.string().optional(),
1794
+ monitoringWakeAt: z14.string().optional(),
1514
1795
  /** The current live monitoring epoch exhausted its 40 automatic checks. */
1515
- monitoringWakeCapReached: z13.boolean().optional(),
1796
+ monitoringWakeCapReached: z14.boolean().optional(),
1516
1797
  /** Exact ISO-8601 instant this run resumes itself after a provider usage limit stopped it
1517
1798
  * (spec 2026-08-03-auto-resume-after-usage-limit). Present only on a `failed` run with a
1518
1799
  * pending automatic resume — its absence is what "no resume is scheduled" looks like. */
1519
- autoResumeAt: z13.string().optional(),
1800
+ autoResumeAt: z14.string().optional(),
1520
1801
  /** Consecutive automatic resumes since the last human turn, against the safety cap. */
1521
- autoResumeAttempts: z13.number().optional(),
1522
- createdAt: z13.string(),
1523
- startedAt: z13.string().optional(),
1524
- finishedAt: z13.string().optional(),
1525
- tokensUsed: z13.number(),
1802
+ autoResumeAttempts: z14.number().optional(),
1803
+ createdAt: z14.string(),
1804
+ startedAt: z14.string().optional(),
1805
+ finishedAt: z14.string().optional(),
1806
+ tokensUsed: z14.number(),
1526
1807
  inputTokens: usageCounterSchema.optional(),
1527
1808
  outputTokens: usageCounterSchema.optional(),
1528
- costUsd: z13.number().optional(),
1529
- pullRequestUrl: z13.string().optional(),
1809
+ costUsd: z14.number().optional(),
1810
+ pullRequestUrl: z14.string().optional(),
1530
1811
  /** The PR this task is ABOUT (#407) — auto-discovered from conversation references. Display
1531
1812
  * tier only: `pullRequestUrl` (the PR this task CREATED) wins, and the action gates ignore it. */
1532
- referencedPullRequestUrl: z13.string().optional(),
1813
+ referencedPullRequestUrl: z14.string().optional(),
1533
1814
  /** The PR/issue number this task is ABOUT (task auto-naming spec) — display tier only. */
1534
- prNumber: z13.number().optional(),
1535
- issueNumber: z13.number().optional(),
1815
+ prNumber: z14.number().optional(),
1816
+ issueNumber: z14.number().optional(),
1536
1817
  /** Server-side provenance: referenced-issue discovery currently owns `issueNumber`. */
1537
- referencedIssueNumberSeeded: z13.boolean().optional(),
1818
+ referencedIssueNumberSeeded: z14.boolean().optional(),
1538
1819
  /** 'user' = renamed via PATCH, never auto-overwritten; 'marker' = agent-declared via
1539
1820
  * CEZ:TITLE (spec 2026-07-18-task-ref-markers); 'auto' = namer-owned. */
1540
- titleOrigin: z13.enum(["user", "auto", "marker"]).optional(),
1821
+ titleOrigin: z14.enum(["user", "auto", "marker"]).optional(),
1541
1822
  /** References the agent declared via CEZ:PR/CEZ:ISSUE markers — authoritative over the namer
1542
1823
  * for the matching kind. */
1543
- markerRefs: z13.object({ pr: z13.number().optional(), issue: z13.number().optional() }).optional(),
1824
+ markerRefs: z14.object({ pr: z14.number().optional(), issue: z14.number().optional() }).optional(),
1544
1825
  /** The referenced tier's working set (distinct PR URLs spotted, capped server-side). */
1545
- referencedPrCandidates: z13.array(z13.string()).optional(),
1826
+ referencedPrCandidates: z14.array(z14.string()).optional(),
1546
1827
  /** The issue this task is ABOUT (spec 2026-07-21-report-ref-discovery). Display-only. */
1547
- referencedIssueUrl: z13.string().optional(),
1828
+ referencedIssueUrl: z14.string().optional(),
1548
1829
  /** The referenced-issue working set, persisted like `referencedPrCandidates`. Capped. */
1549
- referencedIssueCandidates: z13.array(z13.string()).optional(),
1830
+ referencedIssueCandidates: z14.array(z14.string()).optional(),
1550
1831
  /** Explicit execution policy. `false` means the run intentionally uses the repo root;
1551
1832
  * absent on older runs and for the default isolated-worktree mode. */
1552
- worktree: z13.literal(false).optional(),
1833
+ worktree: z14.literal(false).optional(),
1553
1834
  /** Absent for in-place runs and after an isolated worktree is removed. */
1554
- worktreePath: z13.string().optional(),
1555
- branch: z13.string().optional(),
1835
+ worktreePath: z14.string().optional(),
1836
+ branch: z14.string().optional(),
1556
1837
  /** Stable baseline for session git views: a worktree's fork ref, or an in-place run's starting commit. */
1557
- baseBranch: z13.string().optional(),
1838
+ baseBranch: z14.string().optional(),
1558
1839
  /** Set when count-based retention (#483) reclaimed the worktree DIRECTORY (the branch is
1559
1840
  * kept): the dir is gone but recoverable. */
1560
- worktreeReclaimedAt: z13.string().optional(),
1841
+ worktreeReclaimedAt: z14.string().optional(),
1842
+ /** The worktree setup this run's isolated worktree got (#917). Absent when none ran. */
1843
+ worktreeSetup: runWorktreeSetupSchema.optional(),
1561
1844
  /** Parallel variants (spec 010): runs sharing a groupId are one group. */
1562
- groupId: z13.string().optional(),
1845
+ groupId: z14.string().optional(),
1563
1846
  /** Variant letter within the group — 'A' | 'B' | 'C'. */
1564
- variant: z13.string().optional(),
1847
+ variant: z14.string().optional(),
1565
1848
  /** Idempotent start (#504): the caller's request id and the hash of the start payload it
1566
1849
  * named (`src/runs/client-request.ts`). Absent on every run started without one. */
1567
- clientRequestId: z13.string().optional(),
1568
- clientRequestHash: z13.string().optional(),
1569
- peakRssBytes: z13.number().optional(),
1570
- peakProcCount: z13.number().optional(),
1571
- archived: z13.boolean(),
1572
- archivedAt: z13.string().optional(),
1850
+ clientRequestId: z14.string().optional(),
1851
+ clientRequestHash: z14.string().optional(),
1852
+ peakRssBytes: z14.number().optional(),
1853
+ peakProcCount: z14.number().optional(),
1854
+ archived: z14.boolean(),
1855
+ archivedAt: z14.string().optional(),
1573
1856
  /** Pinned to the top of this project's task list (#935) — the `Pinned` group above
1574
1857
  * `Needs you`. Optional, unlike `archived`: absent IS "not pinned", which is what every
1575
1858
  * record written before this carries, and the store never writes `false`. Archiving
1576
1859
  * clears it, because archiving is how a user resigns from a task. */
1577
- pinned: z13.boolean().optional(),
1860
+ pinned: z14.boolean().optional(),
1578
1861
  /** When the pin was set. Deliberately WRITE-ONLY today, like the `archivedAt` above it:
1579
1862
  * ordering inside `Pinned` uses the ordinary status/recency rules, so nothing reads this
1580
1863
  * yet. It is here because a field on a protected surface is far cheaper to add now than to
1581
1864
  * add later — "pinned oldest first" and "unpin what you pinned a month ago" both need it,
1582
1865
  * and neither can be reconstructed after the fact. */
1583
- pinnedAt: z13.string().optional(),
1866
+ pinnedAt: z14.string().optional(),
1584
1867
  /** Read receipt (#unread-done-items): ISO time the cockpit last opened this run's
1585
1868
  * thread. A finished (`done`/`failed`) run reads as *unread* until seen since it
1586
1869
  * finished — see `isUnread()` in the cockpit's `lib/read-state.ts`. Absent on old
1587
1870
  * runs, on any run not yet opened, and on one deliberately put back to unread via
1588
1871
  * `POST /runs/:id/unread` (#775) — all three count as unread. */
1589
- seenAt: z13.string().optional(),
1590
- currentStepId: z13.string().optional(),
1591
- error: z13.string().optional(),
1592
- steps: z13.array(stepStateSchema),
1872
+ seenAt: z14.string().optional(),
1873
+ currentStepId: z14.string().optional(),
1874
+ error: z14.string().optional(),
1875
+ steps: z14.array(stepStateSchema),
1593
1876
  /**
1594
1877
  * The persisted workflow definition, so a `queued` run survives a restart — including the ad-hoc
1595
1878
  * "(planned)" chains that exist nowhere else.
@@ -1607,48 +1890,45 @@ var runRecordSchema = z13.object({
1607
1890
  var apiRunSchema = runRecordSchema.extend({
1608
1891
  /** Read-only GET /runs/:id verdict: null permits Finish, a string explains refusal.
1609
1892
  * Absent on lists, stored records and mutation responses; absence is not permission. */
1610
- finishBlocked: z13.string().nullable().optional(),
1893
+ finishBlocked: z14.string().nullable().optional(),
1611
1894
  /** Server-resolved Cursor CLI command, including the configured executable. Never persisted. */
1612
- cliResumeCommand: z13.string().optional(),
1895
+ cliResumeCommand: z14.string().optional(),
1613
1896
  usage: processUsageSchema.optional()
1614
1897
  });
1615
- var runIndexEntrySchema = z13.object({
1616
- /** The registered project this run belongs to. Joins against `GET /projects`. */
1617
- projectId: z13.string(),
1618
- id: z13.string(),
1619
- title: z13.string(),
1620
- titleSummary: z13.string().optional(),
1621
- titleOrigin: z13.enum(["user", "auto", "marker"]).optional(),
1898
+ var runSummarySchema = z14.object({
1899
+ id: z14.string(),
1900
+ title: z14.string(),
1901
+ titleSummary: z14.string().optional(),
1902
+ titleOrigin: z14.enum(["user", "auto", "marker"]).optional(),
1622
1903
  status: runStatusSchema,
1623
1904
  activity: runActivitySchema.optional(),
1624
1905
  hasPendingHumanAsk: runRecordSchema.shape.hasPendingHumanAsk,
1625
1906
  /** Only the relationship role and wait phase used by list attention. */
1626
1907
  delegation: runDelegationSummarySchema.optional(),
1627
- createdAt: z13.string(),
1628
- finishedAt: z13.string().optional(),
1908
+ createdAt: z14.string(),
1909
+ finishedAt: z14.string().optional(),
1629
1910
  /** With `status`/`finishedAt`/`archived`, the four inputs `isUnread` reads — what lets the
1630
1911
  * palette lead with "finished while you weren't looking" across every project, not just the
1631
1912
  * one you happen to be standing in. */
1632
- seenAt: z13.string().optional(),
1913
+ seenAt: z14.string().optional(),
1633
1914
  /** Always present, like `RunRecord.archived`: absent would read as "not archived", and the
1634
1915
  * unread rule treats archiving as a stronger "done with this" than reading. */
1635
- archived: z13.boolean(),
1916
+ archived: z14.boolean(),
1636
1917
  /** A run parked by a provider usage limit is `failed` on the record with a resume booked
1637
1918
  * (spec 2026-08-03-auto-resume-after-usage-limit). Both `deriveAttention` and `isUnread` read
1638
1919
  * it, so without it here a cross-project row would show a red "failed" dot and land in
1639
1920
  * Recently finished for work that is simply waiting for its appointment. */
1640
- autoResumeAt: z13.string().optional(),
1921
+ autoResumeAt: z14.string().optional(),
1641
1922
  /** The workflow the run executes — the global Tasks page shows it in a column and groups by
1642
- * it. Always present on the record (`RunRecord.workflow`), so required here; the display
1643
- * refinement `workflowLabel` applies needs `steps[]`, which this row deliberately omits, so
1644
- * a `(planned)` chain reads as itself here rather than as its first agent's name. */
1645
- workflow: z13.string(),
1923
+ * it. Always present on the record (`RunRecord.workflow`), so required here. The display
1924
+ * name, which reads a `(planned)` chain as its first agent's name, is `workflowLabel` below. */
1925
+ workflow: z14.string(),
1646
1926
  /** The task's branch, when it has one — a column on the global page, and the one field that
1647
1927
  * makes a cross-project row identifiable at a glance without opening it. */
1648
- branch: z13.string().optional(),
1928
+ branch: z14.string().optional(),
1649
1929
  /** When the agent actually started, as opposed to when the task was created. The global page's
1650
1930
  * age column prefers it and falls back to `createdAt`, exactly as the per-project table does. */
1651
- startedAt: z13.string().optional(),
1931
+ startedAt: z14.string().optional(),
1652
1932
  /**
1653
1933
  * The six fields `taskReference()` (`web/src/lib/tasks-table.ts`) reads to decide a task's PR
1654
1934
  * or issue chip. Carried verbatim rather than pre-resolved into a `{kind, number, url}` on the
@@ -1660,20 +1940,20 @@ var runIndexEntrySchema = z13.object({
1660
1940
  * Six scalars is still the slim row this schema exists to keep: `steps[]` and `workflowDef`,
1661
1941
  * the expensive half, stay off it.
1662
1942
  */
1663
- pullRequestUrl: z13.string().optional(),
1664
- referencedPullRequestUrl: z13.string().optional(),
1665
- prNumber: z13.number().optional(),
1666
- issueNumber: z13.number().optional(),
1667
- referencedIssueUrl: z13.string().optional(),
1668
- markerRefs: z13.object({ pr: z13.number().optional(), issue: z13.number().optional() }).optional(),
1943
+ pullRequestUrl: z14.string().optional(),
1944
+ referencedPullRequestUrl: z14.string().optional(),
1945
+ prNumber: z14.number().optional(),
1946
+ issueNumber: z14.number().optional(),
1947
+ referencedIssueUrl: z14.string().optional(),
1948
+ markerRefs: z14.object({ pr: z14.number().optional(), issue: z14.number().optional() }).optional(),
1669
1949
  /** What the run has cost so far. Absent means nothing was recorded, which is NOT `$0` — the
1670
1950
  * cockpit prints an em dash rather than claiming a measurement that never happened. */
1671
- costUsd: z13.number().optional(),
1951
+ costUsd: z14.number().optional(),
1672
1952
  /** The persisted high-water marks a FINISHED run leaves behind. `usage` below stops existing
1673
1953
  * the moment the process tree does, so without these a finished row could say nothing at all
1674
1954
  * about what it took to run. */
1675
- peakRssBytes: z13.number().optional(),
1676
- peakProcCount: z13.number().optional(),
1955
+ peakRssBytes: z14.number().optional(),
1956
+ peakProcCount: z14.number().optional(),
1677
1957
  /**
1678
1958
  * The live CPU/RSS sample of this run's process tree, attached on the way out exactly as
1679
1959
  * `GET /runs` attaches it (`withUsage`) — never persisted.
@@ -1683,92 +1963,219 @@ var runIndexEntrySchema = z13.object({
1683
1963
  * belongs to. That is what lets a cross-project table show live usage without opening one
1684
1964
  * event stream per project (it could not — the run stream is project-scoped).
1685
1965
  */
1686
- usage: processUsageSchema.optional()
1687
- });
1688
- var referenceStatusesByProjectSchema = z13.record(
1689
- z13.string(),
1690
- z13.object({
1691
- prs: z13.record(z13.number(), referenceStatusSchema),
1692
- issues: z13.record(z13.number(), referenceStatusSchema)
1966
+ usage: processUsageSchema.optional(),
1967
+ /** The Workflow column's text (#817): for a `(planned)` or `(inbox)` chain, its first agent
1968
+ * step's name when it has one, otherwise `workflow`. Derived here because it is the one thing
1969
+ * a list row ever read off `steps[]`. */
1970
+ workflowLabel: z14.string(),
1971
+ /** Variant group membership (spec 010): the list collapses a group into one row. */
1972
+ groupId: z14.string().optional(),
1973
+ variant: z14.string().optional(),
1974
+ pinned: z14.boolean().optional(),
1975
+ runner: runRecordSchema.shape.runner,
1976
+ model: z14.string().optional(),
1977
+ notify: z14.boolean().optional(),
1978
+ diffStat: diffStatSchema.optional(),
1979
+ tokensUsed: z14.number(),
1980
+ inputTokens: runRecordSchema.shape.inputTokens,
1981
+ outputTokens: runRecordSchema.shape.outputTokens,
1982
+ currentStepId: z14.string().optional(),
1983
+ /** The backend of the step `currentStepId` names, when it recorded one — the conversation view
1984
+ * labels a delegated peer by the agent actually running it, which can differ from `runner`. */
1985
+ currentStepBackend: runnerSchema.optional(),
1986
+ error: z14.string().optional(),
1987
+ /** Present while the run's isolated worktree exists — the breadcrumb says "Isolated worktree". */
1988
+ worktreePath: z14.string().optional()
1989
+ });
1990
+ var runIndexEntrySchema = runSummarySchema.extend({
1991
+ /** The registered project this run belongs to. Joins against `GET /projects`. */
1992
+ projectId: z14.string()
1993
+ });
1994
+ var SUMMARY_OPTIONAL_KEYS = [
1995
+ "titleSummary",
1996
+ "titleOrigin",
1997
+ "activity",
1998
+ "hasPendingHumanAsk",
1999
+ "finishedAt",
2000
+ "seenAt",
2001
+ "autoResumeAt",
2002
+ "branch",
2003
+ "startedAt",
2004
+ "pullRequestUrl",
2005
+ "referencedPullRequestUrl",
2006
+ "prNumber",
2007
+ "issueNumber",
2008
+ "referencedIssueUrl",
2009
+ "markerRefs",
2010
+ "costUsd",
2011
+ "peakRssBytes",
2012
+ "peakProcCount",
2013
+ "groupId",
2014
+ "variant",
2015
+ "pinned",
2016
+ "runner",
2017
+ "model",
2018
+ "notify",
2019
+ "diffStat",
2020
+ "inputTokens",
2021
+ "outputTokens",
2022
+ "currentStepId",
2023
+ "error",
2024
+ "worktreePath"
2025
+ ];
2026
+ function runWorkflowLabel(run) {
2027
+ if (run.workflow === "(planned)" || run.workflow === "(inbox)") {
2028
+ const agent = (run.steps ?? []).find((step) => step.kind === "agent");
2029
+ if (agent?.name) return agent.name;
2030
+ }
2031
+ return run.workflow;
2032
+ }
2033
+ function toRunSummary(run) {
2034
+ const summary = {
2035
+ id: run.id,
2036
+ title: run.title,
2037
+ status: run.status,
2038
+ createdAt: run.createdAt,
2039
+ archived: run.archived,
2040
+ workflow: run.workflow,
2041
+ workflowLabel: runWorkflowLabel(run),
2042
+ tokensUsed: run.tokensUsed
2043
+ };
2044
+ for (const key of SUMMARY_OPTIONAL_KEYS) {
2045
+ if (run[key] !== void 0) summary[key] = run[key];
2046
+ }
2047
+ const currentStepBackend = (run.steps ?? []).find((step) => step.id === run.currentStepId)?.backend;
2048
+ if (currentStepBackend !== void 0) summary.currentStepBackend = currentStepBackend;
2049
+ if (run.delegation) {
2050
+ const delegation = runDelegationSummarySchema.safeParse(run.delegation);
2051
+ summary.delegation = delegation.success ? delegation.data : { role: "invalid" };
2052
+ }
2053
+ if (run.usage) summary.usage = run.usage;
2054
+ return summary;
2055
+ }
2056
+ var referenceStatusesByProjectSchema = z14.record(
2057
+ z14.string(),
2058
+ z14.object({
2059
+ prs: z14.record(z14.number(), referenceStatusSchema),
2060
+ issues: z14.record(z14.number(), referenceStatusSchema)
1693
2061
  })
1694
2062
  );
1695
- var runsIndexResponseSchema = z13.object({
1696
- /** Newest first, across every registered project. Archived runs are included — `GET /runs`
1697
- * carries them for the project you are standing in, and a finder that dropped them elsewhere
1698
- * would make a task vanish the moment you left its project. */
1699
- runs: z13.array(runIndexEntrySchema),
2063
+ var ARCHIVED_RUNS_PAGE_DEFAULT = 50;
2064
+ var ARCHIVED_RUNS_PAGE_MAX = 200;
2065
+ var runSummariesQuerySchema = z14.object({
2066
+ archived: z14.enum(["recent", "all"]).optional()
2067
+ });
2068
+ var archivedRunsQuerySchema = z14.object({
2069
+ /** `nextCursor` from the previous page. Opaque: a malformed one answers 400. */
2070
+ before: z14.string().optional(),
2071
+ limit: z14.coerce.number().int().min(1).max(ARCHIVED_RUNS_PAGE_MAX).optional(),
2072
+ /** Only runs that match (`matchesRunQuery`): title, id, branch, workflow, PR or issue. */
2073
+ q: z14.string().optional()
2074
+ });
2075
+ var archivedRunsResponseSchema = z14.object({
2076
+ runs: z14.array(runSummarySchema),
2077
+ /** The `before` of the next page, or null on the last one. */
2078
+ nextCursor: z14.string().nullable(),
2079
+ /** How many archived root runs match, across every page. */
2080
+ total: z14.number().int().nonnegative()
2081
+ });
2082
+ var runsIndexResponseSchema = z14.object({
2083
+ /** Newest first, across every registered project: each project's window (#864) — every
2084
+ * unarchived root run, plus its newest `perProjectLimit` archived root runs. Owned workers are
2085
+ * never included. Older archived runs are
2086
+ * reached through `GET /workspace/runs-search`. */
2087
+ runs: z14.array(runIndexEntrySchema),
1700
2088
  /** Additive: absent statuses mean "nothing warm", never "nothing to show". */
1701
2089
  referenceStatuses: referenceStatusesByProjectSchema,
1702
- /** The per-project cap that produced this list. */
1703
- perProjectLimit: z13.number(),
1704
- /** Ids of the projects that had more runs than the cap allowed. */
1705
- truncated: z13.array(z13.string())
1706
- });
1707
- var createRunResponseSchema = z13.union([
2090
+ /** How many archived root runs each project contributes at most. Unarchived roots are never cut. */
2091
+ perProjectLimit: z14.number(),
2092
+ /** Ids of the projects that had more archived root runs than `perProjectLimit`. */
2093
+ truncated: z14.array(z14.string())
2094
+ });
2095
+ var RUNS_SEARCH_PER_PROJECT_MAX = 50;
2096
+ var runsSearchQuerySchema = z14.object({
2097
+ /** Every whitespace-separated token must match (`matchesRunQuery`). At least two characters:
2098
+ * one matches nearly every run. */
2099
+ q: z14.string().trim().min(2),
2100
+ limit: z14.coerce.number().int().min(1).max(RUNS_SEARCH_PER_PROJECT_MAX).optional()
2101
+ });
2102
+ var runsSearchResponseSchema = z14.object({
2103
+ /** Root runs, archived or not, newest first across every registered project. */
2104
+ runs: z14.array(runIndexEntrySchema),
2105
+ /** Ids of the projects that had more matches than `limit`. */
2106
+ truncated: z14.array(z14.string())
2107
+ });
2108
+ var createRunResponseSchema = z14.union([
1708
2109
  runRecordSchema,
1709
- z13.object({ runs: z13.array(runRecordSchema) })
2110
+ z14.object({ runs: z14.array(runRecordSchema) })
1710
2111
  ]);
1711
- var cancelResponseSchema = z13.object({ cancelled: z13.boolean() });
1712
- var cancelAutoResumeResponseSchema = z13.object({ cancelled: z13.literal(true) });
1713
- var archiveFinishedResponseSchema = z13.object({ archived: z13.number() });
1714
- var markAllReadResponseSchema = z13.object({ read: z13.number() });
1715
- var deleteRunResponseSchema = z13.object({ deleted: z13.literal(true) });
1716
- var finishResponseSchema = z13.object({ finished: z13.literal(true) });
1717
- var continueResponseSchema = z13.object({ continued: z13.literal(true) });
1718
- var createPrResponseSchema = z13.object({
1719
- url: z13.string(),
1720
- dryRun: z13.boolean()
1721
- });
1722
- var messageResponseSchema = z13.union([
1723
- z13.object({ delivered: z13.literal(true) }),
1724
- z13.object({ queued: z13.literal(true), message: queuedMessageSchema }),
1725
- z13.object({ deferred: z13.literal(true) })
2112
+ var cancelResponseSchema = z14.object({ cancelled: z14.boolean() });
2113
+ var cancelAutoResumeResponseSchema = z14.object({ cancelled: z14.literal(true) });
2114
+ var archiveFinishedScopeSchema = z14.enum(["unpinned", "pinned"]);
2115
+ var archiveFinishedRequestSchema = z14.object({ scope: archiveFinishedScopeSchema.optional() });
2116
+ var archiveFinishedResponseSchema = z14.object({
2117
+ archived: z14.number(),
2118
+ ids: z14.array(z14.string()),
2119
+ pinnedIds: z14.array(z14.string())
2120
+ });
2121
+ var markAllReadResponseSchema = z14.object({ read: z14.number() });
2122
+ var deleteRunResponseSchema = z14.object({ deleted: z14.literal(true) });
2123
+ var finishResponseSchema = z14.object({ finished: z14.literal(true) });
2124
+ var continueResponseSchema = z14.object({ continued: z14.literal(true) });
2125
+ var createPrResponseSchema = z14.object({
2126
+ url: z14.string(),
2127
+ dryRun: z14.boolean()
2128
+ });
2129
+ var messageResponseSchema = z14.union([
2130
+ z14.object({ delivered: z14.literal(true) }),
2131
+ z14.object({ queued: z14.literal(true), message: queuedMessageSchema }),
2132
+ z14.object({ deferred: z14.literal(true) })
1726
2133
  ]);
1727
- var editQueuedMessageResponseSchema = z13.object({ message: queuedMessageSchema });
1728
- var removeQueuedMessageResponseSchema = z13.object({ removed: z13.literal(true) });
1729
- var openInCliResponseSchema = z13.object({
1730
- opened: z13.literal(true),
1731
- command: z13.string()
1732
- });
1733
- var removeWorktreeResponseSchema = z13.object({ removed: z13.literal(true) });
1734
- var gitCommitResponseSchema = z13.object({
1735
- committed: z13.literal(true),
1736
- sha: z13.string()
1737
- });
1738
- var gitPushResponseSchema = z13.object({
1739
- pushed: z13.literal(true),
1740
- branch: z13.string(),
1741
- remote: z13.string(),
1742
- upstreamSet: z13.boolean()
1743
- });
1744
- var runCommitSchema = z13.object({
1745
- sha: z13.string(),
1746
- subject: z13.string(),
1747
- author: z13.string(),
2134
+ var editQueuedMessageResponseSchema = z14.object({ message: queuedMessageSchema });
2135
+ var removeQueuedMessageResponseSchema = z14.object({ removed: z14.literal(true) });
2136
+ var openInCliResponseSchema = z14.object({
2137
+ opened: z14.literal(true),
2138
+ command: z14.string()
2139
+ });
2140
+ var removeWorktreeResponseSchema = z14.object({ removed: z14.literal(true) });
2141
+ var gitCommitResponseSchema = z14.object({
2142
+ committed: z14.literal(true),
2143
+ sha: z14.string()
2144
+ });
2145
+ var gitPushResponseSchema = z14.object({
2146
+ pushed: z14.literal(true),
2147
+ branch: z14.string(),
2148
+ remote: z14.string(),
2149
+ upstreamSet: z14.boolean()
2150
+ });
2151
+ var runCommitSchema = z14.object({
2152
+ sha: z14.string(),
2153
+ subject: z14.string(),
2154
+ author: z14.string(),
1748
2155
  /** Relative time ("3 hours ago") — git's `%cr`. */
1749
- when: z13.string()
2156
+ when: z14.string()
1750
2157
  });
1751
- var runCommitsResponseSchema = z13.object({ commits: z13.array(runCommitSchema) });
1752
- var groupVariantSchema = z13.object({
1753
- id: z13.string(),
2158
+ var runCommitsResponseSchema = z14.object({ commits: z14.array(runCommitSchema) });
2159
+ var groupVariantSchema = z14.object({
2160
+ id: z14.string(),
1754
2161
  /** 'A' | 'B' | 'C' in practice; `'?'` for a record that lost its letter. */
1755
- variant: z13.string(),
1756
- title: z13.string(),
2162
+ variant: z14.string(),
2163
+ title: z14.string(),
1757
2164
  status: runStatusSchema,
1758
- archived: z13.boolean(),
1759
- tokensUsed: z13.number(),
2165
+ archived: z14.boolean(),
2166
+ tokensUsed: z14.number(),
1760
2167
  inputTokens: usageCounterSchema.optional(),
1761
2168
  outputTokens: usageCounterSchema.optional(),
1762
- costUsd: z13.number().optional(),
1763
- diffStat: z13.string(),
2169
+ costUsd: z14.number().optional(),
2170
+ diffStat: z14.string(),
1764
2171
  /** First lines of the handoff journal's "## Progress log" section, as markdown. */
1765
- handoffExcerpt: z13.string()
2172
+ handoffExcerpt: z14.string()
1766
2173
  });
1767
- var groupResponseSchema = z13.object({
1768
- groupId: z13.string(),
1769
- runs: z13.array(groupVariantSchema)
2174
+ var groupResponseSchema = z14.object({
2175
+ groupId: z14.string(),
2176
+ runs: z14.array(groupVariantSchema)
1770
2177
  });
1771
- var pickVariantResponseSchema = z13.object({
2178
+ var pickVariantResponseSchema = z14.object({
1772
2179
  winner: runRecordSchema.optional()
1773
2180
  });
1774
2181
  var FILE_ATTACHMENT_MEDIA_TYPES = [
@@ -1791,80 +2198,80 @@ function isImageAttachmentName(name) {
1791
2198
  const ext = name.split(".").pop()?.toLowerCase();
1792
2199
  return ext !== void 0 && IMAGE_ATTACHMENT_EXTENSIONS.has(ext);
1793
2200
  }
1794
- var attachmentFileParamSchema = z13.object({
1795
- id: z13.string().min(1),
1796
- file: z13.string().regex(/^[A-Za-z0-9_-][A-Za-z0-9._-]*$/).refine((name) => !name.includes(".."))
2201
+ var attachmentFileParamSchema = z14.object({
2202
+ id: z14.string().min(1),
2203
+ file: z14.string().regex(/^[A-Za-z0-9_-][A-Za-z0-9._-]*$/).refine((name) => !name.includes(".."))
1797
2204
  });
1798
- var attachmentInputSchema = z13.object({
1799
- mediaType: z13.string().refine(isAttachmentMediaType, {
2205
+ var attachmentInputSchema = z14.object({
2206
+ mediaType: z14.string().refine(isAttachmentMediaType, {
1800
2207
  message: "unsupported attachment type \u2014 images, plain text, markdown and PDF only"
1801
2208
  }),
1802
- data: z13.string().min(1).max(7e6)
2209
+ data: z14.string().min(1).max(7e6)
1803
2210
  });
1804
2211
  var imageInputSchema = attachmentInputSchema;
1805
2212
  var CLIENT_REQUEST_VARIANTS_ERROR = "clientRequestId names one run; it cannot be combined with variants > 1";
1806
- var createRunInputBaseSchema = z13.object({
1807
- workflow: z13.string().min(1).optional(),
2213
+ var createRunInputBaseSchema = z14.object({
2214
+ workflow: z14.string().min(1).optional(),
1808
2215
  /** An inline chain (spec 008 — an approved plan runs as an ad-hoc workflow, never written to
1809
2216
  * a file). The catalog's own step shape, not a copy of it. */
1810
- steps: z13.array(workflowStepDefSchema).min(1).max(8).optional(),
1811
- task: z13.string().min(1).max(1e5, "must be at most 100000 characters"),
1812
- model: z13.string().optional(),
2217
+ steps: z14.array(workflowStepDefSchema).min(1).max(8).optional(),
2218
+ task: z14.string().min(1).max(1e5, "must be at most 100000 characters"),
2219
+ model: z14.string().optional(),
1813
2220
  /** Reasoning-effort pin (#45). Omit for the harness default; empty/`auto` stay implicit. */
1814
- effort: z13.string().max(32).optional(),
2221
+ effort: z14.string().max(32).optional(),
1815
2222
  runner: runnerSchema.optional(),
1816
2223
  /** Agent account for this task (spec 2026-07-29-agent-profiles). Omit to follow the
1817
2224
  * project's own selection; an id that no longer exists is a 400, not a silent default. */
1818
- agentProfile: z13.string().max(64).optional(),
2225
+ agentProfile: z14.string().max(64).optional(),
1819
2226
  /** 1–3. Above 1 the response is `{ runs }` rather than a single record. */
1820
- variants: z13.number().int().min(1).max(3).optional(),
2227
+ variants: z14.number().int().min(1).max(3).optional(),
1821
2228
  /** false → run in the repo working tree instead of an isolated worktree (read-only skills).
1822
2229
  * Omit for the default. Ignored server-side when variants > 1. */
1823
- worktree: z13.boolean().optional(),
2230
+ worktree: z14.boolean().optional(),
1824
2231
  /** true → autonomous run: never parks at "waiting"; auto-continues until done. */
1825
- autonomous: z13.boolean().optional(),
2232
+ autonomous: z14.boolean().optional(),
1826
2233
  /** false → keep the handoff journal but do not expose or request a follow-up todos file.
1827
2234
  * Omit for the default (enabled); a server with the capability off pins it to false. */
1828
- generateFollowups: z13.boolean().optional(),
2235
+ generateFollowups: z14.boolean().optional(),
1829
2236
  /** Per-run system-prompt override (R2 2.3) — programmatic callers only. Wins over the
1830
2237
  * config.json default; whitespace-only degrades to absent. */
1831
- systemPrompt: z13.string().trim().max(2e4, "must be at most 20000 characters").optional().transform((s) => s ? s : void 0),
2238
+ systemPrompt: z14.string().trim().max(2e4, "must be at most 20000 characters").optional().transform((s) => s ? s : void 0),
1832
2239
  /** Attachments pasted into the new-task form — screenshots, and since #950 PDF/TXT/MD files
1833
2240
  * too; delivered with the first agent step. The key keeps its name: the wire contract widened
1834
2241
  * in place rather than growing a second list. */
1835
- images: z13.array(attachmentInputSchema).max(4).optional(),
2242
+ images: z14.array(attachmentInputSchema).max(4).optional(),
1836
2243
  /** The inbox entry this task came from (#374). Best-effort bookkeeping: an unknown or
1837
2244
  * already-started id never fails the run. For ×2/×3 the FIRST variant is recorded. */
1838
- todoId: z13.string().min(1).max(200, "must be at most 200 characters").optional()
2245
+ todoId: z14.string().min(1).max(200, "must be at most 200 characters").optional()
1839
2246
  });
1840
2247
  var createRunInputSchema = createRunInputBaseSchema.extend({
1841
2248
  /** Idempotent start (#504): a retry with the same id and payload answers `200` with the run
1842
2249
  * the first request created; a different payload answers `409`. Scoped to the project. Not
1843
2250
  * on the base schema, so an automation's task definition cannot carry one. */
1844
- clientRequestId: z13.string().uuid().optional(),
2251
+ clientRequestId: z14.string().uuid().optional(),
1845
2252
  /** Task webhook opt-in (#589). Absent = off. `true` on a project with no webhook is a 400.
1846
2253
  * Not on the base schema, and not part of the idempotent-start hash: it can change later. */
1847
- notify: z13.boolean().optional()
2254
+ notify: z14.boolean().optional()
1848
2255
  }).refine(
1849
2256
  (b) => Boolean(b.workflow) !== Boolean(b.steps),
1850
2257
  { message: 'provide either "workflow" or "steps", not both' }
1851
2258
  ).refine((b) => !(b.clientRequestId && (b.variants ?? 1) > 1), {
1852
2259
  message: CLIENT_REQUEST_VARIANTS_ERROR
1853
2260
  });
1854
- var messageInputSchema = z13.object({
1855
- text: z13.string().max(1e5).default(""),
1856
- images: z13.array(attachmentInputSchema).max(4).default([])
2261
+ var messageInputSchema = z14.object({
2262
+ text: z14.string().max(1e5).default(""),
2263
+ images: z14.array(attachmentInputSchema).max(4).default([])
1857
2264
  }).refine((m) => m.text.trim().length > 0 || m.images.length > 0, {
1858
2265
  message: "message needs text or at least one attachment"
1859
2266
  });
1860
- var patchRunInputSchema = z13.object({
1861
- title: z13.string().trim().min(1).max(300).optional(),
1862
- task: z13.string().trim().min(1).max(1e5).optional()
2267
+ var patchRunInputSchema = z14.object({
2268
+ title: z14.string().trim().min(1).max(300).optional(),
2269
+ task: z14.string().trim().min(1).max(1e5).optional()
1863
2270
  });
1864
- var pinRunInputSchema = z13.object({ pinned: z13.boolean().optional() });
1865
- var notifyRunInputSchema = z13.object({
1866
- notify: z13.boolean(),
1867
- message: z13.string().trim().max(1e5).optional().transform((text) => text ? text : void 0)
2271
+ var pinRunInputSchema = z14.object({ pinned: z14.boolean().optional() });
2272
+ var notifyRunInputSchema = z14.object({
2273
+ notify: z14.boolean(),
2274
+ message: z14.string().trim().max(1e5).optional().transform((text) => text ? text : void 0)
1868
2275
  });
1869
2276
 
1870
2277
  // ../contract/src/attention.ts
@@ -1932,162 +2339,162 @@ function deriveAttention(run, hasPendingHumanAsk = false) {
1932
2339
  }
1933
2340
 
1934
2341
  // ../contract/src/repo.ts
1935
- import { z as z14 } from "zod";
1936
- var statusEntrySchema = z14.object({
1937
- status: z14.string(),
1938
- path: z14.string()
1939
- });
1940
- var logEntrySourceSchema = z14.object({
1941
- runId: z14.string(),
1942
- title: z14.string(),
1943
- prNumber: z14.number().nullable()
1944
- });
1945
- var logEntrySchema = z14.object({
1946
- hash: z14.string(),
1947
- subject: z14.string(),
1948
- author: z14.string(),
1949
- when: z14.string(),
1950
- at: z14.string(),
2342
+ import { z as z15 } from "zod";
2343
+ var statusEntrySchema = z15.object({
2344
+ status: z15.string(),
2345
+ path: z15.string()
2346
+ });
2347
+ var logEntrySourceSchema = z15.object({
2348
+ runId: z15.string(),
2349
+ title: z15.string(),
2350
+ prNumber: z15.number().nullable()
2351
+ });
2352
+ var logEntrySchema = z15.object({
2353
+ hash: z15.string(),
2354
+ subject: z15.string(),
2355
+ author: z15.string(),
2356
+ when: z15.string(),
2357
+ at: z15.string(),
1951
2358
  source: logEntrySourceSchema.optional()
1952
2359
  });
1953
- var repoTrackingSchema = z14.object({
1954
- ref: z14.string(),
1955
- ahead: z14.number(),
1956
- behind: z14.number(),
1957
- fetchedAt: z14.string().nullable()
1958
- });
1959
- var repoResponseSchema = z14.union([
1960
- z14.object({
1961
- info: z14.null(),
1962
- status: z14.array(z14.never()),
1963
- log: z14.array(z14.never()),
1964
- branches: z14.array(z14.never()),
1965
- baseBranch: z14.null(),
1966
- tracking: z14.null()
2360
+ var repoTrackingSchema = z15.object({
2361
+ ref: z15.string(),
2362
+ ahead: z15.number(),
2363
+ behind: z15.number(),
2364
+ fetchedAt: z15.string().nullable()
2365
+ });
2366
+ var repoResponseSchema = z15.union([
2367
+ z15.object({
2368
+ info: z15.null(),
2369
+ status: z15.array(z15.never()),
2370
+ log: z15.array(z15.never()),
2371
+ branches: z15.array(z15.never()),
2372
+ baseBranch: z15.null(),
2373
+ tracking: z15.null()
1967
2374
  }),
1968
- z14.object({
2375
+ z15.object({
1969
2376
  info: repoInfoSchema,
1970
- status: z14.array(statusEntrySchema),
1971
- log: z14.array(logEntrySchema),
1972
- branches: z14.array(z14.string()),
1973
- baseBranch: z14.string().nullable(),
2377
+ status: z15.array(statusEntrySchema),
2378
+ log: z15.array(logEntrySchema),
2379
+ branches: z15.array(z15.string()),
2380
+ baseBranch: z15.string().nullable(),
1974
2381
  tracking: repoTrackingSchema.nullable()
1975
2382
  })
1976
2383
  ]);
1977
- var repoBranchResponseSchema = z14.object({
1978
- branch: z14.string(),
1979
- created: z14.boolean()
2384
+ var repoBranchResponseSchema = z15.object({
2385
+ branch: z15.string(),
2386
+ created: z15.boolean()
1980
2387
  });
1981
- var branchClassSchema = z14.enum(["active", "not-landed", "orphan", "merged", "empty", "other"]);
1982
- var branchPrStateSchema = z14.enum(["open", "draft", "merged", "closed"]);
1983
- var repoBranchEntrySchema = z14.object({
1984
- name: z14.string(),
2388
+ var branchClassSchema = z15.enum(["active", "not-landed", "orphan", "merged", "empty", "other"]);
2389
+ var branchPrStateSchema = z15.enum(["open", "draft", "merged", "closed"]);
2390
+ var repoBranchEntrySchema = z15.object({
2391
+ name: z15.string(),
1985
2392
  class: branchClassSchema,
1986
- runId: z14.string().nullable(),
1987
- title: z14.string().nullable(),
2393
+ runId: z15.string().nullable(),
2394
+ title: z15.string().nullable(),
1988
2395
  runStatus: runStatusSchema.nullable(),
1989
2396
  /** Commits on the branch that are not reachable from the base. */
1990
- ahead: z14.number(),
1991
- lastCommit: z14.object({ sha: z14.string(), subject: z14.string(), at: z14.string() }),
2397
+ ahead: z15.number(),
2398
+ lastCommit: z15.object({ sha: z15.string(), subject: z15.string(), at: z15.string() }),
1992
2399
  /** `--shortstat <base>...<branch>`, for `not-landed` and `orphan` rows only. */
1993
- diffStat: z14.object({ additions: z14.number(), deletions: z14.number() }).nullable(),
1994
- pr: z14.object({ number: z14.number(), url: z14.string(), state: branchPrStateSchema }).nullable()
1995
- });
1996
- var repoBranchesResponseSchema = z14.object({
1997
- base: z14.string(),
1998
- prStateKnown: z14.boolean(),
1999
- branches: z14.array(repoBranchEntrySchema),
2000
- counts: z14.object({ notLanded: z14.number(), cleanup: z14.number() })
2001
- });
2002
- var deleteBranchesInputSchema = z14.object({
2003
- names: z14.array(z14.string().trim().min(1).max(250)).min(1).max(500),
2004
- confirm: z14.string().optional()
2005
- });
2006
- var branchRefusalSchema = z14.object({ name: z14.string(), reason: z14.string() });
2007
- var deleteBranchesResponseSchema = z14.object({
2008
- deleted: z14.array(z14.string()),
2009
- refused: z14.array(branchRefusalSchema),
2010
- dropped: z14.array(z14.object({ sha: z14.string(), subject: z14.string() })).optional()
2011
- });
2012
- var deleteBranchesErrorSchema = z14.object({
2013
- error: z14.string(),
2014
- refused: z14.array(branchRefusalSchema)
2015
- });
2016
- var repoPullBranchesResponseSchema = z14.object({ branches: z14.array(z14.string()) });
2017
- var repoPullInputSchema = z14.object({
2018
- branch: z14.string().trim().min(1).max(200).optional(),
2019
- confirm: z14.boolean().optional()
2020
- });
2021
- var repoPullResponseSchema = z14.object({
2022
- branch: z14.string(),
2023
- pulled: z14.literal(true),
2024
- summary: z14.string()
2025
- });
2026
- var repoPullConfirmationSchema = z14.object({
2027
- error: z14.string(),
2028
- branch: z14.string(),
2029
- risks: z14.array(z14.enum(["active_runs", "dirty_tree"]))
2030
- });
2031
- var repoPullErrorSchema = z14.union([
2400
+ diffStat: z15.object({ additions: z15.number(), deletions: z15.number() }).nullable(),
2401
+ pr: z15.object({ number: z15.number(), url: z15.string(), state: branchPrStateSchema }).nullable()
2402
+ });
2403
+ var repoBranchesResponseSchema = z15.object({
2404
+ base: z15.string(),
2405
+ prStateKnown: z15.boolean(),
2406
+ branches: z15.array(repoBranchEntrySchema),
2407
+ counts: z15.object({ notLanded: z15.number(), cleanup: z15.number() })
2408
+ });
2409
+ var deleteBranchesInputSchema = z15.object({
2410
+ names: z15.array(z15.string().trim().min(1).max(250)).min(1).max(500),
2411
+ confirm: z15.string().optional()
2412
+ });
2413
+ var branchRefusalSchema = z15.object({ name: z15.string(), reason: z15.string() });
2414
+ var deleteBranchesResponseSchema = z15.object({
2415
+ deleted: z15.array(z15.string()),
2416
+ refused: z15.array(branchRefusalSchema),
2417
+ dropped: z15.array(z15.object({ sha: z15.string(), subject: z15.string() })).optional()
2418
+ });
2419
+ var deleteBranchesErrorSchema = z15.object({
2420
+ error: z15.string(),
2421
+ refused: z15.array(branchRefusalSchema)
2422
+ });
2423
+ var repoPullBranchesResponseSchema = z15.object({ branches: z15.array(z15.string()) });
2424
+ var repoPullInputSchema = z15.object({
2425
+ branch: z15.string().trim().min(1).max(200).optional(),
2426
+ confirm: z15.boolean().optional()
2427
+ });
2428
+ var repoPullResponseSchema = z15.object({
2429
+ branch: z15.string(),
2430
+ pulled: z15.literal(true),
2431
+ summary: z15.string()
2432
+ });
2433
+ var repoPullConfirmationSchema = z15.object({
2434
+ error: z15.string(),
2435
+ branch: z15.string(),
2436
+ risks: z15.array(z15.enum(["active_runs", "dirty_tree"]))
2437
+ });
2438
+ var repoPullErrorSchema = z15.union([
2032
2439
  repoPullConfirmationSchema,
2033
- z14.object({ error: z14.string() })
2440
+ z15.object({ error: z15.string() })
2034
2441
  ]);
2035
- var diffStatSchema2 = z14.object({
2036
- adds: z14.number(),
2037
- dels: z14.number(),
2038
- files: z14.number()
2442
+ var diffStatSchema2 = z15.object({
2443
+ adds: z15.number(),
2444
+ dels: z15.number(),
2445
+ files: z15.number()
2039
2446
  });
2040
- var changedFileSchema = z14.object({
2041
- path: z14.string(),
2447
+ var changedFileSchema = z15.object({
2448
+ path: z15.string(),
2042
2449
  /** Rename/copy source — present only when `status` is renamed/copied. */
2043
- oldPath: z14.string().optional(),
2044
- status: z14.enum(["added", "modified", "deleted", "renamed", "copied"]),
2045
- adds: z14.number(),
2046
- dels: z14.number(),
2450
+ oldPath: z15.string().optional(),
2451
+ status: z15.enum(["added", "modified", "deleted", "renamed", "copied"]),
2452
+ adds: z15.number(),
2453
+ dels: z15.number(),
2047
2454
  /** Binary per numstat — there is no text patch to render. */
2048
- binary: z14.boolean(),
2455
+ binary: z15.boolean(),
2049
2456
  /** True when the path is one the raw-bytes route serves as an `<img>` (#365) — present only
2050
2457
  * when true, so old clients that never read it stay correct. */
2051
- image: z14.boolean().optional(),
2458
+ image: z15.boolean().optional(),
2052
2459
  /** This file's unified-diff section; possibly `… (patch truncated)`, possibly empty. */
2053
- patch: z14.string()
2460
+ patch: z15.string()
2054
2461
  });
2055
- var changesPayloadSchema = z14.object({
2056
- files: z14.array(changedFileSchema),
2462
+ var changesPayloadSchema = z15.object({
2463
+ files: z15.array(changedFileSchema),
2057
2464
  stat: diffStatSchema2,
2058
2465
  /** Additive context for review tasks whose worktree HEAD no longer matches their own branch. */
2059
- repointedHead: z14.object({ headBranch: z14.string(), taskBranch: z14.string() }).optional()
2466
+ repointedHead: z15.object({ headBranch: z15.string(), taskBranch: z15.string() }).optional()
2060
2467
  });
2061
- var repoCommitPayloadSchema = z14.object({
2062
- sha: z14.string(),
2063
- subject: z14.string(),
2064
- author: z14.string(),
2468
+ var repoCommitPayloadSchema = z15.object({
2469
+ sha: z15.string(),
2470
+ subject: z15.string(),
2471
+ author: z15.string(),
2065
2472
  /** Relative time ("3 hours ago") — same `%cr` format as the /api/v1/repo log. */
2066
- when: z14.string(),
2067
- files: z14.array(changedFileSchema),
2473
+ when: z15.string(),
2474
+ files: z15.array(changedFileSchema),
2068
2475
  stat: diffStatSchema2
2069
2476
  });
2070
- var worktreeDirEntrySchema = z14.object({
2071
- name: z14.string(),
2072
- type: z14.enum(["dir", "file"]),
2073
- size: z14.number().optional()
2074
- });
2075
- var worktreeEntrySchema = z14.discriminatedUnion("type", [
2076
- z14.object({
2077
- type: z14.literal("dir"),
2078
- path: z14.string(),
2079
- entries: z14.array(worktreeDirEntrySchema)
2477
+ var worktreeDirEntrySchema = z15.object({
2478
+ name: z15.string(),
2479
+ type: z15.enum(["dir", "file"]),
2480
+ size: z15.number().optional()
2481
+ });
2482
+ var worktreeEntrySchema = z15.discriminatedUnion("type", [
2483
+ z15.object({
2484
+ type: z15.literal("dir"),
2485
+ path: z15.string(),
2486
+ entries: z15.array(worktreeDirEntrySchema)
2080
2487
  }),
2081
- z14.object({
2082
- type: z14.literal("file"),
2083
- path: z14.string(),
2084
- size: z14.number(),
2085
- binary: z14.boolean(),
2086
- tooLarge: z14.boolean(),
2087
- content: z14.string().optional()
2488
+ z15.object({
2489
+ type: z15.literal("file"),
2490
+ path: z15.string(),
2491
+ size: z15.number(),
2492
+ binary: z15.boolean(),
2493
+ tooLarge: z15.boolean(),
2494
+ content: z15.string().optional()
2088
2495
  })
2089
2496
  ]);
2090
- var worktreeRunStatusSchema = z14.enum([
2497
+ var worktreeRunStatusSchema = z15.enum([
2091
2498
  "queued",
2092
2499
  "running",
2093
2500
  "waiting",
@@ -2096,46 +2503,46 @@ var worktreeRunStatusSchema = z14.enum([
2096
2503
  "failed",
2097
2504
  "cancelled"
2098
2505
  ]);
2099
- var worktreeInfoSchema = z14.object({
2100
- runId: z14.string(),
2101
- title: z14.string(),
2506
+ var worktreeInfoSchema = z15.object({
2507
+ runId: z15.string(),
2508
+ title: z15.string(),
2102
2509
  status: worktreeRunStatusSchema,
2103
- branch: z14.string().nullable(),
2104
- sizeBytes: z14.number().nullable(),
2105
- finishedAt: z14.string().nullable(),
2106
- reclaimable: z14.boolean(),
2107
- pastKeep: z14.boolean()
2510
+ branch: z15.string().nullable(),
2511
+ sizeBytes: z15.number().nullable(),
2512
+ finishedAt: z15.string().nullable(),
2513
+ reclaimable: z15.boolean(),
2514
+ pastKeep: z15.boolean()
2108
2515
  });
2109
- var worktreesResponseSchema = z14.object({
2110
- worktrees: z14.array(worktreeInfoSchema),
2111
- totalBytes: z14.number().nullable(),
2112
- keep: z14.number()
2516
+ var worktreesResponseSchema = z15.object({
2517
+ worktrees: z15.array(worktreeInfoSchema),
2518
+ totalBytes: z15.number().nullable(),
2519
+ keep: z15.number()
2113
2520
  });
2114
- var reclaimWorktreeResponseSchema = z14.object({
2115
- runId: z14.string(),
2116
- worktreeReclaimedAt: z14.string()
2521
+ var reclaimWorktreeResponseSchema = z15.object({
2522
+ runId: z15.string(),
2523
+ worktreeReclaimedAt: z15.string()
2117
2524
  });
2118
- var reclaimWorktreesResponseSchema = z14.object({
2119
- reclaimed: z14.array(z14.string())
2525
+ var reclaimWorktreesResponseSchema = z15.object({
2526
+ reclaimed: z15.array(z15.string())
2120
2527
  });
2121
2528
 
2122
2529
  // ../contract/src/projects.ts
2123
- import { z as z15 } from "zod";
2124
- var projectListEntrySchema = z15.object({
2125
- id: z15.string(),
2126
- name: z15.string(),
2530
+ import { z as z16 } from "zod";
2531
+ var projectListEntrySchema = z16.object({
2532
+ id: z16.string(),
2533
+ name: z16.string(),
2127
2534
  /** Absolute, realpath-normalized repo root. */
2128
- root: z15.string(),
2129
- addedAt: z15.string(),
2130
- lastOpenedAt: z15.string(),
2131
- source: z15.enum(["local", "checkout"]),
2535
+ root: z16.string(),
2536
+ addedAt: z16.string(),
2537
+ lastOpenedAt: z16.string(),
2538
+ source: z16.enum(["local", "checkout"]),
2132
2539
  /** `not-git` is fully usable (degraded single-queue mode); only `missing` blocks. */
2133
- status: z15.enum(["ok", "missing", "not-git"]),
2540
+ status: z16.enum(["ok", "missing", "not-git"]),
2134
2541
  /** Current branch when cheaply available (omitted e.g. on an unborn HEAD). */
2135
- branch: z15.string().optional(),
2542
+ branch: z16.string().optional(),
2136
2543
  /** Which forge this project's remote belongs to (#698) — classified server-side from the
2137
2544
  * remote URL alone. Gates the project group's GitHub nav item; omitted = no forge remote. */
2138
- forge: z15.literal("github").optional(),
2545
+ forge: z16.literal("github").optional(),
2139
2546
  /**
2140
2547
  * The remote's web root, `https://github.com/owner/repo`. Rebuilt server-side from the parsed
2141
2548
  * remote rather than passed through, so a remote carrying credentials cannot leak into the
@@ -2145,10 +2552,10 @@ var projectListEntrySchema = z15.object({
2145
2552
  * the global Tasks page has one row per project, so it cannot use any single repo's base the
2146
2553
  * way a project-scoped view can. With this, every reference it shows is a link.
2147
2554
  */
2148
- repoUrl: z15.string().optional(),
2555
+ repoUrl: z16.string().optional(),
2149
2556
  /** Per-project cap on concurrently running tasks (spec 2026-07-22). Omitted = inherit the
2150
2557
  * workspace `resources.maxParallel`; a number pins this project. */
2151
- maxParallel: z15.number().optional(),
2558
+ maxParallel: z16.number().optional(),
2152
2559
  /**
2153
2560
  * Free-form labels grouping CONNECTED repositories — a `storefront` tag on the API, the web
2154
2561
  * app and the design system says those three are one piece of work spread over three repos.
@@ -2160,44 +2567,44 @@ var projectListEntrySchema = z15.object({
2160
2567
  * server-side (trimmed, deduped case-insensitively, sorted), so a consumer may compare them
2161
2568
  * directly.
2162
2569
  */
2163
- tags: z15.array(z15.string()).optional(),
2570
+ tags: z16.array(z16.string()).optional(),
2164
2571
  /** The task webhook (#589). The token is write-only: the wire says only whether one is set. */
2165
- webhook: z15.object({ url: z15.string(), tokenSet: z15.boolean() }).optional()
2572
+ webhook: z16.object({ url: z16.string(), tokenSet: z16.boolean() }).optional()
2166
2573
  });
2167
- var projectsResponseSchema = z15.object({
2168
- projects: z15.array(projectListEntrySchema),
2169
- bootProject: z15.string(),
2170
- projectsDir: z15.string()
2574
+ var projectsResponseSchema = z16.object({
2575
+ projects: z16.array(projectListEntrySchema),
2576
+ bootProject: z16.string(),
2577
+ projectsDir: z16.string()
2171
2578
  });
2172
- var registerProjectResponseSchema = z15.object({
2579
+ var registerProjectResponseSchema = z16.object({
2173
2580
  project: projectListEntrySchema,
2174
- error: z15.string().optional()
2581
+ error: z16.string().optional()
2175
2582
  });
2176
- var removeProjectResponseSchema = z15.object({
2177
- removed: z15.literal(true),
2178
- id: z15.string()
2583
+ var removeProjectResponseSchema = z16.object({
2584
+ removed: z16.literal(true),
2585
+ id: z16.string()
2179
2586
  });
2180
- var updateProjectResponseSchema = z15.object({
2587
+ var updateProjectResponseSchema = z16.object({
2181
2588
  project: projectListEntrySchema
2182
2589
  });
2183
2590
  var PROJECT_TAG_MAX_LENGTH = 32;
2184
2591
  var PROJECT_TAGS_MAX = 20;
2185
2592
  var PROJECT_WEBHOOK_URL_MAX_LENGTH = 2048;
2186
2593
  var PROJECT_WEBHOOK_TOKEN_MAX_LENGTH = 1024;
2187
- var projectWebhookUrlSchema = z15.string().trim().max(PROJECT_WEBHOOK_URL_MAX_LENGTH).pipe(z15.url({ protocol: /^https?$/, error: "webhook url must be an http(s) URL" })).refine((value) => !/^https?:\/\/[^/?#]*@/i.test(value), "webhook url must not contain credentials; put the secret in the token");
2188
- var projectWebhookInputSchema = z15.object({
2594
+ var projectWebhookUrlSchema = z16.string().trim().max(PROJECT_WEBHOOK_URL_MAX_LENGTH).pipe(z16.url({ protocol: /^https?$/, error: "webhook url must be an http(s) URL" })).refine((value) => !/^https?:\/\/[^/?#]*@/i.test(value), "webhook url must not contain credentials; put the secret in the token");
2595
+ var projectWebhookInputSchema = z16.object({
2189
2596
  url: projectWebhookUrlSchema,
2190
- token: z15.string().trim().max(PROJECT_WEBHOOK_TOKEN_MAX_LENGTH).optional()
2597
+ token: z16.string().trim().max(PROJECT_WEBHOOK_TOKEN_MAX_LENGTH).optional()
2191
2598
  });
2192
- var testProjectWebhookResponseSchema = z15.object({
2193
- ok: z15.boolean(),
2194
- status: z15.number().optional(),
2195
- error: z15.string().optional(),
2196
- dryRun: z15.boolean().optional()
2599
+ var testProjectWebhookResponseSchema = z16.object({
2600
+ ok: z16.boolean(),
2601
+ status: z16.number().optional(),
2602
+ error: z16.string().optional(),
2603
+ dryRun: z16.boolean().optional()
2197
2604
  });
2198
- var updateProjectInputSchema = z15.object({
2199
- maxParallel: z15.number().int().min(1).max(16).nullable().optional(),
2200
- tags: z15.array(z15.string().trim().min(1).max(PROJECT_TAG_MAX_LENGTH)).max(PROJECT_TAGS_MAX).nullable().optional(),
2605
+ var updateProjectInputSchema = z16.object({
2606
+ maxParallel: z16.number().int().min(1).max(16).nullable().optional(),
2607
+ tags: z16.array(z16.string().trim().min(1).max(PROJECT_TAG_MAX_LENGTH)).max(PROJECT_TAGS_MAX).nullable().optional(),
2201
2608
  /**
2202
2609
  * The task webhook (#589). `null` removes it. An omitted `token` keeps the stored one, so the
2203
2610
  * settings form can change the URL without asking for a secret it never shows again; `''`
@@ -2208,170 +2615,170 @@ var updateProjectInputSchema = z15.object({
2208
2615
  (body) => body.maxParallel !== void 0 || body.tags !== void 0 || body.webhook !== void 0,
2209
2616
  "specify maxParallel, tags or webhook"
2210
2617
  );
2211
- var checkoutProjectInputSchema = z15.object({
2212
- url: z15.string().trim().min(1).max(512),
2213
- name: z15.string().trim().max(128).optional(),
2214
- checkoutId: z15.string().trim().max(128).optional()
2618
+ var checkoutProjectInputSchema = z16.object({
2619
+ url: z16.string().trim().min(1).max(512),
2620
+ name: z16.string().trim().max(128).optional(),
2621
+ checkoutId: z16.string().trim().max(128).optional()
2215
2622
  });
2216
- var fsBrowseDirSchema = z15.object({
2217
- name: z15.string(),
2218
- path: z15.string(),
2623
+ var fsBrowseDirSchema = z16.object({
2624
+ name: z16.string(),
2625
+ path: z16.string(),
2219
2626
  /** Has a `.git` entry — drives the "git" badge. A non-repo folder is still selectable. */
2220
- isRepo: z15.boolean()
2627
+ isRepo: z16.boolean()
2221
2628
  });
2222
- var fsBrowseResponseSchema = z15.object({
2629
+ var fsBrowseResponseSchema = z16.object({
2223
2630
  /** The realpath'd directory actually listed — never the spelling asked for, so the breadcrumb
2224
2631
  * shows where the picker really is. */
2225
- path: z15.string(),
2632
+ path: z16.string(),
2226
2633
  /** `null` AT the browse root: there is no "up" out of it, and the dialog must render no parent
2227
2634
  * row rather than one that 400s. */
2228
- parent: z15.string().nullable(),
2229
- dirs: z15.array(fsBrowseDirSchema),
2635
+ parent: z16.string().nullable(),
2636
+ dirs: z16.array(fsBrowseDirSchema),
2230
2637
  /** True when the listing was capped server-side — surfaced honestly instead of showing a
2231
2638
  * silently short list. */
2232
- truncated: z15.boolean()
2639
+ truncated: z16.boolean()
2233
2640
  });
2234
- var launchKeyResponseSchema = z15.object({
2235
- key: z15.string()
2641
+ var launchKeyResponseSchema = z16.object({
2642
+ key: z16.string()
2236
2643
  });
2237
2644
 
2238
2645
  // ../contract/src/skills.ts
2239
- import { z as z16 } from "zod";
2240
- var skillSchema = z16.object({
2241
- name: z16.string(),
2242
- description: z16.string().optional(),
2646
+ import { z as z17 } from "zod";
2647
+ var skillSchema = z17.object({
2648
+ name: z17.string(),
2649
+ description: z17.string().optional(),
2243
2650
  /** Advisory hint for untouched composer run-mode choices. */
2244
- interactive: z16.literal(true).optional(),
2245
- body: z16.string(),
2246
- path: z16.string(),
2247
- source: z16.enum(["ai", "cezar", "agents", "global", "team"]),
2651
+ interactive: z17.literal(true).optional(),
2652
+ body: z17.string(),
2653
+ path: z17.string(),
2654
+ source: z17.enum(["ai", "cezar", "agents", "global", "team"]),
2248
2655
  /** Team skills only: where the definition lives in its skills repo. */
2249
- team: z16.object({
2250
- repo: z16.string(),
2251
- ref: z16.string(),
2252
- path: z16.string(),
2656
+ team: z17.object({
2657
+ repo: z17.string(),
2658
+ ref: z17.string(),
2659
+ path: z17.string(),
2253
2660
  /** True for the `SKILL.md` convention — a whole directory (references/…). */
2254
- dir: z16.boolean(),
2661
+ dir: z17.boolean(),
2255
2662
  /**
2256
2663
  * The exact commit `ref` resolved to when the skill was read (#428).
2257
2664
  *
2258
2665
  * The hand-written DTO omitted this field entirely — it was NARROWER than the route,
2259
2666
  * which has served it since #428.
2260
2667
  */
2261
- commit: z16.string().optional()
2668
+ commit: z17.string().optional()
2262
2669
  }).optional()
2263
2670
  });
2264
- var importableSkillSchema = z16.object({
2265
- name: z16.string(),
2266
- description: z16.string().optional()
2671
+ var importableSkillSchema = z17.object({
2672
+ name: z17.string(),
2673
+ description: z17.string().optional()
2267
2674
  });
2268
- var todoItemSchema = z16.object({
2269
- id: z16.string(),
2270
- ts: z16.string().optional(),
2271
- taskId: z16.string().optional(),
2272
- summary: z16.string().min(1),
2273
- action: z16.string().optional(),
2274
- prUrl: z16.string().optional(),
2275
- suggestedSkill: z16.string().optional(),
2276
- suggestedArgs: z16.string().optional(),
2277
- suggestedPrompt: z16.string().optional(),
2675
+ var todoItemSchema = z17.object({
2676
+ id: z17.string(),
2677
+ ts: z17.string().optional(),
2678
+ taskId: z17.string().optional(),
2679
+ summary: z17.string().min(1),
2680
+ action: z17.string().optional(),
2681
+ prUrl: z17.string().optional(),
2682
+ suggestedSkill: z17.string().optional(),
2683
+ suggestedArgs: z17.string().optional(),
2684
+ suggestedPrompt: z17.string().optional(),
2278
2685
  /** Explicit intent; missing infers from suggestedSkill/suggestedPrompt for old files. */
2279
- runnable: z16.boolean().optional(),
2686
+ runnable: z17.boolean().optional(),
2280
2687
  /** Set once a task was started from this entry — it then leaves the inbox and stays as
2281
2688
  * the audit trail. A later launch never overwrites the first. */
2282
- startedTaskId: z16.string().optional()
2689
+ startedTaskId: z17.string().optional()
2283
2690
  });
2284
- var removeTodoResponseSchema = z16.object({
2285
- removed: z16.literal(true)
2691
+ var removeTodoResponseSchema = z17.object({
2692
+ removed: z17.literal(true)
2286
2693
  });
2287
- var startTodoResponseSchema = z16.object({
2694
+ var startTodoResponseSchema = z17.object({
2288
2695
  run: runRecordSchema
2289
2696
  });
2290
2697
 
2291
2698
  // ../contract/src/agent-config.ts
2292
- import { z as z17 } from "zod";
2293
- var agentConfigFormatSchema = z17.enum(["json", "jsonc", "toml", "markdown"]);
2294
- var agentConfigScopeSchema = z17.enum(["user", "project", "local"]);
2295
- var agentConfigKindSchema = z17.enum(["settings", "memory", "mcp"]);
2296
- var agentConfigTrackedSchema = z17.enum(["tracked", "gitignored", "outside-repo"]);
2297
- var agentConfigFileSchema = z17.object({
2699
+ import { z as z18 } from "zod";
2700
+ var agentConfigFormatSchema = z18.enum(["json", "jsonc", "toml", "yaml", "markdown"]);
2701
+ var agentConfigScopeSchema = z18.enum(["user", "project", "local"]);
2702
+ var agentConfigKindSchema = z18.enum(["settings", "memory", "mcp"]);
2703
+ var agentConfigTrackedSchema = z18.enum(["tracked", "gitignored", "outside-repo"]);
2704
+ var agentConfigFileSchema = z18.object({
2298
2705
  /** Stable, opaque, URL-safe — the ONLY thing a client may name (traversal-proof). */
2299
- id: z17.string(),
2706
+ id: z18.string(),
2300
2707
  /** Every runner that reads this file: `<repo>/AGENTS.md` is one file, two readers. */
2301
- runners: z17.array(runnerSchema),
2708
+ runners: z18.array(runnerSchema),
2302
2709
  kind: agentConfigKindSchema,
2303
2710
  scope: agentConfigScopeSchema,
2304
- label: z17.string(),
2305
- path: z17.string(),
2711
+ label: z18.string(),
2712
+ path: z18.string(),
2306
2713
  format: agentConfigFormatSchema,
2307
2714
  tracked: agentConfigTrackedSchema,
2308
- seeded: z17.boolean(),
2309
- holdsMcp: z17.boolean(),
2715
+ seeded: z18.boolean(),
2716
+ holdsMcp: z18.boolean(),
2310
2717
  /** VERBATIM from the vendor docs. Never computed, never generic. */
2311
- precedence: z17.string(),
2718
+ precedence: z18.string(),
2312
2719
  /** Documented mid-run reload behaviour, or absent when the vendor is silent. */
2313
- hotReload: z17.string().optional(),
2314
- docsUrl: z17.string(),
2315
- exists: z17.boolean(),
2316
- size: z17.number(),
2720
+ hotReload: z18.string().optional(),
2721
+ docsUrl: z18.string(),
2722
+ exists: z18.boolean(),
2723
+ size: z18.number(),
2317
2724
  /** sha256 of the bytes, or null when absent. */
2318
- version: z17.string().nullable(),
2725
+ version: z18.string().nullable(),
2319
2726
  /** False in hosted mode (whole feature) — the client renders read-only up front. */
2320
- writable: z17.boolean(),
2321
- readOnlyReason: z17.string().optional()
2727
+ writable: z18.boolean(),
2728
+ readOnlyReason: z18.string().optional()
2322
2729
  });
2323
- var userMcpListingSchema = z17.object({
2324
- path: z17.string(),
2325
- servers: z17.array(z17.string()),
2326
- readable: z17.boolean()
2730
+ var userMcpListingSchema = z18.object({
2731
+ path: z18.string(),
2732
+ servers: z18.array(z18.string()),
2733
+ readable: z18.boolean()
2327
2734
  });
2328
- var agentConfigListingSchema = z17.object({
2329
- editable: z17.boolean(),
2330
- files: z17.array(agentConfigFileSchema),
2735
+ var agentConfigListingSchema = z18.object({
2736
+ editable: z18.boolean(),
2737
+ files: z18.array(agentConfigFileSchema),
2331
2738
  /** null in hosted mode (host-state disclosure guard). */
2332
2739
  userMcp: userMcpListingSchema.nullable()
2333
2740
  });
2334
- var agentConfigFileContentSchema = z17.object({
2335
- id: z17.string(),
2336
- path: z17.string(),
2337
- exists: z17.boolean(),
2338
- content: z17.string(),
2741
+ var agentConfigFileContentSchema = z18.object({
2742
+ id: z18.string(),
2743
+ path: z18.string(),
2744
+ exists: z18.boolean(),
2745
+ content: z18.string(),
2339
2746
  /** sha256 of the bytes, or null when the file does not exist yet. */
2340
- version: z17.string().nullable()
2747
+ version: z18.string().nullable()
2341
2748
  });
2342
- var setAgentConfigInputSchema = z17.object({
2343
- content: z17.string().max(2e6),
2344
- version: z17.string().nullable()
2749
+ var setAgentConfigInputSchema = z18.object({
2750
+ content: z18.string().max(2e6),
2751
+ version: z18.string().nullable()
2345
2752
  });
2346
2753
 
2347
2754
  // ../contract/src/agent-profiles.ts
2348
- import { z as z18 } from "zod";
2755
+ import { z as z19 } from "zod";
2349
2756
  var DEFAULT_AGENT_ACCOUNT_ID = "default";
2350
- var agentAccountFileSchema = z18.object({
2351
- id: z18.string(),
2757
+ var agentAccountFileSchema = z19.object({
2758
+ id: z19.string(),
2352
2759
  /** e.g. `settings.json` — the file's own name, since the folder is shown once on the account. */
2353
- label: z18.string(),
2760
+ label: z19.string(),
2354
2761
  /** Absolute, resolved inside this account's config folder. */
2355
- path: z18.string(),
2356
- exists: z18.boolean()
2762
+ path: z19.string(),
2763
+ exists: z19.boolean()
2357
2764
  });
2358
- var agentProfileSchema = z18.object({
2765
+ var agentProfileSchema = z19.object({
2359
2766
  /** `default` for the discovered profile, else the stored slug. */
2360
- id: z18.string(),
2767
+ id: z19.string(),
2361
2768
  provider: providerIdSchema,
2362
- label: z18.string(),
2769
+ label: z19.string(),
2363
2770
  /** As the user wrote it — a literal `~` is preserved, matching `browseRoot`/`projectsDir`. */
2364
- configDir: z18.string(),
2771
+ configDir: z19.string(),
2365
2772
  /** Expanded absolute path. Same-origin route, like `ProjectListEntry.root`. */
2366
- path: z18.string(),
2773
+ path: z19.string(),
2367
2774
  /** False for a dir the CLI has not created yet — legitimate, and NOT a reason to fall back
2368
2775
  * to another account at run time (that would silently bill the wrong subscription). */
2369
- exists: z18.boolean(),
2776
+ exists: z19.boolean(),
2370
2777
  /** Whether the dir carries this agent's own marker files. ADVISORY: an unrecognised dir is
2371
2778
  * still accepted, because "add profile → Connect → the CLI creates it" is the real flow. */
2372
- looksValid: z18.boolean(),
2779
+ looksValid: z19.boolean(),
2373
2780
  /** True for the profile cezar discovers from the environment. Never stored, never deletable. */
2374
- isDefault: z18.boolean(),
2781
+ isDefault: z19.boolean(),
2375
2782
  /** This account's own authentication state — two Claude logins answer independently.
2376
2783
  *
2377
2784
  * **Absent until the probe has warmed.** Every probe shells out to an agent CLI, and this
@@ -2382,36 +2789,37 @@ var agentProfileSchema = z18.object({
2382
2789
  status: providerStatusSchema.optional(),
2383
2790
  /** This agent's own user-scope config files, resolved inside THIS account's folder — so a
2384
2791
  * second login's `settings.json` is the one you open, not the default account's. */
2385
- files: z18.array(agentAccountFileSchema)
2792
+ files: z19.array(agentAccountFileSchema)
2386
2793
  });
2387
2794
  function agentAccountRouteId(profile) {
2388
2795
  return profile.isDefault ? `default:${profile.provider}` : profile.id;
2389
2796
  }
2390
- var agentAccountSelectionSchema = z18.object({
2391
- claude: z18.string().optional(),
2392
- codex: z18.string().optional(),
2393
- opencode: z18.string().optional(),
2394
- pi: z18.string().optional(),
2395
- cursor: z18.string().optional()
2396
- });
2397
- var agentProfilesResponseSchema = z18.object({
2398
- editable: z18.boolean(),
2399
- profiles: z18.array(agentProfileSchema),
2797
+ var agentAccountSelectionSchema = z19.object({
2798
+ claude: z19.string().optional(),
2799
+ codex: z19.string().optional(),
2800
+ opencode: z19.string().optional(),
2801
+ pi: z19.string().optional(),
2802
+ cursor: z19.string().optional(),
2803
+ omp: z19.string().optional()
2804
+ });
2805
+ var agentProfilesResponseSchema = z19.object({
2806
+ editable: z19.boolean(),
2807
+ profiles: z19.array(agentProfileSchema),
2400
2808
  /** Providers that can carry more than one account at all — what "Add account" is offered for.
2401
2809
  * OpenCode is absent: its credentials live in a SQLite DB behind a separate `OPENCODE_DB`, so
2402
2810
  * a config-dir profile would swap settings while still billing the other account. */
2403
- profileCapableProviders: z18.array(providerIdSchema),
2811
+ profileCapableProviders: z19.array(providerIdSchema),
2404
2812
  /** Which account each project uses, keyed by the project's realpath'd ROOT.
2405
2813
  *
2406
2814
  * Served here rather than on `GET /api/v1/projects` because it is stored beside the accounts it
2407
2815
  * names (`~/.cezar/agent-accounts.json`) — one file, so deleting an account and scrubbing every
2408
2816
  * reference to it is one atomic write, and neither can be dropped by a cezar version that never
2409
2817
  * heard of accounts. Empty in hosted mode, where the whole family is withheld. */
2410
- selections: z18.record(z18.string(), agentAccountSelectionSchema),
2818
+ selections: z19.record(z19.string(), agentAccountSelectionSchema),
2411
2819
  /** The machine-wide fallback account per provider, used by any repo that has chosen none. */
2412
2820
  defaults: agentAccountSelectionSchema
2413
2821
  });
2414
- var selectAgentProfileInputSchema = z18.object({
2822
+ var selectAgentProfileInputSchema = z19.object({
2415
2823
  /**
2416
2824
  * Registry slug, or the reserved `default` boot alias. Resolved to a root server-side.
2417
2825
  *
@@ -2419,108 +2827,325 @@ var selectAgentProfileInputSchema = z18.object({
2419
2827
  * chosen nothing uses, so a second login is set up once rather than per checkout. A repo's own
2420
2828
  * choice always wins over it, which is what keeps this a default and not an override.
2421
2829
  */
2422
- projectId: z18.string().min(1).max(64).nullable(),
2830
+ projectId: z19.string().min(1).max(64).nullable(),
2423
2831
  provider: providerIdSchema,
2424
- profileId: z18.string().max(64).nullable()
2832
+ profileId: z19.string().max(64).nullable()
2425
2833
  });
2426
- var agentProfileSelectionsResponseSchema = z18.object({
2427
- selections: z18.record(z18.string(), agentAccountSelectionSchema),
2834
+ var agentProfileSelectionsResponseSchema = z19.object({
2835
+ selections: z19.record(z19.string(), agentAccountSelectionSchema),
2428
2836
  /** The machine-wide fallback, for repos with no selection of their own. */
2429
2837
  defaults: agentAccountSelectionSchema
2430
2838
  });
2431
- var agentAccountStatusResponseSchema = z18.object({ status: providerStatusSchema });
2432
- var agentAccountDetailsResponseSchema = z18.object({
2433
- available: z18.boolean(),
2434
- reason: z18.string().optional(),
2435
- fields: z18.array(z18.object({ label: z18.string(), value: z18.string() }))
2839
+ var agentAccountStatusResponseSchema = z19.object({ status: providerStatusSchema });
2840
+ var agentAccountDetailsResponseSchema = z19.object({
2841
+ available: z19.boolean(),
2842
+ reason: z19.string().optional(),
2843
+ fields: z19.array(z19.object({ label: z19.string(), value: z19.string() }))
2436
2844
  });
2437
- var openAgentAccountFileInputSchema = z18.object({
2438
- file: z18.string().min(1).max(200),
2439
- target: z18.string().min(1).max(64).optional()
2845
+ var openAgentAccountFileInputSchema = z19.object({
2846
+ file: z19.string().min(1).max(200),
2847
+ target: z19.string().min(1).max(64).optional()
2440
2848
  });
2441
- var openAgentAccountFileResponseSchema = z18.object({
2442
- opened: z18.literal(true),
2443
- path: z18.string()
2849
+ var openAgentAccountFileResponseSchema = z19.object({
2850
+ opened: z19.literal(true),
2851
+ path: z19.string()
2444
2852
  });
2445
- var createAgentProfileInputSchema = z18.object({
2853
+ var createAgentProfileInputSchema = z19.object({
2446
2854
  provider: providerIdSchema,
2447
- label: z18.string().trim().max(200).optional(),
2855
+ label: z19.string().trim().max(200).optional(),
2448
2856
  /** Stored as written; validated absolute after `~` expansion, server-side. */
2449
- configDir: z18.string().trim().min(1).max(4096)
2857
+ configDir: z19.string().trim().min(1).max(4096)
2450
2858
  });
2451
- var agentProfileResponseSchema = z18.object({ profile: agentProfileSchema });
2452
- var updateAgentProfileInputSchema = z18.object({
2453
- label: z18.string().trim().max(200).optional(),
2454
- configDir: z18.string().trim().min(1).max(4096).optional()
2859
+ var agentProfileResponseSchema = z19.object({ profile: agentProfileSchema });
2860
+ var updateAgentProfileInputSchema = z19.object({
2861
+ label: z19.string().trim().max(200).optional(),
2862
+ configDir: z19.string().trim().min(1).max(4096).optional()
2455
2863
  });
2456
- var removeAgentProfileResponseSchema = z18.object({
2457
- removed: z18.literal(true),
2458
- id: z18.string()
2864
+ var removeAgentProfileResponseSchema = z19.object({
2865
+ removed: z19.literal(true),
2866
+ id: z19.string()
2459
2867
  });
2460
2868
 
2869
+ // ../contract/src/zoned-time.ts
2870
+ var formatters = /* @__PURE__ */ new Map();
2871
+ function formatter(timeZone) {
2872
+ let cached = formatters.get(timeZone);
2873
+ if (!cached) {
2874
+ cached = new Intl.DateTimeFormat("en-CA", {
2875
+ timeZone,
2876
+ year: "numeric",
2877
+ month: "2-digit",
2878
+ day: "2-digit",
2879
+ hour: "2-digit",
2880
+ minute: "2-digit",
2881
+ second: "2-digit",
2882
+ hourCycle: "h23"
2883
+ });
2884
+ formatters.set(timeZone, cached);
2885
+ }
2886
+ return cached;
2887
+ }
2888
+ function zonedParts(utcMs, timeZone) {
2889
+ try {
2890
+ const parts = formatter(timeZone).formatToParts(new Date(utcMs));
2891
+ const value = (type) => Number(parts.find((part) => part.type === type)?.value);
2892
+ const year = value("year");
2893
+ const month = value("month");
2894
+ const day = value("day");
2895
+ const hour = value("hour") % 24;
2896
+ return {
2897
+ year,
2898
+ month,
2899
+ day,
2900
+ hour,
2901
+ minute: value("minute"),
2902
+ second: value("second"),
2903
+ weekday: isoWeekday(year, month, day)
2904
+ };
2905
+ } catch {
2906
+ return null;
2907
+ }
2908
+ }
2909
+ function isoWeekday(year, month, day) {
2910
+ const dow = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
2911
+ return (dow + 6) % 7 + 1;
2912
+ }
2913
+ function timeZoneOffsetMs(timeZone, utcMs) {
2914
+ const parts = zonedParts(utcMs, timeZone);
2915
+ if (!parts) return null;
2916
+ const asUtc = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second);
2917
+ return asUtc - utcMs;
2918
+ }
2919
+ function zonedWallTimeToUtc(year, month, day, hour, minute, timeZone) {
2920
+ const wallAsUtc = Date.UTC(year, month - 1, day, hour, minute, 0, 0);
2921
+ let candidate = wallAsUtc;
2922
+ for (let i = 0; i < 3; i += 1) {
2923
+ const offset = timeZoneOffsetMs(timeZone, candidate);
2924
+ if (offset === null) return null;
2925
+ const next = wallAsUtc - offset;
2926
+ if (Math.abs(next - candidate) < 1e3) return next;
2927
+ candidate = next;
2928
+ }
2929
+ return candidate;
2930
+ }
2931
+ function isValidTimeZone(candidate) {
2932
+ if (!candidate) return false;
2933
+ try {
2934
+ formatter(candidate).format(/* @__PURE__ */ new Date(0));
2935
+ return true;
2936
+ } catch {
2937
+ return false;
2938
+ }
2939
+ }
2940
+ function localTimeZone() {
2941
+ try {
2942
+ return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
2943
+ } catch {
2944
+ return "UTC";
2945
+ }
2946
+ }
2947
+
2948
+ // ../contract/src/automation-schedule.ts
2949
+ import { z as z20 } from "zod";
2950
+ var SCHEDULE_TYPES = ["daily", "weekdays", "weekly", "hours"];
2951
+ var SCHEDULE_HOURS_OPTIONS = [1, 2, 3, 4, 6, 8, 12];
2952
+ var WEEKDAY_NAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
2953
+ var WEEKDAY_LONG = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
2954
+ var automationScheduleSchema = z20.object({
2955
+ type: z20.enum(SCHEDULE_TYPES),
2956
+ /** 0–23; `daily`, `weekdays`, `weekly`. Default 4. */
2957
+ hour: z20.number().int().min(0).max(23).optional(),
2958
+ /** 0–59; `daily`, `weekdays`, `weekly`. Default 0. */
2959
+ minute: z20.number().int().min(0).max(59).optional(),
2960
+ /** ISO weekday, Monday = 1 … Sunday = 7; `weekly`. Default 1. */
2961
+ day: z20.number().int().min(1).max(7).optional(),
2962
+ /** Hours between runs, from 00:00; `hours`. Default 6. */
2963
+ every: z20.union([
2964
+ z20.literal(1),
2965
+ z20.literal(2),
2966
+ z20.literal(3),
2967
+ z20.literal(4),
2968
+ z20.literal(6),
2969
+ z20.literal(8),
2970
+ z20.literal(12)
2971
+ ]).optional()
2972
+ });
2973
+ function normalizeSchedule(schedule) {
2974
+ return {
2975
+ type: schedule.type,
2976
+ hour: schedule.hour ?? 4,
2977
+ minute: schedule.minute ?? 0,
2978
+ day: schedule.day ?? 1,
2979
+ every: schedule.every ?? 6
2980
+ };
2981
+ }
2982
+ var pad = (n) => String(n).padStart(2, "0");
2983
+ function hm(hour, minute = 0) {
2984
+ return `${pad(hour)}:${pad(minute)}`;
2985
+ }
2986
+ function scheduleLabel(schedule) {
2987
+ const s = normalizeSchedule(schedule);
2988
+ switch (s.type) {
2989
+ case "daily":
2990
+ return `every day at ${hm(s.hour, s.minute)}`;
2991
+ case "weekdays":
2992
+ return `weekdays at ${hm(s.hour, s.minute)}`;
2993
+ case "hours":
2994
+ return s.every === 1 ? "every hour" : `every ${s.every} hours`;
2995
+ case "weekly":
2996
+ return `${WEEKDAY_LONG[s.day - 1]}s at ${hm(s.hour, s.minute)}`;
2997
+ }
2998
+ }
2999
+ function cronOf(schedule) {
3000
+ const s = normalizeSchedule(schedule);
3001
+ switch (s.type) {
3002
+ case "daily":
3003
+ return `${s.minute} ${s.hour} * * *`;
3004
+ case "weekdays":
3005
+ return `${s.minute} ${s.hour} * * 1-5`;
3006
+ case "hours":
3007
+ return `0 */${s.every} * * *`;
3008
+ case "weekly":
3009
+ return `${s.minute} ${s.hour} * * ${s.day % 7}`;
3010
+ }
3011
+ }
3012
+ function parseCron(expression) {
3013
+ const fields = expression.trim().split(/\s+/);
3014
+ if (fields.length !== 5) return null;
3015
+ const [minuteField, hourField, dom, month, dow] = fields;
3016
+ if (dom !== "*" || month !== "*") return null;
3017
+ const hoursEvery = /^\*\/(\d+)$/.exec(hourField);
3018
+ if (hoursEvery && minuteField === "0" && dow === "*") {
3019
+ const every = Number(hoursEvery[1]);
3020
+ return SCHEDULE_HOURS_OPTIONS.includes(every) ? { type: "hours", every } : null;
3021
+ }
3022
+ if (!/^\d{1,2}$/.test(minuteField) || !/^\d{1,2}$/.test(hourField)) return null;
3023
+ const minute = Number(minuteField);
3024
+ const hour = Number(hourField);
3025
+ if (minute > 59 || hour > 23) return null;
3026
+ if (dow === "*") return { type: "daily", hour, minute };
3027
+ if (dow === "1-5") return { type: "weekdays", hour, minute };
3028
+ if (/^[0-7]$/.test(dow)) {
3029
+ const cronDay = Number(dow);
3030
+ const day = cronDay === 0 ? 7 : cronDay;
3031
+ return { type: "weekly", hour, minute, day };
3032
+ }
3033
+ return null;
3034
+ }
3035
+ function wallTimesOn(s, weekday) {
3036
+ switch (s.type) {
3037
+ case "daily":
3038
+ return [[s.hour, s.minute]];
3039
+ case "weekdays":
3040
+ return weekday <= 5 ? [[s.hour, s.minute]] : [];
3041
+ case "weekly":
3042
+ return weekday === s.day ? [[s.hour, s.minute]] : [];
3043
+ case "hours": {
3044
+ const out = [];
3045
+ for (let h = 0; h < 24; h += s.every) out.push([h, 0]);
3046
+ return out;
3047
+ }
3048
+ }
3049
+ }
3050
+ function occurrencesBetween(schedule, fromMs, toMs, timeZone, limit = 1e3) {
3051
+ const s = normalizeSchedule(schedule);
3052
+ const start = zonedParts(fromMs, timeZone);
3053
+ if (!start || toMs <= fromMs) return [];
3054
+ const out = [];
3055
+ const dayCount = Math.ceil((toMs - fromMs) / 864e5) + 2;
3056
+ for (let d = -1; d <= dayCount; d += 1) {
3057
+ const date = new Date(Date.UTC(start.year, start.month - 1, start.day + d));
3058
+ const year = date.getUTCFullYear();
3059
+ const month = date.getUTCMonth() + 1;
3060
+ const day = date.getUTCDate();
3061
+ for (const [hour, minute] of wallTimesOn(s, isoWeekday(year, month, day))) {
3062
+ const at = zonedWallTimeToUtc(year, month, day, hour, minute, timeZone);
3063
+ if (at === null) return out;
3064
+ if (at === out.at(-1)) continue;
3065
+ if (at >= fromMs && at < toMs) {
3066
+ out.push(at);
3067
+ if (out.length >= limit) return out;
3068
+ }
3069
+ }
3070
+ }
3071
+ return out;
3072
+ }
3073
+ function nextOccurrence(schedule, afterMs, timeZone) {
3074
+ const [first] = occurrencesBetween(schedule, afterMs + 1, afterMs + 9 * 864e5, timeZone, 1);
3075
+ return first ?? null;
3076
+ }
3077
+
2461
3078
  // ../contract/src/automations.ts
2462
- import { z as z19 } from "zod";
2463
- var automationEventSchema = z19.enum([
3079
+ import { z as z21 } from "zod";
3080
+ var automationEventSchema = z21.enum([
2464
3081
  "pull_request.opened",
2465
3082
  "issue.opened",
2466
3083
  "issue.labeled",
2467
3084
  "issue.unlabeled"
2468
3085
  ]);
2469
- var automationFiltersSchema = z19.object({
2470
- authors: z19.array(z19.string()).optional(),
2471
- assignees: z19.array(z19.string()).optional(),
2472
- allLabels: z19.array(z19.string()).optional(),
2473
- anyLabels: z19.array(z19.string()).optional(),
2474
- excludeLabels: z19.array(z19.string()).optional(),
3086
+ var automationFiltersSchema = z21.object({
3087
+ authors: z21.array(z21.string()).optional(),
3088
+ assignees: z21.array(z21.string()).optional(),
3089
+ allLabels: z21.array(z21.string()).optional(),
3090
+ anyLabels: z21.array(z21.string()).optional(),
3091
+ excludeLabels: z21.array(z21.string()).optional(),
2475
3092
  /** Required for the two label events — the server rejects a definition without it. */
2476
- changedLabels: z19.array(z19.string()).optional(),
2477
- lookbackDays: z19.number(),
2478
- maxRecords: z19.number()
3093
+ changedLabels: z21.array(z21.string()).optional(),
3094
+ lookbackDays: z21.number(),
3095
+ maxRecords: z21.number()
2479
3096
  });
3097
+ var automationKindSchema = z21.enum(["github", "schedule"]);
2480
3098
  var automationTaskSchema = createRunInputBaseSchema.omit({ task: true, images: true, todoId: true, systemPrompt: true }).extend({
2481
3099
  /** The prompt template. `{{github.number}}`, `{{github.title}}`, `{{github.url}}` and
2482
3100
  * `{{github.labels}}` are substituted per match; GitHub content is appended as untrusted
2483
3101
  * context, never interpolated into instructions. */
2484
- prompt: z19.string(),
2485
- variants: z19.union([z19.literal(1), z19.literal(2), z19.literal(3)]).optional(),
2486
- systemPrompt: z19.string().optional()
3102
+ prompt: z21.string(),
3103
+ variants: z21.union([z21.literal(1), z21.literal(2), z21.literal(3)]).optional(),
3104
+ systemPrompt: z21.string().optional()
2487
3105
  });
2488
- var automationDefinitionSchema = z19.object({
2489
- id: z19.string(),
3106
+ var automationDefinitionSchema = z21.object({
3107
+ id: z21.string(),
2490
3108
  /** Bumped on every edit; a PUT must echo the revision it read (optimistic concurrency). */
2491
- revision: z19.number(),
2492
- name: z19.string(),
2493
- description: z19.string().optional(),
3109
+ revision: z21.number(),
3110
+ name: z21.string(),
3111
+ description: z21.string().optional(),
2494
3112
  /** Always present: the storage schema defaults it to `false`, so a definition is created
2495
3113
  * PAUSED and enabling it is a separate, baseline-establishing act. */
2496
- enabled: z19.boolean(),
2497
- events: z19.array(automationEventSchema),
2498
- intervalSeconds: z19.number(),
2499
- filters: automationFiltersSchema,
3114
+ enabled: z21.boolean(),
3115
+ kind: automationKindSchema,
3116
+ /** `github` kind: always present. `schedule` kind: absent. */
3117
+ events: z21.array(automationEventSchema).optional(),
3118
+ intervalSeconds: z21.number().optional(),
3119
+ filters: automationFiltersSchema.optional(),
3120
+ /** `schedule` kind: always present. `github` kind: absent. */
3121
+ schedule: automationScheduleSchema.optional(),
2500
3122
  task: automationTaskSchema,
2501
- createdAt: z19.string(),
2502
- updatedAt: z19.string()
3123
+ createdAt: z21.string(),
3124
+ updatedAt: z21.string()
2503
3125
  });
2504
- var automationCursorSchema = z19.object({
2505
- timestamp: z19.string(),
2506
- tieBreaker: z19.string().optional()
3126
+ var automationCursorSchema = z21.object({
3127
+ timestamp: z21.string(),
3128
+ tieBreaker: z21.string().optional()
2507
3129
  });
2508
- var automationRuntimeStateSchema = z19.object({
3130
+ var automationRuntimeStateSchema = z21.object({
2509
3131
  /** The definition revision this state belongs to; a bumped revision re-baselines. */
2510
- revision: z19.number().optional(),
3132
+ revision: z21.number().optional(),
2511
3133
  /** Enabling establishes a CURRENT-TIME baseline: records older than this never launch. */
2512
- baselineAt: z19.string().optional(),
3134
+ baselineAt: z21.string().optional(),
2513
3135
  cursor: automationCursorSchema.optional(),
2514
- frozenHighWatermark: automationCursorSchema.extend({ tieBreaker: z19.string() }).optional(),
2515
- backlogAfter: automationCursorSchema.extend({ tieBreaker: z19.string() }).optional(),
2516
- nextCheckAt: z19.string().optional(),
2517
- lastSuccessAt: z19.string().optional(),
3136
+ frozenHighWatermark: automationCursorSchema.extend({ tieBreaker: z21.string() }).optional(),
3137
+ backlogAfter: automationCursorSchema.extend({ tieBreaker: z21.string() }).optional(),
3138
+ nextCheckAt: z21.string().optional(),
3139
+ lastSuccessAt: z21.string().optional(),
3140
+ /** `schedule` kind: the next occurrence's instant and the last fired one's. */
3141
+ nextRunAt: z21.string().optional(),
3142
+ lastRunAt: z21.string().optional(),
2518
3143
  /** Per-query GitHub ETags, so an unchanged page costs no rate-limit budget. */
2519
- etags: z19.record(z19.string(), z19.string()).optional(),
2520
- backoffUntil: z19.string().optional(),
2521
- consecutiveFailures: z19.number().optional()
3144
+ etags: z21.record(z21.string(), z21.string()).optional(),
3145
+ backoffUntil: z21.string().optional(),
3146
+ consecutiveFailures: z21.number().optional()
2522
3147
  });
2523
- var automationLogResultSchema = z19.enum([
3148
+ var automationLogResultSchema = z21.enum([
2524
3149
  "launched",
2525
3150
  "no-match",
2526
3151
  "duplicate",
@@ -2528,116 +3153,136 @@ var automationLogResultSchema = z19.enum([
2528
3153
  "error",
2529
3154
  "baseline",
2530
3155
  "preview",
2531
- "skipped"
3156
+ "skipped",
3157
+ // schedule kind: a Run now launch, a missed occurrence fired once after a gap, a launch that threw.
3158
+ "manual",
3159
+ "catch-up",
3160
+ "failed"
2532
3161
  ]);
2533
- var automationLogRecordSchema = z19.object({
2534
- seq: z19.number(),
2535
- ts: z19.string(),
2536
- automationId: z19.string(),
2537
- revision: z19.number(),
3162
+ var automationLogRecordSchema = z21.object({
3163
+ seq: z21.number(),
3164
+ ts: z21.string(),
3165
+ automationId: z21.string(),
3166
+ revision: z21.number(),
2538
3167
  event: automationEventSchema.optional(),
2539
3168
  result: automationLogResultSchema,
2540
- reason: z19.string().optional(),
2541
- durationMs: z19.number().optional(),
2542
- receiptId: z19.string().optional(),
2543
- runId: z19.string().optional(),
2544
- githubNumber: z19.number().optional(),
2545
- githubTitle: z19.string().optional(),
2546
- githubUrl: z19.string().optional(),
2547
- rateLimit: z19.object({
2548
- bucket: z19.enum(["core", "search"]),
2549
- remaining: z19.number().optional(),
2550
- resetAt: z19.string().optional()
3169
+ reason: z21.string().optional(),
3170
+ durationMs: z21.number().optional(),
3171
+ receiptId: z21.string().optional(),
3172
+ runId: z21.string().optional(),
3173
+ githubNumber: z21.number().optional(),
3174
+ githubTitle: z21.string().optional(),
3175
+ githubUrl: z21.string().optional(),
3176
+ rateLimit: z21.object({
3177
+ bucket: z21.enum(["core", "search"]),
3178
+ remaining: z21.number().optional(),
3179
+ resetAt: z21.string().optional()
2551
3180
  }).optional()
2552
3181
  });
2553
- var automationCountsSchema = z19.object({
2554
- matches: z19.number(),
2555
- launched: z19.number(),
2556
- duplicates: z19.number(),
2557
- errors: z19.number()
3182
+ var automationCountsSchema = z21.object({
3183
+ /** GitHub candidates that matched a filter: `launched` + `duplicate` rows. */
3184
+ matches: z21.number(),
3185
+ /** Tasks launched: `launched`, plus a schedule's `manual` (Run now) and `catch-up` rows. */
3186
+ launched: z21.number(),
3187
+ /** `duplicate` rows: a match whose receipt already existed, so nothing launched. */
3188
+ duplicates: z21.number(),
3189
+ /** `error` and `rate-limited` rows, plus a schedule's `failed` launches. */
3190
+ errors: z21.number()
2558
3191
  });
2559
3192
  var automationListEntrySchema = automationDefinitionSchema.extend({
2560
3193
  state: automationRuntimeStateSchema.optional(),
2561
3194
  latestLog: automationLogRecordSchema.optional(),
2562
- counts: automationCountsSchema
2563
- });
2564
- var automationsResponseSchema = z19.object({
2565
- available: z19.boolean(),
2566
- reason: z19.string().optional(),
2567
- scheduler: z19.object({
2568
- state: z19.enum(["scheduled", "idle"]),
2569
- nextDue: z19.string().optional()
3195
+ counts: automationCountsSchema,
3196
+ /** Enabled only: a schedule's armed `state.nextRunAt`, a poll's `state.nextCheckAt`. Absent
3197
+ * while paused, and for a schedule the timer has not armed yet. */
3198
+ nextRunAt: z21.string().optional()
3199
+ });
3200
+ var automationsResponseSchema = z21.object({
3201
+ available: z21.boolean(),
3202
+ reason: z21.string().optional(),
3203
+ timeZone: z21.string(),
3204
+ scheduler: z21.object({
3205
+ state: z21.enum(["scheduled", "idle"]),
3206
+ nextDue: z21.string().optional()
2570
3207
  }),
2571
- automations: z19.array(automationListEntrySchema)
3208
+ automations: z21.array(automationListEntrySchema)
2572
3209
  });
2573
- var automationResponseSchema = z19.object({ automation: automationDefinitionSchema });
2574
- var automationDetailResponseSchema = z19.object({
3210
+ var automationResponseSchema = z21.object({ automation: automationDefinitionSchema });
3211
+ var automationDetailResponseSchema = z21.object({
2575
3212
  automation: automationDefinitionSchema,
2576
3213
  state: automationRuntimeStateSchema.optional(),
2577
3214
  latestLog: automationLogRecordSchema.optional()
2578
3215
  });
2579
- var automationCheckSchema = z19.object({
2580
- id: z19.string(),
2581
- automationId: z19.string(),
2582
- mode: z19.enum(["preview", "execute"]),
2583
- status: z19.enum(["queued", "running", "complete", "error"]),
2584
- createdAt: z19.string(),
2585
- completedAt: z19.string().optional(),
2586
- matches: z19.number().optional(),
2587
- truncated: z19.boolean().optional(),
2588
- error: z19.string().optional()
2589
- });
2590
- var automationCheckQueuedResponseSchema = z19.object({ checkId: z19.string() });
2591
- var automationLogResponseSchema = z19.object({
2592
- records: z19.array(automationLogRecordSchema)
2593
- });
2594
- var automationRetryResponseSchema = z19.object({
2595
- receiptId: z19.string(),
2596
- runId: z19.string()
2597
- });
2598
- var createAutomationInputSchema = automationDefinitionSchema.omit({ id: true, revision: true, createdAt: true, updatedAt: true, enabled: true }).extend({ enable: z19.boolean().optional() });
3216
+ var automationCheckSchema = z21.object({
3217
+ id: z21.string(),
3218
+ automationId: z21.string(),
3219
+ mode: z21.enum(["preview", "execute"]),
3220
+ status: z21.enum(["queued", "running", "complete", "error"]),
3221
+ createdAt: z21.string(),
3222
+ completedAt: z21.string().optional(),
3223
+ matches: z21.number().optional(),
3224
+ truncated: z21.boolean().optional(),
3225
+ error: z21.string().optional()
3226
+ });
3227
+ var automationCheckQueuedResponseSchema = z21.object({ checkId: z21.string() });
3228
+ var automationLogResponseSchema = z21.object({
3229
+ records: z21.array(automationLogRecordSchema)
3230
+ });
3231
+ var automationRetryResponseSchema = z21.object({
3232
+ receiptId: z21.string(),
3233
+ runId: z21.string()
3234
+ });
3235
+ var automationRunResponseSchema = z21.object({ runId: z21.string() });
3236
+ var createAutomationInputSchema = automationDefinitionSchema.omit({ id: true, revision: true, createdAt: true, updatedAt: true, enabled: true, kind: true }).extend({
3237
+ /** Omitted = `github` on create, the shape every pre-schedule client sends; omitted on
3238
+ * update = the stored kind. */
3239
+ kind: automationKindSchema.optional(),
3240
+ enable: z21.boolean().optional()
3241
+ });
2599
3242
  var updateAutomationInputSchema = createAutomationInputSchema.omit({ enable: true }).extend({
2600
- enabled: z19.boolean().optional(),
2601
- expectedRevision: z19.number()
3243
+ enabled: z21.boolean().optional(),
3244
+ expectedRevision: z21.number()
2602
3245
  });
2603
- var automationCheckInputSchema = z19.object({
2604
- mode: z19.enum(["preview", "execute"])
3246
+ var automationCheckInputSchema = z21.object({
3247
+ mode: z21.enum(["preview", "execute"])
2605
3248
  });
2606
3249
 
2607
3250
  // ../contract/src/artifacts.ts
2608
- import { z as z20 } from "zod";
2609
- var pathSchema = z20.string().min(1).max(8192).refine((value) => !value.includes("\0"), "Path contains NUL");
2610
- var publishedArtifactSchema = z20.object({
2611
- id: z20.uuid(),
2612
- runId: z20.uuid(),
2613
- name: z20.string().min(1).max(255),
3251
+ import { z as z22 } from "zod";
3252
+ var pathSchema = z22.string().min(1).max(8192).refine((value) => !value.includes("\0"), "Path contains NUL");
3253
+ var publishedArtifactSchema = z22.object({
3254
+ id: z22.uuid(),
3255
+ runId: z22.uuid(),
3256
+ name: z22.string().min(1).max(255),
2614
3257
  sourcePath: pathSchema.refine((value) => /^(?:\/|[A-Za-z]:[\\/]|\\\\)/.test(value), "Expected an absolute source path"),
2615
- createdAt: z20.iso.datetime(),
2616
- size: z20.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
2617
- sha256: z20.string().regex(/^[a-f0-9]{64}$/)
3258
+ createdAt: z22.iso.datetime(),
3259
+ size: z22.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
3260
+ sha256: z22.string().regex(/^[a-f0-9]{64}$/)
2618
3261
  }).strict();
2619
- var filePreviewDataSchema = z20.object({
2620
- type: z20.literal("file"),
3262
+ var filePreviewDataSchema = z22.object({
3263
+ type: z22.literal("file"),
2621
3264
  path: pathSchema,
2622
- size: z20.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
2623
- binary: z20.boolean(),
2624
- tooLarge: z20.boolean(),
2625
- content: z20.string().optional(),
2626
- source: z20.enum(["worktree", "project", "artifact"]),
3265
+ size: z22.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
3266
+ binary: z22.boolean(),
3267
+ tooLarge: z22.boolean(),
3268
+ content: z22.string().optional(),
3269
+ source: z22.enum(["worktree", "project", "artifact"]),
2627
3270
  artifact: publishedArtifactSchema.optional()
2628
3271
  }).strict();
2629
- var fileLinkResultSchema = z20.union([
3272
+ var fileLinkResultSchema = z22.union([
2630
3273
  filePreviewDataSchema,
2631
- z20.object({
2632
- type: z20.enum(["unavailable", "unpublished"]),
3274
+ z22.object({
3275
+ type: z22.enum(["unavailable", "unpublished"]),
2633
3276
  path: pathSchema,
2634
- reason: z20.string().min(1).max(4096)
3277
+ reason: z22.string().min(1).max(4096)
2635
3278
  }).strict()
2636
3279
  ]);
2637
- var artifactListSchema = z20.object({ artifacts: z20.array(publishedArtifactSchema).max(64) }).strict();
2638
- var fileLinkQuerySchema = z20.object({ path: pathSchema, raw: z20.literal("1").optional() }).strict();
2639
- var artifactParamsSchema = z20.object({ id: z20.uuid(), artifactId: z20.uuid() });
3280
+ var artifactListSchema = z22.object({ artifacts: z22.array(publishedArtifactSchema).max(64) }).strict();
3281
+ var fileLinkQuerySchema = z22.object({ path: pathSchema, raw: z22.literal("1").optional() }).strict();
3282
+ var artifactParamsSchema = z22.object({ id: z22.uuid(), artifactId: z22.uuid() });
2640
3283
  export {
3284
+ ARCHIVED_RUNS_PAGE_DEFAULT,
3285
+ ARCHIVED_RUNS_PAGE_MAX,
2641
3286
  ATTENTION_RANK,
2642
3287
  CI_WAIT_LIMITATION,
2643
3288
  CI_WAIT_RECEIPT_INSTRUCTION,
@@ -2652,7 +3297,15 @@ export {
2652
3297
  PROJECT_WEBHOOK_TOKEN_MAX_LENGTH,
2653
3298
  PROJECT_WEBHOOK_URL_MAX_LENGTH,
2654
3299
  REFERENCE_STATUS_MAX,
3300
+ RUNS_SEARCH_PER_PROJECT_MAX,
2655
3301
  RUN_HISTORY_PAGE_ITEMS,
3302
+ SCHEDULE_HOURS_OPTIONS,
3303
+ SCHEDULE_TYPES,
3304
+ WEEKDAY_NAMES,
3305
+ WORKTREE_SETUP_DEFAULT_TIMEOUT_SECONDS,
3306
+ WORKTREE_SETUP_MAX_COMMANDS,
3307
+ WORKTREE_SETUP_MAX_COMMAND_LENGTH,
3308
+ WORKTREE_SETUP_MAX_TIMEOUT_SECONDS,
2656
3309
  advancePendingHumanAsk,
2657
3310
  agentAccountDetailsResponseSchema,
2658
3311
  agentAccountFileSchema,
@@ -2676,7 +3329,11 @@ export {
2676
3329
  applicationUpdateInputSchema,
2677
3330
  applicationUpdateResponseSchema,
2678
3331
  applicationUpdateStateSchema,
3332
+ archiveFinishedRequestSchema,
2679
3333
  archiveFinishedResponseSchema,
3334
+ archiveFinishedScopeSchema,
3335
+ archivedRunsQuerySchema,
3336
+ archivedRunsResponseSchema,
2680
3337
  artifactListSchema,
2681
3338
  artifactParamsSchema,
2682
3339
  askOptionSchema,
@@ -2694,13 +3351,16 @@ export {
2694
3351
  automationDetailResponseSchema,
2695
3352
  automationEventSchema,
2696
3353
  automationFiltersSchema,
3354
+ automationKindSchema,
2697
3355
  automationListEntrySchema,
2698
3356
  automationLogRecordSchema,
2699
3357
  automationLogResponseSchema,
2700
3358
  automationLogResultSchema,
2701
3359
  automationResponseSchema,
2702
3360
  automationRetryResponseSchema,
3361
+ automationRunResponseSchema,
2703
3362
  automationRuntimeStateSchema,
3363
+ automationScheduleSchema,
2704
3364
  automationTaskSchema,
2705
3365
  automationsResponseSchema,
2706
3366
  backendCheckSchema,
@@ -2741,6 +3401,7 @@ export {
2741
3401
  createRunInputBaseSchema,
2742
3402
  createRunInputSchema,
2743
3403
  createRunResponseSchema,
3404
+ cronOf,
2744
3405
  delegationErrorResponseSchema,
2745
3406
  delegationStateSchema,
2746
3407
  delegationWaitLabel,
@@ -2792,6 +3453,7 @@ export {
2792
3453
  groupResponseSchema,
2793
3454
  groupVariantSchema,
2794
3455
  healthResponseSchema,
3456
+ hm,
2795
3457
  humanInputDeliveredEventSchema,
2796
3458
  imageInputSchema,
2797
3459
  importableSkillSchema,
@@ -2802,7 +3464,10 @@ export {
2802
3464
  isAttachmentMediaType,
2803
3465
  isImageAttachmentName,
2804
3466
  isImageMediaType,
3467
+ isValidTimeZone,
3468
+ isoWeekday,
2805
3469
  launchKeyResponseSchema,
3470
+ localTimeZone,
2806
3471
  logEntrySchema,
2807
3472
  logEntrySourceSchema,
2808
3473
  markAllReadResponseSchema,
@@ -2810,7 +3475,11 @@ export {
2810
3475
  messageResponseSchema,
2811
3476
  modelChoicesSchema,
2812
3477
  modelDiscoveryRunnerSchema,
3478
+ nextOccurrence,
3479
+ normalizeSchedule,
3480
+ normalizeSidebarLimits,
2813
3481
  notifyRunInputSchema,
3482
+ occurrencesBetween,
2814
3483
  openAgentAccountFileInputSchema,
2815
3484
  openAgentAccountFileResponseSchema,
2816
3485
  openInCliResponseSchema,
@@ -2818,6 +3487,7 @@ export {
2818
3487
  openProjectInSchema,
2819
3488
  openTargetSchema,
2820
3489
  openTargetsResponseSchema,
3490
+ parseCron,
2821
3491
  parseEffort,
2822
3492
  parsedWorkflowSchema,
2823
3493
  patchRunInputSchema,
@@ -2825,6 +3495,19 @@ export {
2825
3495
  pickVariantResponseSchema,
2826
3496
  pinRunInputSchema,
2827
3497
  planResponseSchema,
3498
+ previewClientMessageSchema,
3499
+ previewKeyTypeSchema,
3500
+ previewMouseButtonSchema,
3501
+ previewMouseTypeSchema,
3502
+ previewResultCodeSchema,
3503
+ previewServeRequestSchema,
3504
+ previewServeResultSchema,
3505
+ previewServerMessageSchema,
3506
+ previewServerSchema,
3507
+ previewServerStateSchema,
3508
+ previewStateMessageSchema,
3509
+ previewStopRequestSchema,
3510
+ previewStopResultSchema,
2828
3511
  processUsageSchema,
2829
3512
  projectListEntrySchema,
2830
3513
  projectWebhookInputSchema,
@@ -2843,6 +3526,7 @@ export {
2843
3526
  referenceStatusSchema,
2844
3527
  referenceStatusesByProjectSchema,
2845
3528
  registerProjectResponseSchema,
3529
+ relatedRunTitleSchema,
2846
3530
  removeAgentProfileResponseSchema,
2847
3531
  removeProjectResponseSchema,
2848
3532
  removeQueuedMessageResponseSchema,
@@ -2879,21 +3563,29 @@ export {
2879
3563
  runRecordSchema,
2880
3564
  runRelationshipsSchema,
2881
3565
  runStatusSchema,
3566
+ runSummariesQuerySchema,
3567
+ runSummarySchema,
2882
3568
  runWebhookOutcomeSchema,
3569
+ runWorkflowLabel,
3570
+ runWorktreeSetupSchema,
2883
3571
  runnerDiscoversModels,
2884
3572
  runnerModelCatalogResponseSchema,
2885
3573
  runnerModelOptionSchema,
2886
3574
  runnerModelsSchema,
2887
3575
  runnerSchema,
2888
3576
  runsIndexResponseSchema,
3577
+ runsSearchQuerySchema,
3578
+ runsSearchResponseSchema,
2889
3579
  saveWorkflowInputSchema,
2890
3580
  saveWorkflowResponseSchema,
3581
+ scheduleLabel,
2891
3582
  selectAgentProfileInputSchema,
2892
3583
  setAgentConfigInputSchema,
2893
3584
  setConfigInputSchema,
2894
3585
  setConfigResponseSchema,
2895
3586
  setWorkspaceConfigInputSchema,
2896
3587
  setWorkspaceUiStateInputSchema,
3588
+ sidebarLimitsSchema,
2897
3589
  skillSchema,
2898
3590
  skillsUpdateScopeStateSchema,
2899
3591
  skillsUpdateStateSchema,
@@ -2903,6 +3595,8 @@ export {
2903
3595
  stepStateSchema,
2904
3596
  stepStatusSchema,
2905
3597
  testProjectWebhookResponseSchema,
3598
+ timeZoneOffsetMs,
3599
+ toRunSummary,
2906
3600
  todoItemSchema,
2907
3601
  uiStateSchema,
2908
3602
  updateAgentProfileInputSchema,
@@ -2913,12 +3607,15 @@ export {
2913
3607
  workerBackendSchema,
2914
3608
  workerCancelWaitRequestSchema,
2915
3609
  workerCancelWaitResultSchema,
3610
+ workerCapacitySchema,
2916
3611
  workerCollectedResultSchema,
2917
3612
  workerContextReferenceSchema,
2918
3613
  workerContextSchema,
2919
3614
  workerCreationReceiptSchema,
2920
3615
  workerDestroyResultSchema,
3616
+ workerDestroyRetrySchema,
2921
3617
  workerDestroySchema,
3618
+ workerDestroyViewSchema,
2922
3619
  workerDiffSchema,
2923
3620
  workerEmptyRequestSchema,
2924
3621
  workerInputRecipeSchema,
@@ -2952,5 +3649,8 @@ export {
2952
3649
  worktreeDirEntrySchema,
2953
3650
  worktreeEntrySchema,
2954
3651
  worktreeInfoSchema,
2955
- worktreesResponseSchema
3652
+ worktreeSetupConfigSchema,
3653
+ worktreesResponseSchema,
3654
+ zonedParts,
3655
+ zonedWallTimeToUtc
2956
3656
  };