cloving 1.3.0 → 1.5.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 (484) hide show
  1. package/README.md +329 -215
  2. package/dist/src/agent-harness-shell.d.ts +2 -1
  3. package/dist/src/agent-harness-shell.js +8 -5
  4. package/dist/src/authority/command-wait-checks.d.ts +8 -0
  5. package/dist/src/authority/command-wait-checks.js +88 -0
  6. package/dist/src/authority/command-wait-results.d.ts +15 -0
  7. package/dist/src/authority/command-wait-results.js +73 -0
  8. package/dist/src/authority/command-wait-view.d.ts +21 -0
  9. package/dist/src/authority/command-wait-view.js +34 -0
  10. package/dist/src/authority/command-waits.d.ts +39 -0
  11. package/dist/src/authority/command-waits.js +97 -0
  12. package/dist/src/authority/commands.js +22 -1
  13. package/dist/src/authority/dispatch-decision.d.ts +8 -0
  14. package/dist/src/authority/dispatch-decision.js +26 -1
  15. package/dist/src/authority/effect-requests.js +6 -3
  16. package/dist/src/authority/effect-results.js +4 -2
  17. package/dist/src/authority/history-state.d.ts +2 -0
  18. package/dist/src/authority/history-state.js +13 -1
  19. package/dist/src/authority/instants.d.ts +1 -0
  20. package/dist/src/authority/instants.js +21 -0
  21. package/dist/src/authority/reduction-state.d.ts +2 -0
  22. package/dist/src/authority/reduction-state.js +5 -0
  23. package/dist/src/authority/reduction.js +24 -0
  24. package/dist/src/authority/status-input.d.ts +2 -0
  25. package/dist/src/authority/status.d.ts +2 -0
  26. package/dist/src/authority/status.js +1 -0
  27. package/dist/src/authority/stop-sequence.d.ts +1 -0
  28. package/dist/src/authority/stop-sequence.js +2 -1
  29. package/dist/src/authority/transitions.d.ts +6 -4
  30. package/dist/src/authority/transitions.js +7 -0
  31. package/dist/src/broker/actor/authority-health.d.ts +9 -0
  32. package/dist/src/broker/actor/authority-health.js +24 -0
  33. package/dist/src/broker/actor/authority-queries.d.ts +2 -1
  34. package/dist/src/broker/actor/authority-queries.js +14 -5
  35. package/dist/src/broker/actor/authority-receipts.js +1 -1
  36. package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
  37. package/dist/src/broker/actor/authority-runtime.js +29 -20
  38. package/dist/src/broker/actor/authority-session.d.ts +6 -19
  39. package/dist/src/broker/actor/authority-session.js +66 -88
  40. package/dist/src/broker/actor/authority-settings.d.ts +2 -1
  41. package/dist/src/broker/actor/authority-settings.js +6 -3
  42. package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
  43. package/dist/src/broker/actor/authority-upgrades.js +8 -2
  44. package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
  45. package/dist/src/broker/actor/authority-watchdog.js +31 -9
  46. package/dist/src/broker/actor/authority.js +3 -1
  47. package/dist/src/broker/actor/delivery-intents.js +2 -0
  48. package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
  49. package/dist/src/broker/actor/effect-delivery.js +15 -2
  50. package/dist/src/broker/actor/effect-plan.js +11 -2
  51. package/dist/src/broker/actor/effect-queries.d.ts +4 -0
  52. package/dist/src/broker/actor/effect-queries.js +9 -1
  53. package/dist/src/broker/actor/effect-turn.js +2 -0
  54. package/dist/src/broker/actor/projection-memory.d.ts +43 -0
  55. package/dist/src/broker/actor/projection-memory.js +207 -0
  56. package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
  57. package/dist/src/broker/actor/runtime-parts.js +8 -3
  58. package/dist/src/broker/actor/stop-plan.js +9 -3
  59. package/dist/src/broker/actor/stop-turn.d.ts +2 -0
  60. package/dist/src/broker/actor/stop-turn.js +24 -11
  61. package/dist/src/broker/actor/turn-draft.d.ts +1 -0
  62. package/dist/src/broker/actor/turn-draft.js +4 -0
  63. package/dist/src/broker/actor/turn-state.js +5 -1
  64. package/dist/src/broker/authority-admission.js +60 -0
  65. package/dist/src/broker/authority-restore.d.ts +2 -0
  66. package/dist/src/broker/authority-restore.js +35 -1
  67. package/dist/src/broker/command-wait-restore.d.ts +31 -0
  68. package/dist/src/broker/command-wait-restore.js +86 -0
  69. package/dist/src/broker/decision-restore.d.ts +1 -1
  70. package/dist/src/broker/decision-restore.js +1 -0
  71. package/dist/src/broker/effect-upgrade.d.ts +3 -0
  72. package/dist/src/broker/effect-upgrade.js +11 -2
  73. package/dist/src/cli/arguments.d.ts +13 -0
  74. package/dist/src/cli/arguments.js +43 -3
  75. package/dist/src/cli/chat-stores.d.ts +2 -0
  76. package/dist/src/cli/chat-stores.js +113 -0
  77. package/dist/src/cli/client.d.ts +7 -2
  78. package/dist/src/cli/client.js +13 -7
  79. package/dist/src/cli/command-requests.d.ts +46 -0
  80. package/dist/src/cli/command-requests.js +84 -0
  81. package/dist/src/cli/command-waits.d.ts +9 -0
  82. package/dist/src/cli/command-waits.js +51 -0
  83. package/dist/src/cli/commands.js +70 -88
  84. package/dist/src/cli/config-file.d.ts +2 -2
  85. package/dist/src/cli/config-file.js +4 -2
  86. package/dist/src/cli/config-notice.js +5 -2
  87. package/dist/src/cli/doctor-retention.d.ts +2 -0
  88. package/dist/src/cli/doctor-retention.js +93 -0
  89. package/dist/src/cli/doctor-workflows.d.ts +5 -2
  90. package/dist/src/cli/doctor-workflows.js +12 -7
  91. package/dist/src/cli/doctor.js +11 -9
  92. package/dist/src/cli/harness-probes.d.ts +2 -0
  93. package/dist/src/cli/harness-probes.js +1 -1
  94. package/dist/src/cli/harness-processes.d.ts +6 -0
  95. package/dist/src/cli/harness-processes.js +36 -0
  96. package/dist/src/cli/init-command.d.ts +9 -0
  97. package/dist/src/cli/init-command.js +52 -0
  98. package/dist/src/cli/init-prompt-command.d.ts +10 -0
  99. package/dist/src/cli/init-prompt-command.js +145 -0
  100. package/dist/src/cli/init-prompt.d.ts +35 -0
  101. package/dist/src/cli/init-prompt.js +74 -0
  102. package/dist/src/cli/init-selection.d.ts +13 -0
  103. package/dist/src/cli/init-selection.js +75 -0
  104. package/dist/src/cli/main.d.ts +2 -0
  105. package/dist/src/cli/main.js +37 -7
  106. package/dist/src/cli/mcp-server.d.ts +1 -0
  107. package/dist/src/cli/mcp-server.js +156 -0
  108. package/dist/src/cli/mcp-tools.d.ts +15 -0
  109. package/dist/src/cli/mcp-tools.js +242 -0
  110. package/dist/src/cli/queue-arguments.d.ts +15 -0
  111. package/dist/src/cli/queue-arguments.js +31 -0
  112. package/dist/src/cli/queue-render.d.ts +3 -0
  113. package/dist/src/cli/queue-render.js +26 -0
  114. package/dist/src/cli/reload-render.d.ts +2 -0
  115. package/dist/src/cli/reload-render.js +12 -0
  116. package/dist/src/cli/render.d.ts +1 -1
  117. package/dist/src/cli/render.js +54 -38
  118. package/dist/src/cli/report-ci-jobs.d.ts +23 -0
  119. package/dist/src/cli/report-ci-jobs.js +103 -0
  120. package/dist/src/cli/report-ci-usage.d.ts +9 -0
  121. package/dist/src/cli/report-ci-usage.js +185 -0
  122. package/dist/src/cli/report-ci.d.ts +13 -0
  123. package/dist/src/cli/report-ci.js +74 -0
  124. package/dist/src/cli/report-closures.d.ts +6 -0
  125. package/dist/src/cli/report-closures.js +97 -0
  126. package/dist/src/cli/report-flow.d.ts +7 -0
  127. package/dist/src/cli/report-flow.js +122 -0
  128. package/dist/src/cli/report-github-reader.d.ts +29 -0
  129. package/dist/src/cli/report-github-reader.js +157 -0
  130. package/dist/src/cli/report-github.d.ts +15 -8
  131. package/dist/src/cli/report-github.js +131 -150
  132. package/dist/src/cli/report-operator.d.ts +3 -0
  133. package/dist/src/cli/report-operator.js +40 -0
  134. package/dist/src/cli/report-ready.d.ts +3 -0
  135. package/dist/src/cli/report-ready.js +96 -0
  136. package/dist/src/cli/report-text.d.ts +9 -0
  137. package/dist/src/cli/report-text.js +33 -0
  138. package/dist/src/cli/report.d.ts +1 -0
  139. package/dist/src/cli/report.js +104 -27
  140. package/dist/src/cli/runtime-arguments.d.ts +18 -3
  141. package/dist/src/cli/runtime-arguments.js +29 -20
  142. package/dist/src/cli/schedule-arguments.d.ts +14 -0
  143. package/dist/src/cli/schedule-arguments.js +26 -0
  144. package/dist/src/cli/schedule-render.d.ts +22 -0
  145. package/dist/src/cli/schedule-render.js +73 -0
  146. package/dist/src/cli/terminal-text.d.ts +3 -0
  147. package/dist/src/cli/terminal-text.js +28 -0
  148. package/dist/src/cli/toolchain.d.ts +1 -0
  149. package/dist/src/cli/toolchain.js +1 -0
  150. package/dist/src/cli/usage-render.d.ts +1 -0
  151. package/dist/src/cli/usage-render.js +28 -1
  152. package/dist/src/cli/usage.d.ts +2 -2
  153. package/dist/src/cli/usage.js +89 -11
  154. package/dist/src/cli/watch-actions.js +2 -2
  155. package/dist/src/cli/watch-api-document.d.ts +430 -0
  156. package/dist/src/cli/watch-api-document.js +291 -0
  157. package/dist/src/cli/watch-api-run.d.ts +56 -0
  158. package/dist/src/cli/watch-api-run.js +112 -0
  159. package/dist/src/cli/watch-api.d.ts +17 -0
  160. package/dist/src/cli/watch-api.js +230 -0
  161. package/dist/src/cli/watch-board-view.js +19 -2
  162. package/dist/src/cli/watch-board.d.ts +4 -2
  163. package/dist/src/cli/watch-board.js +53 -43
  164. package/dist/src/cli/watch-card-forms.d.ts +1 -1
  165. package/dist/src/cli/watch-card-forms.js +11 -10
  166. package/dist/src/cli/watch-client.d.ts +1 -1
  167. package/dist/src/cli/watch-client.js +2 -11
  168. package/dist/src/cli/watch-header-view.d.ts +1 -5
  169. package/dist/src/cli/watch-header-view.js +17 -21
  170. package/dist/src/cli/watch-model.d.ts +5 -1
  171. package/dist/src/cli/watch-model.js +20 -11
  172. package/dist/src/cli/watch-page.js +15 -15
  173. package/dist/src/cli/watch-phases.d.ts +12 -3
  174. package/dist/src/cli/watch-phases.js +68 -11
  175. package/dist/src/cli/watch-pr-board.js +1 -1
  176. package/dist/src/cli/watch-pr-command.d.ts +1 -0
  177. package/dist/src/cli/watch-pull-request.js +18 -8
  178. package/dist/src/cli/watch-reads.d.ts +3 -0
  179. package/dist/src/cli/watch-reads.js +22 -20
  180. package/dist/src/cli/watch-render.d.ts +15 -0
  181. package/dist/src/cli/watch-run-input.d.ts +0 -1
  182. package/dist/src/cli/watch-run-input.js +0 -13
  183. package/dist/src/cli/watch-server.js +24 -10
  184. package/dist/src/cli/watch-view.d.ts +0 -3
  185. package/dist/src/cli/watch-view.js +13 -13
  186. package/dist/src/cli.js +73 -12
  187. package/dist/src/command-wait.d.ts +4 -0
  188. package/dist/src/command-wait.js +45 -0
  189. package/dist/src/configuration-change.d.ts +7 -0
  190. package/dist/src/configuration-change.js +14 -0
  191. package/dist/src/configuration-display.js +2 -0
  192. package/dist/src/configuration-schema.d.ts +14 -0
  193. package/dist/src/configuration-schema.js +6 -2
  194. package/dist/src/daemon/attachment-file.d.ts +6 -0
  195. package/dist/src/daemon/attachment-file.js +86 -0
  196. package/dist/src/daemon/attachments.d.ts +14 -0
  197. package/dist/src/daemon/attachments.js +17 -0
  198. package/dist/src/daemon/claude-recovery.d.ts +50 -0
  199. package/dist/src/daemon/claude-recovery.js +208 -0
  200. package/dist/src/daemon/claude-stream.d.ts +27 -0
  201. package/dist/src/daemon/claude-stream.js +63 -0
  202. package/dist/src/daemon/claude-turn.d.ts +11 -25
  203. package/dist/src/daemon/claude-turn.js +64 -81
  204. package/dist/src/daemon/claude-worker.d.ts +5 -4
  205. package/dist/src/daemon/claude-worker.js +127 -126
  206. package/dist/src/daemon/daemon-adapters.d.ts +9 -0
  207. package/dist/src/daemon/daemon-adapters.js +33 -5
  208. package/dist/src/daemon/daemon-loops.d.ts +5 -1
  209. package/dist/src/daemon/daemon-loops.js +18 -10
  210. package/dist/src/daemon/daemon.js +80 -61
  211. package/dist/src/daemon/github-attach.d.ts +2 -0
  212. package/dist/src/daemon/github-attach.js +222 -0
  213. package/dist/src/daemon/github-calls.js +1 -1
  214. package/dist/src/daemon/github-ci-filters.d.ts +6 -0
  215. package/dist/src/daemon/github-ci-filters.js +138 -0
  216. package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
  217. package/dist/src/daemon/github-ci-workflows.js +148 -0
  218. package/dist/src/daemon/github-ci.js +22 -4
  219. package/dist/src/daemon/github-issue-methods.d.ts +2 -0
  220. package/dist/src/daemon/github-issue-methods.js +37 -2
  221. package/dist/src/daemon/github-merge-call.d.ts +2 -1
  222. package/dist/src/daemon/github-merge-call.js +10 -3
  223. package/dist/src/daemon/github-merge.js +52 -24
  224. package/dist/src/daemon/github-methods.js +18 -4
  225. package/dist/src/daemon/github-operation.d.ts +4 -0
  226. package/dist/src/daemon/github-operation.js +6 -0
  227. package/dist/src/daemon/github-worker.d.ts +4 -0
  228. package/dist/src/daemon/github-worker.js +6 -0
  229. package/dist/src/daemon/issue-queue.d.ts +4 -1
  230. package/dist/src/daemon/issue-queue.js +76 -78
  231. package/dist/src/daemon/merge-turns.d.ts +10 -0
  232. package/dist/src/daemon/merge-turns.js +37 -0
  233. package/dist/src/daemon/notify-events.d.ts +6 -0
  234. package/dist/src/daemon/notify-events.js +84 -0
  235. package/dist/src/daemon/notify-journal.js +1 -1
  236. package/dist/src/daemon/notify-message.d.ts +4 -1
  237. package/dist/src/daemon/notify-message.js +36 -0
  238. package/dist/src/daemon/notify.d.ts +1 -1
  239. package/dist/src/daemon/notify.js +5 -77
  240. package/dist/src/daemon/operation-journal.d.ts +1 -0
  241. package/dist/src/daemon/queue-control.d.ts +13 -0
  242. package/dist/src/daemon/queue-control.js +86 -0
  243. package/dist/src/daemon/queue-journal.d.ts +20 -0
  244. package/dist/src/daemon/queue-journal.js +89 -0
  245. package/dist/src/daemon/queue-status.d.ts +9 -3
  246. package/dist/src/daemon/queue-status.js +17 -4
  247. package/dist/src/daemon/record-archive.d.ts +19 -0
  248. package/dist/src/daemon/record-archive.js +82 -0
  249. package/dist/src/daemon/record-sweep.d.ts +24 -0
  250. package/dist/src/daemon/record-sweep.js +147 -0
  251. package/dist/src/daemon/resume-index-lock.d.ts +13 -0
  252. package/dist/src/daemon/resume-index-lock.js +160 -0
  253. package/dist/src/daemon/resume-worktree.d.ts +7 -0
  254. package/dist/src/daemon/resume-worktree.js +29 -0
  255. package/dist/src/daemon/retrying-turn.d.ts +2 -12
  256. package/dist/src/daemon/retrying-turn.js +98 -172
  257. package/dist/src/daemon/schedule-control.d.ts +26 -0
  258. package/dist/src/daemon/schedule-control.js +110 -0
  259. package/dist/src/daemon/schedule-journal.d.ts +2 -15
  260. package/dist/src/daemon/schedule-journal.js +67 -4
  261. package/dist/src/daemon/settings-reload.d.ts +26 -0
  262. package/dist/src/daemon/settings-reload.js +82 -0
  263. package/dist/src/daemon/ticket-registration.d.ts +2 -7
  264. package/dist/src/daemon/ticket-registration.js +15 -81
  265. package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
  266. package/dist/src/daemon/turn-attempt-journal.js +136 -0
  267. package/dist/src/daemon/turn-attempts.d.ts +47 -0
  268. package/dist/src/daemon/turn-attempts.js +166 -0
  269. package/dist/src/daemon/turn-details.d.ts +4 -0
  270. package/dist/src/daemon/turn-details.js +33 -0
  271. package/dist/src/daemon/turn-report.d.ts +8 -1
  272. package/dist/src/daemon/turn-report.js +39 -0
  273. package/dist/src/daemon/work-tree.d.ts +9 -0
  274. package/dist/src/daemon/work-tree.js +20 -0
  275. package/dist/src/daemon/worker-profile.d.ts +9 -0
  276. package/dist/src/daemon/worker-profile.js +44 -0
  277. package/dist/src/daemon/workflow-generations.d.ts +7 -4
  278. package/dist/src/daemon/workflow-generations.js +22 -14
  279. package/dist/src/daemon/workflow-reload.d.ts +41 -0
  280. package/dist/src/daemon/workflow-reload.js +244 -0
  281. package/dist/src/daemon/workflow-replay.d.ts +2 -1
  282. package/dist/src/daemon/workflow-replay.js +7 -3
  283. package/dist/src/daemon/workflow-schedules.d.ts +3 -0
  284. package/dist/src/daemon/workflow-schedules.js +98 -45
  285. package/dist/src/daemon/worktree-processes.d.ts +9 -0
  286. package/dist/src/daemon/worktree-processes.js +151 -0
  287. package/dist/src/doctor-report.d.ts +4 -6
  288. package/dist/src/doctor-report.js +8 -13
  289. package/dist/src/harness-start.d.ts +15 -0
  290. package/dist/src/harness-start.js +37 -0
  291. package/dist/src/host/command-wait.d.ts +38 -0
  292. package/dist/src/host/command-wait.js +115 -0
  293. package/dist/src/host/start-delivery.d.ts +5 -7
  294. package/dist/src/host/start-delivery.js +3 -15
  295. package/dist/src/host/step-bridge-host.d.ts +2 -0
  296. package/dist/src/host/step-bridge-host.js +21 -0
  297. package/dist/src/operation-identity.d.ts +1 -0
  298. package/dist/src/operation-identity.js +4 -0
  299. package/dist/src/private-config.schema.json +71 -0
  300. package/dist/src/project-config.schema.json +40 -0
  301. package/dist/src/project-settings.d.ts +16 -2
  302. package/dist/src/project-settings.js +35 -1
  303. package/dist/src/queue-spend.d.ts +4 -0
  304. package/dist/src/queue-spend.js +21 -0
  305. package/dist/src/queue-state.d.ts +26 -0
  306. package/dist/src/queue-state.js +34 -0
  307. package/dist/src/record-retention.d.ts +46 -0
  308. package/dist/src/record-retention.js +81 -0
  309. package/dist/src/relay/relay-service.d.ts +3 -0
  310. package/dist/src/relay/relay-service.js +5 -3
  311. package/dist/src/report-ci.d.ts +164 -0
  312. package/dist/src/report-ci.js +32 -0
  313. package/dist/src/report-effects.d.ts +15 -0
  314. package/dist/src/report-effects.js +212 -0
  315. package/dist/src/report-flow-types.d.ts +38 -0
  316. package/dist/src/report-flow-types.js +7 -0
  317. package/dist/src/report-flow.d.ts +43 -0
  318. package/dist/src/report-flow.js +193 -0
  319. package/dist/src/report-operator.d.ts +67 -0
  320. package/dist/src/report-operator.js +25 -0
  321. package/dist/src/report-quality.d.ts +221 -0
  322. package/dist/src/report-quality.js +94 -0
  323. package/dist/src/report-ready.d.ts +23 -0
  324. package/dist/src/report-ready.js +117 -0
  325. package/dist/src/report-statistics.d.ts +2 -1
  326. package/dist/src/report-statistics.js +40 -4
  327. package/dist/src/report.d.ts +588 -47
  328. package/dist/src/report.js +156 -41
  329. package/dist/src/schedule-progress.d.ts +33 -0
  330. package/dist/src/schedule-progress.js +45 -0
  331. package/dist/src/service/active-tickets.js +11 -6
  332. package/dist/src/service/command-waits.d.ts +34 -0
  333. package/dist/src/service/command-waits.js +86 -0
  334. package/dist/src/service/dispatcher.d.ts +4 -0
  335. package/dist/src/service/dispatcher.js +33 -0
  336. package/dist/src/service/expiry.js +2 -0
  337. package/dist/src/service/gateway.js +3 -1
  338. package/dist/src/service/queue-handlers.d.ts +4 -0
  339. package/dist/src/service/queue-handlers.js +32 -0
  340. package/dist/src/service/queue-spend.d.ts +6 -0
  341. package/dist/src/service/queue-spend.js +68 -0
  342. package/dist/src/service/registry.d.ts +28 -2
  343. package/dist/src/service/registry.js +48 -0
  344. package/dist/src/service/replies.d.ts +22 -8
  345. package/dist/src/service/replies.js +16 -2
  346. package/dist/src/service/run-handlers.js +37 -12
  347. package/dist/src/service/run-metadata.d.ts +15 -1
  348. package/dist/src/service/run-metadata.js +93 -8
  349. package/dist/src/service/service.d.ts +11 -3
  350. package/dist/src/service/service.js +22 -37
  351. package/dist/src/service/submission-handler.js +18 -4
  352. package/dist/src/service/worker-port.js +9 -1
  353. package/dist/src/service/worker-totals.d.ts +6 -0
  354. package/dist/src/service/worker-totals.js +8 -1
  355. package/dist/src/service/workflow-reload.d.ts +35 -0
  356. package/dist/src/service/workflow-reload.js +52 -0
  357. package/dist/src/step-bridge.d.ts +20 -0
  358. package/dist/src/steps/command-wait.d.ts +12 -0
  359. package/dist/src/steps/command-wait.js +26 -0
  360. package/dist/src/steps/open-decision-wait.d.ts +2 -0
  361. package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
  362. package/dist/src/steps/review-by-person.js +4 -1
  363. package/dist/src/steps/wait-for-command.d.ts +3 -0
  364. package/dist/src/steps/wait-for-command.js +17 -0
  365. package/dist/src/steps/wait-for-decision.js +1 -1
  366. package/dist/src/storage/command-wait-rows.d.ts +30 -0
  367. package/dist/src/storage/command-wait-rows.js +96 -0
  368. package/dist/src/storage/decision-snapshots.d.ts +8 -2
  369. package/dist/src/storage/decision-snapshots.js +16 -8
  370. package/dist/src/storage/domain-changes.d.ts +3 -1
  371. package/dist/src/storage/domain-changes.js +4 -0
  372. package/dist/src/storage/domain-schema.d.ts +16 -1
  373. package/dist/src/storage/domain-schema.js +35 -4
  374. package/dist/src/storage/effect-schema.d.ts +2 -0
  375. package/dist/src/storage/effect-schema.js +9 -0
  376. package/dist/src/storage/projection-changes.d.ts +12 -0
  377. package/dist/src/storage/projection-changes.js +194 -0
  378. package/dist/src/storage/projection-lookups.d.ts +7 -0
  379. package/dist/src/storage/projection-lookups.js +30 -0
  380. package/dist/src/testing-requests.d.ts +15 -0
  381. package/dist/src/testing-requests.js +93 -0
  382. package/dist/src/testing.d.ts +4 -10
  383. package/dist/src/testing.js +33 -86
  384. package/dist/src/worker-usage.d.ts +1 -0
  385. package/dist/src/worker-usage.js +3 -0
  386. package/dist/src/workflow-candidate.d.ts +1 -0
  387. package/dist/src/workflow-candidate.js +12 -1
  388. package/dist/src/workflow-contracts.d.ts +1 -0
  389. package/dist/src/workflow-contracts.js +9 -2
  390. package/dist/src/workflow-declaration.d.ts +1 -0
  391. package/dist/src/workflow-declaration.js +3 -0
  392. package/dist/src/workflow-discovery.d.ts +2 -13
  393. package/dist/src/workflow-discovery.js +1 -13
  394. package/dist/src/workflow-refusals.js +0 -1
  395. package/dist/src/workflows.d.ts +1 -1
  396. package/dist/src/workflows.js +1 -1
  397. package/dist/tools/compile-workflows.js +3 -0
  398. package/dist/tools/project-configuration.d.ts +7 -2
  399. package/dist/tools/project-configuration.js +30 -1
  400. package/dist/tools/red-green-command.d.ts +1 -0
  401. package/dist/tools/red-green-command.js +174 -0
  402. package/dist/tools/red-green-process.d.ts +10 -0
  403. package/dist/tools/red-green-process.js +59 -0
  404. package/dist/tools/self-host-processes.d.ts +2 -0
  405. package/dist/tools/self-host-processes.js +69 -26
  406. package/dist/tools/self-host-project.d.ts +2 -0
  407. package/dist/tools/self-host-project.js +30 -77
  408. package/dist/tools/self-host-runtime.js +1 -1
  409. package/dist/tools/self-host.js +76 -34
  410. package/dist/tools/template-command.d.ts +1 -0
  411. package/dist/tools/template-command.js +160 -0
  412. package/dist/tools/template-copy.d.ts +11 -0
  413. package/dist/tools/template-copy.js +130 -0
  414. package/dist/tools/template-files.d.ts +17 -0
  415. package/dist/tools/template-files.js +74 -0
  416. package/dist/tools/workflow-bundles.js +1 -0
  417. package/dist/tools/workflow-candidate-counts.js +2 -2
  418. package/dist/tools/workflow-candidate-program.d.ts +4 -2
  419. package/dist/tools/workflow-candidate-program.js +30 -11
  420. package/dist/tools/workflow-candidate-shape.d.ts +3 -0
  421. package/dist/tools/workflow-candidate-shape.js +90 -0
  422. package/dist/tools/workflow-candidate-source.d.ts +1 -0
  423. package/dist/tools/workflow-candidate-source.js +26 -4
  424. package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
  425. package/dist/tools/workflow-candidate-syntax.js +24 -94
  426. package/dist/tools/workflow-command.js +1 -2
  427. package/dist/tools/workflow-folders.d.ts +2 -3
  428. package/dist/tools/workflow-folders.js +1 -1
  429. package/package.json +17 -9
  430. package/templates/develop/README.md +93 -4
  431. package/templates/develop/develop/flow-tests.ts +38 -1
  432. package/templates/develop/develop/interruption-tests.ts +157 -0
  433. package/templates/develop/develop/local.ts +1 -0
  434. package/templates/develop/develop/option-tests.ts +138 -9
  435. package/templates/develop/develop/pull.ts +5 -1
  436. package/templates/develop/develop/red-green.ts +55 -0
  437. package/templates/develop/develop/refusal-tests.ts +77 -0
  438. package/templates/develop/develop/report.ts +31 -11
  439. package/templates/develop/develop/round.ts +1 -0
  440. package/templates/develop/develop/scenarios.ts +27 -0
  441. package/templates/develop/develop/turn.ts +28 -7
  442. package/templates/develop/develop.declaration.json +1 -1
  443. package/templates/develop/develop.test.ts +4 -0
  444. package/templates/develop/template.json +29 -2
  445. package/templates/idea-to-issue/README.md +27 -0
  446. package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
  447. package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
  448. package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
  449. package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
  450. package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
  451. package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
  452. package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
  453. package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
  454. package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
  455. package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
  456. package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
  457. package/templates/idea-to-issue/idea-to-issue.ts +49 -0
  458. package/templates/idea-to-issue/template.json +81 -0
  459. package/templates/review-day/README.md +97 -0
  460. package/templates/review-day/review-day/critique.ts +58 -0
  461. package/templates/review-day/review-day/decision.ts +29 -0
  462. package/templates/review-day/review-day/facts.ts +69 -0
  463. package/templates/review-day/review-day/label.ts +29 -0
  464. package/templates/review-day/review-day/next.ts +28 -0
  465. package/templates/review-day/review-day/post.ts +27 -0
  466. package/templates/review-day/review-day/report.ts +98 -0
  467. package/templates/review-day/review-day/rules.ts +12 -0
  468. package/templates/review-day/review-day/scenarios.ts +76 -0
  469. package/templates/review-day/review-day/turn.ts +73 -0
  470. package/templates/review-day/review-day.declaration.json +16 -0
  471. package/templates/review-day/review-day.test.ts +362 -0
  472. package/templates/review-day/review-day.ts +37 -0
  473. package/templates/review-day/template.json +56 -0
  474. package/dist/src/cli/watch-start-view.d.ts +0 -18
  475. package/dist/src/cli/watch-start-view.js +0 -77
  476. package/dist/src/steps/decision-gate.d.ts +0 -3
  477. package/dist/workflows/develop-prd.d.ts +0 -7
  478. package/dist/workflows/develop-prd.js +0 -165
  479. package/dist/workflows/develop-ticket.d.ts +0 -9
  480. package/dist/workflows/develop-ticket.js +0 -207
  481. package/dist/workflows/issue-labels.d.ts +0 -16
  482. package/dist/workflows/issue-labels.js +0 -70
  483. package/dist/workflows/ticket-prompts.d.ts +0 -35
  484. package/dist/workflows/ticket-prompts.js +0 -147
@@ -0,0 +1,68 @@
1
+ import { queueSpending } from "../queue-spend.js";
2
+ import { priceOf } from "../worker-usage.js";
3
+ import { reportFields } from "./worker-totals.js";
4
+ export async function queueRun(context, runId) {
5
+ const { queries } = context.authority;
6
+ if ((await queries.manifest(runId))?.queue === true)
7
+ return true;
8
+ if ((await queries.workflowIds([runId]))[runId] !== "develop-issue")
9
+ return false;
10
+ const { events } = await queries.eventsAfter({ runId, after: 0, limit: 1 });
11
+ return (events[0]?.type === "run.created" &&
12
+ events[0].payload["resolver"] === "issue-command:1");
13
+ }
14
+ export async function queueSpend(context) {
15
+ const limitUsd = context.queueDailySpendLimitUsd;
16
+ if (limitUsd === undefined)
17
+ return {};
18
+ const now = Date.parse(context.clock());
19
+ const operations = await context.authority.effects.workerTurns({
20
+ after: new Date(now - 24 * 3_600_000).toISOString(),
21
+ through: new Date(now).toISOString(),
22
+ });
23
+ const runIds = [...new Set(operations.map((operation) => operation.runId))];
24
+ const costs = [];
25
+ const totals = {
26
+ costs,
27
+ unknownTurns: 0,
28
+ turnsInWork: 0,
29
+ };
30
+ const queued = new Set();
31
+ for (const runId of runIds) {
32
+ if (await queueRun(context, runId))
33
+ queued.add(runId);
34
+ }
35
+ for (const operation of operations) {
36
+ if (queued.has(operation.runId))
37
+ await countTurn(context, { operation, totals });
38
+ }
39
+ const spending = queueSpending(totals.costs, limitUsd);
40
+ const spentUsd = totals.costs.length === 0 && totals.unknownTurns > 0
41
+ ? null
42
+ : spending.spentUsd;
43
+ return {
44
+ spend: {
45
+ limitUsd,
46
+ spentUsd,
47
+ unknownTurns: totals.unknownTurns,
48
+ turnsInWork: totals.turnsInWork,
49
+ windowHours: 24,
50
+ holding: spentUsd !== null && spending.holding,
51
+ },
52
+ };
53
+ }
54
+ async function countTurn(context, turn) {
55
+ const { operation, totals } = turn;
56
+ if (operation.settledSequence === null) {
57
+ totals.turnsInWork += 1;
58
+ return;
59
+ }
60
+ const report = reportFields(operation.result === null
61
+ ? undefined
62
+ : await context.authority.queries.document(operation.result));
63
+ const cost = priceOf(report["costUsd"]) ?? priceOf(report["estimatedCostUsd"]);
64
+ if (cost === null)
65
+ totals.unknownTurns += 1;
66
+ else
67
+ totals.costs.push(cost);
68
+ }
@@ -2,6 +2,7 @@ import type { CommandWaits, WorkflowStage, WorkflowStages } from "../workflow-de
2
2
  import type { SubmissionContract } from "../submission.ts";
3
3
  import type { ExecutionManifest } from "../workflow-admission.ts";
4
4
  import type { AvailableManifest } from "../broker/actor/delivery-intents.ts";
5
+ import { type WorkflowRefusal } from "../workflow-refusals.ts";
5
6
  export interface WorkflowBundleStore {
6
7
  readonly directory: string;
7
8
  readonly repository: string;
@@ -52,8 +53,33 @@ export interface Registry {
52
53
  readonly bundle: (pinned: ExecutionManifest) => Promise<string | undefined>;
53
54
  readonly available: AvailableManifest;
54
55
  }
55
- export declare function workflowRegistry(workflows: readonly WorkflowRegistration[], options?: {
56
+ export interface RegistryOptions {
56
57
  readonly retainedWorkflows?: readonly WorkflowRegistration[];
57
58
  readonly workflowBundles?: WorkflowBundleStore;
58
59
  readonly retainedWorkflow?: AvailableManifest;
59
- }): Registry;
60
+ }
61
+ export interface ReplaceableRegistry extends Registry {
62
+ readonly replace: (workflows: readonly WorkflowRegistration[]) => void;
63
+ }
64
+ export declare function replaceableRegistry(workflows: readonly WorkflowRegistration[], options?: RegistryOptions): ReplaceableRegistry;
65
+ export declare function workflowRegistry(workflows: readonly WorkflowRegistration[], options?: RegistryOptions): Registry;
66
+ interface WorkflowInventory {
67
+ readonly bundleDigest?: string;
68
+ readonly workflowRefusals: readonly WorkflowRefusal[];
69
+ }
70
+ export interface WorkflowCatalog {
71
+ readonly registry: Registry;
72
+ readonly inventory: () => WorkflowInventory;
73
+ readonly replace: (next: {
74
+ readonly bundleDigest: string;
75
+ readonly workflows: readonly WorkflowRegistration[];
76
+ readonly workflowRefusals: readonly WorkflowRefusal[];
77
+ }) => void;
78
+ readonly replaceRefusals: (refusals: readonly WorkflowRefusal[]) => void;
79
+ }
80
+ export declare function workflowCatalog(options: RegistryOptions & {
81
+ readonly workflows: readonly WorkflowRegistration[];
82
+ readonly bundleDigest?: string;
83
+ readonly workflowRefusals?: readonly WorkflowRefusal[];
84
+ }): WorkflowCatalog;
85
+ export {};
@@ -1,6 +1,7 @@
1
1
  import { workflowPin } from "../broker/workflow-pin.js";
2
2
  import { declaredManifest } from "../execution-pin.js";
3
3
  import { readRetainedWorkflowBundle } from "../../tools/workflow-bundles.js";
4
+ import { workflowRefusals, } from "../workflow-refusals.js";
4
5
  function registered(workflow) {
5
6
  const manifest = declaredManifest(workflow.manifest, workflow);
6
7
  return {
@@ -19,6 +20,30 @@ function availableVersions(workflow) {
19
20
  delete manifest.bundleDigest;
20
21
  return [workflow, { ...workflow, manifest, pin: workflowPin(manifest) }];
21
22
  }
23
+ export function replaceableRegistry(workflows, options = {}) {
24
+ let earlier = [...workflows, ...(options.retainedWorkflows ?? [])];
25
+ let current = workflowRegistry(workflows, options);
26
+ return {
27
+ get workflowIds() {
28
+ return current.workflowIds;
29
+ },
30
+ get workflowStages() {
31
+ return current.workflowStages;
32
+ },
33
+ byId: (workflowId) => current.byId(workflowId),
34
+ byPin: (pin) => current.byPin(pin),
35
+ bundle: (pinned) => current.bundle(pinned),
36
+ available: (pinned) => current.available(pinned),
37
+ replace: (next) => {
38
+ const replacement = workflowRegistry(next, {
39
+ ...options,
40
+ retainedWorkflows: earlier,
41
+ });
42
+ earlier = [...next, ...earlier];
43
+ current = replacement;
44
+ },
45
+ };
46
+ }
22
47
  export function workflowRegistry(workflows, options = {}) {
23
48
  const current = workflows.map(registered);
24
49
  const available = [
@@ -54,3 +79,26 @@ export function workflowRegistry(workflows, options = {}) {
54
79
  },
55
80
  };
56
81
  }
82
+ export function workflowCatalog(options) {
83
+ const registry = replaceableRegistry(options.workflows, options);
84
+ let inventory = {
85
+ ...(options.bundleDigest === undefined
86
+ ? {}
87
+ : { bundleDigest: options.bundleDigest }),
88
+ workflowRefusals: workflowRefusals(options.workflowRefusals),
89
+ };
90
+ return {
91
+ registry,
92
+ inventory: () => inventory,
93
+ replace: (next) => {
94
+ registry.replace(next.workflows);
95
+ inventory = {
96
+ bundleDigest: next.bundleDigest,
97
+ workflowRefusals: next.workflowRefusals,
98
+ };
99
+ },
100
+ replaceRefusals: (refusals) => {
101
+ inventory = { ...inventory, workflowRefusals: refusals };
102
+ },
103
+ };
104
+ }
@@ -1,16 +1,26 @@
1
+ import type { SchedulePort } from "../schedule-progress.ts";
2
+ import type { QueuePort } from "../queue-state.ts";
1
3
  import type { Authority, CommandRecord, StoreReceipt } from "../broker/actor/authority.ts";
2
4
  import type { Fields, Reply } from "../protocol.ts";
3
5
  import type { ChangeSignal } from "./changes.ts";
4
6
  import type { Gateway } from "./gateway.ts";
5
- import type { Registry } from "./registry.ts";
6
- import { type WorkflowRefusal } from "../workflow-refusals.ts";
7
+ import type { Registry, WorkflowCatalog } from "./registry.ts";
7
8
  import type { CommandEffects } from "../command-settings.ts";
8
- export interface ServiceContext {
9
+ import type { RunTurns, TurnDetails } from "../record-retention.ts";
10
+ export interface ServiceReads {
9
11
  readonly workerHarness?: (operationId: string) => Promise<string | undefined>;
12
+ readonly turnDetails?: (turns: RunTurns) => Promise<TurnDetails | undefined>;
13
+ }
14
+ export interface ServiceContext extends ServiceReads {
15
+ readonly version?: string;
16
+ readonly schedule?: SchedulePort;
17
+ readonly queue?: QueuePort;
18
+ readonly queueDailySpendLimitUsd?: number;
10
19
  readonly commandEffects?: CommandEffects;
11
20
  readonly authority: Authority;
12
21
  readonly registry: Registry;
13
- readonly workflowRefusals?: readonly WorkflowRefusal[];
22
+ readonly workflowCatalog?: WorkflowCatalog;
23
+ readonly reload?: () => Promise<Reply>;
14
24
  readonly gateway: Gateway;
15
25
  readonly clock: () => string;
16
26
  readonly livenessMilliseconds: number;
@@ -21,11 +31,13 @@ export interface ServiceContext {
21
31
  readonly worldReports?: () => readonly unknown[];
22
32
  readonly changed?: ChangeSignal["next"];
23
33
  }
24
- export declare function queryMetadata(options: {
25
- readonly workerHarness?: ServiceContext["workerHarness"];
34
+ export declare function queryMetadata(options: ServiceReads & {
35
+ readonly version?: string;
36
+ readonly schedule?: SchedulePort;
37
+ readonly queue?: QueuePort;
38
+ readonly queueDailySpendLimitUsd?: number;
26
39
  readonly commandEffects?: CommandEffects;
27
- readonly workflowRefusals?: readonly WorkflowRefusal[];
28
- }): Pick<ServiceContext, "workerHarness" | "commandEffects" | "workflowRefusals">;
40
+ }): Pick<ServiceContext, "schedule" | "queue" | "workerHarness" | "turnDetails" | "commandEffects" | "queueDailySpendLimitUsd" | "version">;
29
41
  export declare function result(kind: string, fields: Fields): Reply;
30
42
  export declare function failed(code: string, extra: Fields): Reply;
31
43
  export declare function invalidRequest(detail: string): Reply;
@@ -34,3 +46,5 @@ export declare function committed(receipt: StoreReceipt): boolean;
34
46
  export declare function isIdentifier(value: unknown): value is string;
35
47
  export declare function wholeNumber(value: unknown, minimum: number): value is number;
36
48
  export declare function publicReceipt(record: CommandRecord): Fields;
49
+ export declare function scheduleRequest(context: ServiceContext, parameters: Fields): Promise<Reply>;
50
+ export declare function errorMessage(error: unknown): string;
@@ -1,14 +1,21 @@
1
1
  import { isRecordKey } from "../authority/commands.js";
2
- import { workflowRefusals, } from "../workflow-refusals.js";
3
2
  export function queryMetadata(options) {
4
3
  return {
4
+ ...(options.version === undefined ? {} : { version: options.version }),
5
+ ...(options.schedule === undefined ? {} : { schedule: options.schedule }),
6
+ ...(options.queue === undefined ? {} : { queue: options.queue }),
7
+ ...(options.queueDailySpendLimitUsd === undefined
8
+ ? {}
9
+ : { queueDailySpendLimitUsd: options.queueDailySpendLimitUsd }),
5
10
  ...(options.workerHarness === undefined
6
11
  ? {}
7
12
  : { workerHarness: options.workerHarness }),
13
+ ...(options.turnDetails === undefined
14
+ ? {}
15
+ : { turnDetails: options.turnDetails }),
8
16
  ...(options.commandEffects === undefined
9
17
  ? {}
10
18
  : { commandEffects: options.commandEffects }),
11
- workflowRefusals: workflowRefusals(options.workflowRefusals),
12
19
  };
13
20
  }
14
21
  const codes = {
@@ -66,3 +73,10 @@ export function publicReceipt(record) {
66
73
  commandDigest: record.commandDigest,
67
74
  };
68
75
  }
76
+ export function scheduleRequest(context, parameters) {
77
+ return (context.schedule?.(parameters) ??
78
+ Promise.resolve(failed("schedules-unavailable", {})));
79
+ }
80
+ export function errorMessage(error) {
81
+ return String(Reflect.get(Object(error), "message"));
82
+ }
@@ -1,18 +1,22 @@
1
- import { metadataOf, outcomeOf } from "./run-metadata.js";
1
+ import { commandWaitDisplay } from "./command-waits.js";
2
+ import { scheduleMetadata, scheduledMetadata, metadataOf, outcomeOf, ticketMetadataPage, workflowMetadata, } from "./run-metadata.js";
2
3
  import { linksOf } from "../authority/handoff-chain.js";
4
+ import { terminal } from "../authority/transitions.js";
3
5
  import { runView, unresolvedEffects, } from "../authority/status.js";
4
6
  import { record } from "../protocol.js";
5
7
  import { committed, failed, invalidRequest, isIdentifier, publicReceipt, rejection, result, wholeNumber, } from "./replies.js";
6
- import { usageTotals } from "./worker-totals.js";
8
+ import { turnDetailsOf, usageTotals } from "./worker-totals.js";
7
9
  import { commandFields } from "./command-effects.js";
8
10
  import { decidedOf, feedbackOf } from "./decision-handler.js";
9
11
  import { queueOverview } from "./active-tickets.js";
10
12
  import { queueRunStatuses } from "./queue-runs.js";
13
+ import { workflowFields } from "./workflow-reload.js";
11
14
  async function snapshot(context) {
12
15
  const { authority } = context;
13
16
  const state = await authority.state();
14
17
  const sequences = await authority.queries.sequences();
15
18
  return {
19
+ now: context.clock(),
16
20
  links: await authority.queries.runLinks(),
17
21
  state,
18
22
  operations: await authority.operations(),
@@ -64,9 +68,16 @@ async function viewOf(context, scope) {
64
68
  if (run === undefined)
65
69
  return undefined;
66
70
  const details = state.details[run.runId];
71
+ const workflowId = scope.snapshot.workflowIds[run.runId] ?? run.workflow;
67
72
  const effects = await effectInput(context, run.runId);
68
73
  const input = {
69
74
  ...effects,
75
+ commandWaits: await commandWaitDisplay({
76
+ authority: context.authority,
77
+ runId: run.runId,
78
+ waits: state.commandWaits,
79
+ now: scope.snapshot.now,
80
+ }),
70
81
  closure: run.status === "cancelled"
71
82
  ? await context.authority.effects.closure(run.runId)
72
83
  : null,
@@ -84,10 +95,14 @@ async function viewOf(context, scope) {
84
95
  };
85
96
  return {
86
97
  ...runView(input),
98
+ ...(await scheduledMetadata(context, {
99
+ runId: run.runId,
100
+ workflowId,
101
+ })),
87
102
  commandOperations: effects.commandOperations,
88
103
  ...linksOf({ runId: run.runId, ...scope.snapshot.links[run.runId] }),
89
104
  input: await submittedInput(context, details?.submission),
90
- workflowId: scope.snapshot.workflowIds[run.runId] ?? run.workflow,
105
+ workflowId,
91
106
  latestAt: times[run.runId] ?? null,
92
107
  unresolvedEffects: unresolvedEffects(input),
93
108
  feedback: await feedbackOf(context, { state, runId: run.runId }),
@@ -96,6 +111,7 @@ async function viewOf(context, scope) {
96
111
  function summary(view) {
97
112
  return {
98
113
  runId: view.runId,
114
+ ...(view.scheduled === undefined ? {} : { scheduled: view.scheduled }),
99
115
  ...linksOf(view),
100
116
  input: view.input,
101
117
  workflowId: view.workflowId,
@@ -106,6 +122,7 @@ function summary(view) {
106
122
  latestSequence: view.latestSequence,
107
123
  latestAt: view.latestAt,
108
124
  pendingDecisions: view.pendingDecisions,
125
+ commandWaits: view.commandWaits,
109
126
  };
110
127
  }
111
128
  function full(view) {
@@ -135,7 +152,9 @@ async function submittedInput(context, digest) {
135
152
  return record(request?.["submission"]) ?? null;
136
153
  }
137
154
  async function listed(context, page) {
138
- const identifiers = Object.keys(page.snapshot.state.runs)
155
+ const identifiers = Object.entries(page.snapshot.state.runs)
156
+ .filter(([, run]) => !page.active || !terminal.includes(run.status))
157
+ .map(([runId]) => runId)
139
158
  .sort()
140
159
  .filter((runId) => runId > page.after);
141
160
  const shown = identifiers.slice(0, page.limit);
@@ -144,14 +163,12 @@ async function listed(context, page) {
144
163
  views.push(await viewOf(context, { snapshot: page.snapshot, runId }));
145
164
  const runs = views.filter((view) => view !== undefined).map(summary);
146
165
  return result("run-list", {
147
- ...(await queueOverview(context)),
148
- workflows: context.registry.workflowIds,
149
- workflowRefusals: context.workflowRefusals ?? [],
150
- ...(Object.keys(context.registry.workflowStages).length === 0
166
+ ...(context.version === undefined
151
167
  ? {}
152
- : {
153
- workflowStages: context.registry.workflowStages,
154
- }),
168
+ : { serviceVersion: context.version }),
169
+ ...(await queueOverview(context)),
170
+ ...(await scheduleMetadata(context)),
171
+ ...workflowFields(context),
155
172
  runs,
156
173
  next: identifiers.length > shown.length ? (shown.at(-1) ?? null) : null,
157
174
  worldReports: context.worldReports?.() ?? [],
@@ -160,17 +177,24 @@ async function listed(context, page) {
160
177
  function listParameters(parameters) {
161
178
  const after = parameters["after"] ?? "";
162
179
  const limit = parameters["limit"] ?? 50;
180
+ const active = parameters["active"] ?? false;
163
181
  if (typeof after !== "string" || !wholeNumber(limit, 1) || limit > 500)
164
182
  return undefined;
165
- return { after, limit };
183
+ if (typeof active !== "boolean")
184
+ return undefined;
185
+ return { after, limit, active };
166
186
  }
167
187
  export async function status(context, parameters) {
188
+ if (parameters["metadata"] === "workflows")
189
+ return workflowMetadata(context, parameters["runIds"]);
168
190
  if (parameters["runIds"] !== undefined)
169
191
  return queueRunStatuses(context, parameters["runIds"]);
170
192
  const { runId } = parameters;
171
193
  const page = listParameters(parameters);
172
194
  if (page === undefined)
173
195
  return invalidRequest("The status request is not valid.");
196
+ if (parameters["metadata"] === "tickets")
197
+ return ticketMetadataPage(context, page);
174
198
  const current = await snapshot(context);
175
199
  if (runId === undefined)
176
200
  return listed(context, { snapshot: current, ...page });
@@ -182,6 +206,7 @@ export async function status(context, parameters) {
182
206
  return result("run-status", {
183
207
  run: {
184
208
  ...full({ ...view, ...totals }),
209
+ ...(await turnDetailsOf(context, { runId: view.runId, totals })),
185
210
  ...(await commandFields(context, view.commandOperations)),
186
211
  outcome: await outcomeOf(context, view),
187
212
  decisions: await decidedOf(context, {
@@ -1,8 +1,22 @@
1
1
  import { type Fields } from "../protocol.ts";
2
2
  import type { RunView } from "../authority/status.ts";
3
- import type { ServiceContext } from "./replies.ts";
3
+ import { type ServiceContext } from "./replies.ts";
4
+ export declare function workflowMetadata(context: ServiceContext, runIds: unknown): Promise<import("../protocol.ts").Reply>;
5
+ export declare function ticketMetadataPage(context: ServiceContext, page: {
6
+ readonly after: string;
7
+ readonly limit: number;
8
+ }): Promise<import("../protocol.ts").Reply>;
4
9
  export declare function outcomeOf(context: ServiceContext, view: Pick<RunView, "state" | "runId" | "latestSequence">): Promise<Fields | null>;
5
10
  export declare function metadataOf(context: ServiceContext, source: {
6
11
  readonly workflowId: string;
7
12
  readonly digest: string | null | undefined;
8
13
  }): Promise<Fields>;
14
+ export declare function scheduleMetadata(context: ServiceContext): Promise<Fields>;
15
+ export declare function scheduledMetadata(context: ServiceContext, run: {
16
+ readonly runId: string;
17
+ readonly workflowId: string;
18
+ }): Promise<{
19
+ readonly scheduled?: {
20
+ readonly slot: number;
21
+ };
22
+ }>;
@@ -1,5 +1,43 @@
1
1
  import { issueIdentity } from "../issue-identity.js";
2
2
  import { record } from "../protocol.js";
3
+ import { invalidRequest, isIdentifier, result, } from "./replies.js";
4
+ export async function workflowMetadata(context, runIds) {
5
+ if (!Array.isArray(runIds) ||
6
+ runIds.length === 0 ||
7
+ runIds.length > 500 ||
8
+ !runIds.every(isIdentifier) ||
9
+ new Set(runIds).size !== runIds.length)
10
+ return invalidRequest("Workflow metadata needs one to 500 distinct run IDs.");
11
+ const identities = await context.authority.queries.workflowIds(runIds);
12
+ return result("run-workflow-metadata", {
13
+ runs: runIds.map((runId) => ({
14
+ runId,
15
+ workflowId: identities[runId] ?? null,
16
+ })),
17
+ });
18
+ }
19
+ export async function ticketMetadataPage(context, page) {
20
+ const state = await context.authority.state();
21
+ const identifiers = Object.keys(state.runs)
22
+ .sort()
23
+ .filter((runId) => runId > page.after);
24
+ const shown = identifiers.slice(0, page.limit);
25
+ const runs = [];
26
+ for (const runId of shown) {
27
+ const digest = state.details[runId]?.input;
28
+ const document = digest
29
+ ? await context.authority.queries.document(digest)
30
+ : "{}";
31
+ const input = record(JSON.parse(document ?? "null"));
32
+ if (input === undefined)
33
+ throw new Error("report-ticket-metadata-unavailable");
34
+ runs.push({ runId, ticketId: ticketIdOf(input) });
35
+ }
36
+ return result("run-ticket-metadata", {
37
+ runs,
38
+ next: identifiers.length > shown.length ? shown.at(-1) : null,
39
+ });
40
+ }
3
41
  export async function outcomeOf(context, view) {
4
42
  if (view.state !== "completed")
5
43
  return null;
@@ -20,13 +58,22 @@ export async function outcomeOf(context, view) {
20
58
  ...(issueUpdate === "failed" ? { issueUpdate } : {}),
21
59
  };
22
60
  }
61
+ function ticketOf(input) {
62
+ const declared = record(record(input?.["input"])?.["ticket"]);
63
+ const id = declared === undefined ? input?.["ticketId"] : declared["id"];
64
+ const text = declared === undefined ? input?.["ticket"] : declared["text"];
65
+ return {
66
+ id: typeof id === "string" ? id : undefined,
67
+ text: typeof text === "string" ? text : undefined,
68
+ };
69
+ }
23
70
  function titleOf(input, workflowId) {
24
- const ticket = input?.["ticket"];
25
- if (typeof ticket !== "string")
71
+ const ticket = ticketOf(input).text;
72
+ if (ticket === undefined)
26
73
  return null;
27
74
  const fallback = `Cloving task ${String(input?.["cycleId"])}`;
28
75
  const lines = ticket.split("\n");
29
- if (workflowId === "develop-prompt") {
76
+ if (workflowId === "develop-prompt" && !Object.hasOwn(input ?? {}, "input")) {
30
77
  const first = lines.find((line) => /\S/.test(line));
31
78
  return first === undefined
32
79
  ? fallback
@@ -42,12 +89,50 @@ export async function metadataOf(context, source) {
42
89
  ? await context.authority.queries.document(source.digest)
43
90
  : undefined;
44
91
  const input = record(JSON.parse(document ?? "null"));
45
- const ticketId = input?.["ticketId"];
46
92
  return {
47
- ticketId: typeof ticketId === "string" && ticketId !== "" ? ticketId : null,
93
+ ticketId: ticketIdOf(input),
48
94
  title: titleOf(input, source.workflowId),
49
- ...(source.workflowId === "develop-issue"
50
- ? { issueIdentity: issueIdentity(input?.["ticket"]) }
51
- : {}),
95
+ ...(ticketOf(input).text === undefined
96
+ ? {}
97
+ : { issueIdentity: issueIdentity(ticketOf(input).text) }),
98
+ };
99
+ }
100
+ function ticketIdOf(input) {
101
+ const ticketId = ticketOf(input).id;
102
+ return ticketId === undefined || ticketId === "" ? null : ticketId;
103
+ }
104
+ export async function scheduleMetadata(context) {
105
+ if (context.schedule === undefined)
106
+ return {};
107
+ const reply = await context.schedule({ action: "list" });
108
+ if (reply.kind !== "result" || !Array.isArray(reply.result["schedules"]))
109
+ return { schedules: { status: "unavailable" } };
110
+ const schedules = reply.result["schedules"];
111
+ if (schedules.length === 0)
112
+ return {};
113
+ return {
114
+ schedules: schedules.map((value) => {
115
+ const schedule = record(value) ?? {};
116
+ return Object.fromEntries([
117
+ "workflowId",
118
+ "everySeconds",
119
+ "state",
120
+ "failuresInRow",
121
+ "nextAt",
122
+ "stoppedAt",
123
+ ].map((name) => [name, schedule[name]]));
124
+ }),
52
125
  };
53
126
  }
127
+ export async function scheduledMetadata(context, run) {
128
+ const commandId = (await context.authority.queries.run(run.runId))
129
+ ?.admissionCommandId;
130
+ const prefix = `schedule:${run.workflowId}:`;
131
+ if (typeof commandId !== "string" || !commandId.startsWith(prefix))
132
+ return {};
133
+ const suffix = commandId.slice(prefix.length);
134
+ const slot = Number(suffix);
135
+ return /^(0|[1-9][0-9]*)$/.test(suffix) && Number.isSafeInteger(slot)
136
+ ? { scheduled: { slot } }
137
+ : {};
138
+ }
@@ -1,10 +1,12 @@
1
1
  import { type Authority, type AuthorityTiming, type Delivery, type EffectSettings, type Refusal } from "../broker/actor/authority.ts";
2
2
  import { type WorkflowRefusal } from "../workflow-refusals.ts";
3
3
  import { type Registry, type WorkflowRegistration, type WorkflowBundleStore } from "./registry.ts";
4
- import { type ServiceContext } from "./replies.ts";
4
+ import { type WorkflowReloadPort } from "./workflow-reload.ts";
5
+ import { type ServiceContext, type ServiceReads } from "./replies.ts";
5
6
  import { type WorkerPort } from "./worker-port.ts";
6
7
  import type { RunWaitTarget } from "../run-wait.ts";
7
8
  import type { CommandEffects } from "../command-settings.ts";
9
+ import { type CommandWaitPort } from "./command-waits.ts";
8
10
  export type { WorkflowRegistration } from "./registry.ts";
9
11
  export type { EffectReply, EffectReport, EffectRequest, WorkerPort, } from "./worker-port.ts";
10
12
  export interface ServiceTiming {
@@ -27,6 +29,7 @@ export interface ServiceHost {
27
29
  readonly reports?: () => readonly unknown[];
28
30
  }
29
31
  export interface HostPorts {
32
+ readonly commandWait: CommandWaitPort;
30
33
  readonly runWait?: {
31
34
  readonly target: (runId: string) => Promise<RunWaitTarget | undefined>;
32
35
  readonly observe: WorkerPort["observe"];
@@ -47,8 +50,11 @@ export interface HostPorts {
47
50
  readonly openGate: WorkerPort["openGate"];
48
51
  readonly registerWait: WorkerPort["registerWait"];
49
52
  }
50
- export interface ServiceOptions {
51
- readonly workerHarness?: ServiceContext["workerHarness"];
53
+ export interface ServiceOptions extends ServiceReads {
54
+ readonly version?: string;
55
+ readonly schedule?: NonNullable<ServiceContext["schedule"]>;
56
+ readonly queue?: NonNullable<ServiceContext["queue"]>;
57
+ readonly queueDailySpendLimitUsd?: number;
52
58
  readonly commandEffects?: CommandEffects;
53
59
  readonly stateDirectory: string;
54
60
  readonly runtimeDirectory: string;
@@ -57,6 +63,8 @@ export interface ServiceOptions {
57
63
  readonly workflowBundles?: WorkflowBundleStore;
58
64
  readonly retainedWorkflow?: Registry["available"];
59
65
  readonly workflowRefusals?: readonly WorkflowRefusal[];
66
+ readonly bundleDigest?: string;
67
+ readonly reload?: WorkflowReloadPort;
60
68
  readonly delivery: Delivery;
61
69
  readonly host?: (ports: HostPorts) => Promise<ServiceHost>;
62
70
  readonly timing?: ServiceTiming;