cloving 1.3.0 → 1.4.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 (396) hide show
  1. package/README.md +235 -206
  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-queries.d.ts +2 -1
  32. package/dist/src/broker/actor/authority-queries.js +14 -5
  33. package/dist/src/broker/actor/authority-receipts.js +1 -1
  34. package/dist/src/broker/actor/authority-settings.js +2 -2
  35. package/dist/src/broker/actor/authority-upgrades.d.ts +19 -2
  36. package/dist/src/broker/actor/authority-upgrades.js +7 -2
  37. package/dist/src/broker/actor/delivery-intents.js +2 -0
  38. package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
  39. package/dist/src/broker/actor/effect-delivery.js +15 -2
  40. package/dist/src/broker/actor/effect-plan.js +11 -2
  41. package/dist/src/broker/actor/effect-queries.d.ts +4 -0
  42. package/dist/src/broker/actor/effect-queries.js +9 -1
  43. package/dist/src/broker/actor/effect-turn.js +2 -0
  44. package/dist/src/broker/actor/stop-plan.js +9 -3
  45. package/dist/src/broker/actor/stop-turn.d.ts +2 -0
  46. package/dist/src/broker/actor/stop-turn.js +24 -11
  47. package/dist/src/broker/actor/turn-draft.d.ts +1 -0
  48. package/dist/src/broker/actor/turn-draft.js +4 -0
  49. package/dist/src/broker/actor/turn-state.js +5 -1
  50. package/dist/src/broker/authority-admission.js +60 -0
  51. package/dist/src/broker/authority-restore.d.ts +2 -0
  52. package/dist/src/broker/authority-restore.js +35 -1
  53. package/dist/src/broker/command-wait-restore.d.ts +31 -0
  54. package/dist/src/broker/command-wait-restore.js +86 -0
  55. package/dist/src/broker/decision-restore.d.ts +1 -1
  56. package/dist/src/broker/decision-restore.js +1 -0
  57. package/dist/src/broker/effect-upgrade.d.ts +2 -0
  58. package/dist/src/broker/effect-upgrade.js +8 -2
  59. package/dist/src/cli/arguments.d.ts +13 -0
  60. package/dist/src/cli/arguments.js +42 -3
  61. package/dist/src/cli/chat-stores.d.ts +2 -0
  62. package/dist/src/cli/chat-stores.js +113 -0
  63. package/dist/src/cli/client.d.ts +4 -1
  64. package/dist/src/cli/client.js +9 -3
  65. package/dist/src/cli/command-requests.d.ts +17 -0
  66. package/dist/src/cli/command-requests.js +43 -0
  67. package/dist/src/cli/command-waits.d.ts +9 -0
  68. package/dist/src/cli/command-waits.js +51 -0
  69. package/dist/src/cli/commands.js +14 -41
  70. package/dist/src/cli/config-file.d.ts +2 -2
  71. package/dist/src/cli/config-file.js +4 -2
  72. package/dist/src/cli/doctor-workflows.d.ts +5 -2
  73. package/dist/src/cli/doctor-workflows.js +12 -7
  74. package/dist/src/cli/doctor.js +6 -9
  75. package/dist/src/cli/harness-probes.d.ts +2 -0
  76. package/dist/src/cli/harness-probes.js +1 -1
  77. package/dist/src/cli/harness-processes.d.ts +6 -0
  78. package/dist/src/cli/harness-processes.js +36 -0
  79. package/dist/src/cli/init-command.d.ts +9 -0
  80. package/dist/src/cli/init-command.js +52 -0
  81. package/dist/src/cli/init-prompt-command.d.ts +10 -0
  82. package/dist/src/cli/init-prompt-command.js +145 -0
  83. package/dist/src/cli/init-prompt.d.ts +35 -0
  84. package/dist/src/cli/init-prompt.js +74 -0
  85. package/dist/src/cli/init-selection.d.ts +13 -0
  86. package/dist/src/cli/init-selection.js +75 -0
  87. package/dist/src/cli/main.d.ts +2 -0
  88. package/dist/src/cli/main.js +37 -7
  89. package/dist/src/cli/mcp-server.d.ts +1 -0
  90. package/dist/src/cli/mcp-server.js +156 -0
  91. package/dist/src/cli/mcp-tools.d.ts +15 -0
  92. package/dist/src/cli/mcp-tools.js +80 -0
  93. package/dist/src/cli/render.d.ts +1 -1
  94. package/dist/src/cli/render.js +17 -30
  95. package/dist/src/cli/report-ci-jobs.d.ts +23 -0
  96. package/dist/src/cli/report-ci-jobs.js +103 -0
  97. package/dist/src/cli/report-ci-usage.d.ts +9 -0
  98. package/dist/src/cli/report-ci-usage.js +185 -0
  99. package/dist/src/cli/report-ci.d.ts +13 -0
  100. package/dist/src/cli/report-ci.js +74 -0
  101. package/dist/src/cli/report-closures.d.ts +6 -0
  102. package/dist/src/cli/report-closures.js +97 -0
  103. package/dist/src/cli/report-flow.d.ts +7 -0
  104. package/dist/src/cli/report-flow.js +122 -0
  105. package/dist/src/cli/report-github-reader.d.ts +29 -0
  106. package/dist/src/cli/report-github-reader.js +157 -0
  107. package/dist/src/cli/report-github.d.ts +15 -8
  108. package/dist/src/cli/report-github.js +131 -150
  109. package/dist/src/cli/report-operator.d.ts +3 -0
  110. package/dist/src/cli/report-operator.js +40 -0
  111. package/dist/src/cli/report-ready.d.ts +3 -0
  112. package/dist/src/cli/report-ready.js +96 -0
  113. package/dist/src/cli/report-text.d.ts +9 -0
  114. package/dist/src/cli/report-text.js +33 -0
  115. package/dist/src/cli/report.d.ts +1 -0
  116. package/dist/src/cli/report.js +104 -27
  117. package/dist/src/cli/runtime-arguments.d.ts +2 -1
  118. package/dist/src/cli/runtime-arguments.js +7 -2
  119. package/dist/src/cli/schedule-arguments.d.ts +14 -0
  120. package/dist/src/cli/schedule-arguments.js +26 -0
  121. package/dist/src/cli/schedule-render.d.ts +22 -0
  122. package/dist/src/cli/schedule-render.js +73 -0
  123. package/dist/src/cli/terminal-text.d.ts +3 -0
  124. package/dist/src/cli/terminal-text.js +28 -0
  125. package/dist/src/cli/usage-render.d.ts +1 -0
  126. package/dist/src/cli/usage-render.js +28 -1
  127. package/dist/src/cli/usage.d.ts +1 -1
  128. package/dist/src/cli/usage.js +50 -7
  129. package/dist/src/cli/watch-actions.js +2 -2
  130. package/dist/src/cli/watch-board-view.js +19 -2
  131. package/dist/src/cli/watch-board.d.ts +4 -2
  132. package/dist/src/cli/watch-board.js +53 -43
  133. package/dist/src/cli/watch-card-forms.d.ts +1 -1
  134. package/dist/src/cli/watch-card-forms.js +11 -10
  135. package/dist/src/cli/watch-client.d.ts +1 -1
  136. package/dist/src/cli/watch-client.js +2 -11
  137. package/dist/src/cli/watch-header-view.d.ts +0 -5
  138. package/dist/src/cli/watch-header-view.js +8 -20
  139. package/dist/src/cli/watch-model.d.ts +4 -1
  140. package/dist/src/cli/watch-model.js +17 -11
  141. package/dist/src/cli/watch-page.js +12 -14
  142. package/dist/src/cli/watch-phases.d.ts +12 -3
  143. package/dist/src/cli/watch-phases.js +68 -11
  144. package/dist/src/cli/watch-pr-board.js +1 -1
  145. package/dist/src/cli/watch-pr-command.d.ts +1 -0
  146. package/dist/src/cli/watch-pull-request.js +18 -8
  147. package/dist/src/cli/watch-reads.d.ts +2 -0
  148. package/dist/src/cli/watch-reads.js +17 -16
  149. package/dist/src/cli/watch-render.d.ts +14 -0
  150. package/dist/src/cli/watch-run-input.d.ts +0 -1
  151. package/dist/src/cli/watch-run-input.js +0 -13
  152. package/dist/src/cli/watch-server.js +6 -6
  153. package/dist/src/cli/watch-view.d.ts +0 -3
  154. package/dist/src/cli/watch-view.js +13 -13
  155. package/dist/src/cli.js +59 -5
  156. package/dist/src/command-wait.d.ts +4 -0
  157. package/dist/src/command-wait.js +45 -0
  158. package/dist/src/configuration-change.d.ts +7 -0
  159. package/dist/src/configuration-change.js +14 -0
  160. package/dist/src/configuration-schema.d.ts +9 -0
  161. package/dist/src/configuration-schema.js +6 -2
  162. package/dist/src/daemon/attachment-file.d.ts +6 -0
  163. package/dist/src/daemon/attachment-file.js +86 -0
  164. package/dist/src/daemon/attachments.d.ts +14 -0
  165. package/dist/src/daemon/attachments.js +17 -0
  166. package/dist/src/daemon/claude-recovery.d.ts +50 -0
  167. package/dist/src/daemon/claude-recovery.js +204 -0
  168. package/dist/src/daemon/claude-stream.d.ts +27 -0
  169. package/dist/src/daemon/claude-stream.js +63 -0
  170. package/dist/src/daemon/claude-turn.d.ts +11 -25
  171. package/dist/src/daemon/claude-turn.js +64 -81
  172. package/dist/src/daemon/claude-worker.d.ts +2 -1
  173. package/dist/src/daemon/claude-worker.js +124 -122
  174. package/dist/src/daemon/daemon-adapters.d.ts +2 -0
  175. package/dist/src/daemon/daemon-adapters.js +26 -2
  176. package/dist/src/daemon/daemon-loops.d.ts +3 -1
  177. package/dist/src/daemon/daemon-loops.js +3 -1
  178. package/dist/src/daemon/daemon.js +14 -6
  179. package/dist/src/daemon/github-attach.d.ts +2 -0
  180. package/dist/src/daemon/github-attach.js +149 -0
  181. package/dist/src/daemon/github-ci-filters.d.ts +6 -0
  182. package/dist/src/daemon/github-ci-filters.js +138 -0
  183. package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
  184. package/dist/src/daemon/github-ci-workflows.js +148 -0
  185. package/dist/src/daemon/github-ci.js +22 -4
  186. package/dist/src/daemon/github-issue-methods.d.ts +2 -0
  187. package/dist/src/daemon/github-issue-methods.js +37 -2
  188. package/dist/src/daemon/github-merge-call.d.ts +2 -1
  189. package/dist/src/daemon/github-merge-call.js +10 -3
  190. package/dist/src/daemon/github-merge.js +52 -24
  191. package/dist/src/daemon/github-methods.js +12 -2
  192. package/dist/src/daemon/github-operation.d.ts +4 -0
  193. package/dist/src/daemon/github-operation.js +6 -0
  194. package/dist/src/daemon/github-worker.d.ts +4 -0
  195. package/dist/src/daemon/github-worker.js +6 -0
  196. package/dist/src/daemon/issue-queue.d.ts +1 -1
  197. package/dist/src/daemon/issue-queue.js +16 -11
  198. package/dist/src/daemon/notify-events.d.ts +6 -0
  199. package/dist/src/daemon/notify-events.js +84 -0
  200. package/dist/src/daemon/notify-journal.js +1 -1
  201. package/dist/src/daemon/notify-message.d.ts +4 -1
  202. package/dist/src/daemon/notify-message.js +36 -0
  203. package/dist/src/daemon/notify.d.ts +1 -1
  204. package/dist/src/daemon/notify.js +5 -77
  205. package/dist/src/daemon/operation-journal.d.ts +1 -0
  206. package/dist/src/daemon/queue-status.d.ts +9 -3
  207. package/dist/src/daemon/queue-status.js +17 -4
  208. package/dist/src/daemon/resume-index-lock.d.ts +13 -0
  209. package/dist/src/daemon/resume-index-lock.js +160 -0
  210. package/dist/src/daemon/resume-worktree.d.ts +7 -0
  211. package/dist/src/daemon/resume-worktree.js +29 -0
  212. package/dist/src/daemon/retrying-turn.d.ts +2 -12
  213. package/dist/src/daemon/retrying-turn.js +98 -172
  214. package/dist/src/daemon/schedule-control.d.ts +26 -0
  215. package/dist/src/daemon/schedule-control.js +110 -0
  216. package/dist/src/daemon/schedule-journal.d.ts +2 -15
  217. package/dist/src/daemon/schedule-journal.js +67 -4
  218. package/dist/src/daemon/ticket-registration.d.ts +2 -7
  219. package/dist/src/daemon/ticket-registration.js +15 -81
  220. package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
  221. package/dist/src/daemon/turn-attempt-journal.js +136 -0
  222. package/dist/src/daemon/turn-attempts.d.ts +47 -0
  223. package/dist/src/daemon/turn-attempts.js +166 -0
  224. package/dist/src/daemon/turn-report.d.ts +8 -1
  225. package/dist/src/daemon/turn-report.js +39 -0
  226. package/dist/src/daemon/work-tree.d.ts +9 -0
  227. package/dist/src/daemon/work-tree.js +20 -0
  228. package/dist/src/daemon/worker-profile.d.ts +8 -0
  229. package/dist/src/daemon/worker-profile.js +40 -0
  230. package/dist/src/daemon/workflow-schedules.d.ts +3 -0
  231. package/dist/src/daemon/workflow-schedules.js +98 -45
  232. package/dist/src/daemon/worktree-processes.d.ts +9 -0
  233. package/dist/src/daemon/worktree-processes.js +151 -0
  234. package/dist/src/doctor-report.d.ts +3 -5
  235. package/dist/src/doctor-report.js +6 -13
  236. package/dist/src/harness-start.d.ts +15 -0
  237. package/dist/src/harness-start.js +37 -0
  238. package/dist/src/host/command-wait.d.ts +38 -0
  239. package/dist/src/host/command-wait.js +115 -0
  240. package/dist/src/host/start-delivery.d.ts +5 -7
  241. package/dist/src/host/start-delivery.js +3 -15
  242. package/dist/src/host/step-bridge-host.d.ts +2 -0
  243. package/dist/src/host/step-bridge-host.js +21 -0
  244. package/dist/src/operation-identity.d.ts +1 -0
  245. package/dist/src/operation-identity.js +4 -0
  246. package/dist/src/private-config.schema.json +40 -0
  247. package/dist/src/project-config.schema.json +40 -0
  248. package/dist/src/project-settings.d.ts +2 -2
  249. package/dist/src/project-settings.js +3 -1
  250. package/dist/src/queue-spend.d.ts +4 -0
  251. package/dist/src/queue-spend.js +21 -0
  252. package/dist/src/relay/relay-service.d.ts +3 -0
  253. package/dist/src/relay/relay-service.js +5 -3
  254. package/dist/src/report-ci.d.ts +164 -0
  255. package/dist/src/report-ci.js +32 -0
  256. package/dist/src/report-effects.d.ts +15 -0
  257. package/dist/src/report-effects.js +212 -0
  258. package/dist/src/report-flow-types.d.ts +38 -0
  259. package/dist/src/report-flow-types.js +7 -0
  260. package/dist/src/report-flow.d.ts +43 -0
  261. package/dist/src/report-flow.js +193 -0
  262. package/dist/src/report-operator.d.ts +67 -0
  263. package/dist/src/report-operator.js +25 -0
  264. package/dist/src/report-quality.d.ts +221 -0
  265. package/dist/src/report-quality.js +94 -0
  266. package/dist/src/report-ready.d.ts +23 -0
  267. package/dist/src/report-ready.js +117 -0
  268. package/dist/src/report-statistics.d.ts +2 -1
  269. package/dist/src/report-statistics.js +40 -4
  270. package/dist/src/report.d.ts +588 -47
  271. package/dist/src/report.js +156 -41
  272. package/dist/src/schedule-progress.d.ts +33 -0
  273. package/dist/src/schedule-progress.js +45 -0
  274. package/dist/src/service/active-tickets.js +6 -6
  275. package/dist/src/service/command-waits.d.ts +34 -0
  276. package/dist/src/service/command-waits.js +86 -0
  277. package/dist/src/service/expiry.js +2 -0
  278. package/dist/src/service/gateway.js +3 -1
  279. package/dist/src/service/queue-spend.d.ts +6 -0
  280. package/dist/src/service/queue-spend.js +68 -0
  281. package/dist/src/service/replies.d.ts +8 -1
  282. package/dist/src/service/replies.js +11 -0
  283. package/dist/src/service/run-handlers.js +22 -2
  284. package/dist/src/service/run-metadata.d.ts +15 -1
  285. package/dist/src/service/run-metadata.js +93 -8
  286. package/dist/src/service/service.d.ts +4 -0
  287. package/dist/src/service/service.js +8 -8
  288. package/dist/src/service/submission-handler.js +18 -4
  289. package/dist/src/service/worker-port.js +9 -1
  290. package/dist/src/service/worker-totals.d.ts +2 -0
  291. package/dist/src/service/worker-totals.js +1 -1
  292. package/dist/src/step-bridge.d.ts +20 -0
  293. package/dist/src/steps/command-wait.d.ts +12 -0
  294. package/dist/src/steps/command-wait.js +26 -0
  295. package/dist/src/steps/open-decision-wait.d.ts +2 -0
  296. package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
  297. package/dist/src/steps/review-by-person.js +4 -1
  298. package/dist/src/steps/wait-for-command.d.ts +3 -0
  299. package/dist/src/steps/wait-for-command.js +17 -0
  300. package/dist/src/steps/wait-for-decision.js +1 -1
  301. package/dist/src/storage/command-wait-rows.d.ts +30 -0
  302. package/dist/src/storage/command-wait-rows.js +96 -0
  303. package/dist/src/storage/decision-snapshots.d.ts +8 -1
  304. package/dist/src/storage/decision-snapshots.js +15 -1
  305. package/dist/src/storage/domain-changes.d.ts +2 -0
  306. package/dist/src/storage/domain-changes.js +3 -0
  307. package/dist/src/storage/domain-schema.d.ts +13 -1
  308. package/dist/src/storage/domain-schema.js +31 -4
  309. package/dist/src/storage/effect-schema.d.ts +1 -0
  310. package/dist/src/storage/effect-schema.js +5 -0
  311. package/dist/src/testing-requests.d.ts +15 -0
  312. package/dist/src/testing-requests.js +93 -0
  313. package/dist/src/testing.d.ts +4 -10
  314. package/dist/src/testing.js +33 -86
  315. package/dist/src/worker-usage.d.ts +1 -0
  316. package/dist/src/worker-usage.js +3 -0
  317. package/dist/src/workflow-candidate.d.ts +1 -0
  318. package/dist/src/workflow-candidate.js +12 -1
  319. package/dist/src/workflow-contracts.d.ts +1 -0
  320. package/dist/src/workflow-contracts.js +9 -2
  321. package/dist/src/workflow-discovery.d.ts +2 -13
  322. package/dist/src/workflow-discovery.js +1 -13
  323. package/dist/src/workflow-refusals.js +0 -1
  324. package/dist/src/workflows.d.ts +1 -1
  325. package/dist/src/workflows.js +1 -1
  326. package/dist/tools/red-green-command.d.ts +1 -0
  327. package/dist/tools/red-green-command.js +174 -0
  328. package/dist/tools/red-green-process.d.ts +10 -0
  329. package/dist/tools/red-green-process.js +59 -0
  330. package/dist/tools/self-host-processes.d.ts +2 -0
  331. package/dist/tools/self-host-processes.js +32 -13
  332. package/dist/tools/self-host-project.js +13 -78
  333. package/dist/tools/self-host-runtime.js +1 -1
  334. package/dist/tools/self-host.js +42 -10
  335. package/dist/tools/template-command.d.ts +1 -0
  336. package/dist/tools/template-command.js +160 -0
  337. package/dist/tools/template-copy.d.ts +11 -0
  338. package/dist/tools/template-copy.js +130 -0
  339. package/dist/tools/template-files.d.ts +17 -0
  340. package/dist/tools/template-files.js +74 -0
  341. package/dist/tools/workflow-bundles.js +1 -0
  342. package/dist/tools/workflow-candidate-counts.js +2 -2
  343. package/dist/tools/workflow-candidate-shape.d.ts +3 -0
  344. package/dist/tools/workflow-candidate-shape.js +90 -0
  345. package/dist/tools/workflow-candidate-source.js +15 -1
  346. package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
  347. package/dist/tools/workflow-candidate-syntax.js +24 -94
  348. package/dist/tools/workflow-command.js +1 -2
  349. package/dist/tools/workflow-folders.d.ts +2 -3
  350. package/dist/tools/workflow-folders.js +1 -1
  351. package/package.json +16 -8
  352. package/templates/develop/README.md +12 -0
  353. package/templates/develop/develop/flow-tests.ts +37 -0
  354. package/templates/develop/develop/pull.ts +5 -1
  355. package/templates/develop/develop/refusal-tests.ts +77 -0
  356. package/templates/develop/develop/turn.ts +2 -1
  357. package/templates/idea-to-issue/README.md +27 -0
  358. package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
  359. package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
  360. package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
  361. package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
  362. package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
  363. package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
  364. package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
  365. package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
  366. package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
  367. package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
  368. package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
  369. package/templates/idea-to-issue/idea-to-issue.ts +49 -0
  370. package/templates/idea-to-issue/template.json +81 -0
  371. package/templates/review-day/README.md +97 -0
  372. package/templates/review-day/review-day/critique.ts +58 -0
  373. package/templates/review-day/review-day/decision.ts +29 -0
  374. package/templates/review-day/review-day/facts.ts +69 -0
  375. package/templates/review-day/review-day/label.ts +29 -0
  376. package/templates/review-day/review-day/next.ts +28 -0
  377. package/templates/review-day/review-day/post.ts +27 -0
  378. package/templates/review-day/review-day/report.ts +98 -0
  379. package/templates/review-day/review-day/rules.ts +12 -0
  380. package/templates/review-day/review-day/scenarios.ts +76 -0
  381. package/templates/review-day/review-day/turn.ts +73 -0
  382. package/templates/review-day/review-day.declaration.json +16 -0
  383. package/templates/review-day/review-day.test.ts +362 -0
  384. package/templates/review-day/review-day.ts +37 -0
  385. package/templates/review-day/template.json +56 -0
  386. package/dist/src/cli/watch-start-view.d.ts +0 -18
  387. package/dist/src/cli/watch-start-view.js +0 -77
  388. package/dist/src/steps/decision-gate.d.ts +0 -3
  389. package/dist/workflows/develop-prd.d.ts +0 -7
  390. package/dist/workflows/develop-prd.js +0 -165
  391. package/dist/workflows/develop-ticket.d.ts +0 -9
  392. package/dist/workflows/develop-ticket.js +0 -207
  393. package/dist/workflows/issue-labels.d.ts +0 -16
  394. package/dist/workflows/issue-labels.js +0 -70
  395. package/dist/workflows/ticket-prompts.d.ts +0 -35
  396. package/dist/workflows/ticket-prompts.js +0 -147
@@ -0,0 +1,166 @@
1
+ import { priceOf, sumUsage, usageOf, } from "../worker-usage.js";
2
+ import { commandModel, replaceCommandModel, estimatedCostUsd, priceForModel, } from "../token-prices.js";
3
+ import { capacityRefusal, retryKind, } from "./claude-turn.js";
4
+ import { nativeHarness } from "../harness-defaults.js";
5
+ import { profileCommand } from "../turn-profile.js";
6
+ export function total(values) {
7
+ if (values.includes(null))
8
+ return null;
9
+ return priceOf(values.reduce((sum, value) => sum + (value ?? 0), 0));
10
+ }
11
+ export function combined(attempts) {
12
+ const { ends } = attempts;
13
+ const last = ends.at(-1) ?? { exitCode: null, result: undefined };
14
+ const result = last.result ?? ends.find((end) => end.result)?.result;
15
+ if (result === undefined)
16
+ return last;
17
+ return {
18
+ ...last,
19
+ result: {
20
+ ...result,
21
+ attempts: ends.map((end, index) => attemptUsage(attempts, { end, attempt: index + 1 })),
22
+ ...(last.result === undefined ? { failed: true, text: "" } : {}),
23
+ usage: sumUsage(ends.map((end) => end.result?.usage ?? usageOf(null))),
24
+ costUsd: (attempts.start.worker ?? "claude") === "claude"
25
+ ? sessionCost(ends)
26
+ : total(ends.map((end) => end.result?.costUsd ?? null)),
27
+ turns: total(ends.map((end) => end.result?.turns ?? null)),
28
+ },
29
+ };
30
+ }
31
+ function selectedCommand(attempts, attempt) {
32
+ const { start, options } = attempts;
33
+ const original = start.command;
34
+ const previous = attempts.ends[attempt - 2];
35
+ if (options.resume !== undefined &&
36
+ attempt === options.resume.ends.length + 1) {
37
+ const model = previous?.result?.model;
38
+ return {
39
+ command: model == null ? original : replaceCommandModel(original, model),
40
+ fallback: undefined,
41
+ };
42
+ }
43
+ const ordinal = attempt -
44
+ attempts.ends
45
+ .slice(0, attempt - 1)
46
+ .filter((end) => end.resumedAfter !== undefined).length;
47
+ const fallback = previous !== undefined && kindOf(attempts, previous) === "capacity"
48
+ ? options.fallbackModels?.[ordinal - 3]
49
+ : undefined;
50
+ return {
51
+ command: fallback === undefined
52
+ ? original
53
+ : replaceCommandModel(original, fallback),
54
+ fallback,
55
+ };
56
+ }
57
+ export function attemptCommand(attempts, attempt) {
58
+ const { start } = attempts;
59
+ const { command: selected, fallback } = selectedCommand(attempts, attempt);
60
+ const budgetUsd = remainingBudget(attempts);
61
+ const command = budgetUsd === undefined
62
+ ? selected
63
+ : profileCommand(selected, { maxBudgetUsd: budgetUsd });
64
+ const model = start.output === "text" ? null : commandModel(command);
65
+ return {
66
+ command,
67
+ ...(budgetUsd === undefined ? {} : { budgetUsd }),
68
+ model,
69
+ ...(fallback !== undefined && model === null
70
+ ? { fallbackReason: "fallback-model-unavailable" }
71
+ : {}),
72
+ };
73
+ }
74
+ export function attemptUsage(attempts, completion) {
75
+ const { end, attempt } = completion;
76
+ const result = end.result ?? {
77
+ model: null,
78
+ usage: usageOf(null),
79
+ costUsd: null,
80
+ pricingModel: undefined,
81
+ };
82
+ const model = result.model ?? attemptCommand(attempts, attempt).model;
83
+ const usage = result.usage;
84
+ return {
85
+ attempt,
86
+ ...(end.resumedAfter === undefined
87
+ ? {}
88
+ : { resumedAfter: end.resumedAfter }),
89
+ retryKind: kindOf(attempts, end),
90
+ model,
91
+ ...(end.result?.models === undefined ? {} : { models: end.result.models }),
92
+ usage,
93
+ costUsd: (attempts.start.worker ?? "claude") === "claude"
94
+ ? attemptCost(attempts.ends, attempt - 1)
95
+ : result.costUsd,
96
+ estimatedCostUsd: attemptEstimate(attempts, { end, model, usage }),
97
+ };
98
+ }
99
+ export function sessionCost(ends) {
100
+ const sessions = new Map();
101
+ ends.forEach((end, index) => {
102
+ sessions.set(end.result?.sessionId ?? index, end.result?.costUsd ?? null);
103
+ });
104
+ return total([...sessions.values()]);
105
+ }
106
+ export function attemptCost(ends, index) {
107
+ const result = ends[index]?.result;
108
+ if (result?.costUsd == null)
109
+ return null;
110
+ const earlier = result.sessionId === null
111
+ ? undefined
112
+ : ends
113
+ .slice(0, index)
114
+ .findLast((end) => end.result?.sessionId === result.sessionId);
115
+ if (earlier === undefined)
116
+ return result.costUsd;
117
+ const cost = earlier.result?.costUsd;
118
+ return cost == null
119
+ ? null
120
+ : priceOf(Number((result.costUsd - cost).toFixed(12)));
121
+ }
122
+ function remainingBudget(attempts) {
123
+ if ((attempts.start.worker ?? "claude") !== "claude" ||
124
+ attempts.start.output === "text")
125
+ return undefined;
126
+ const budget = commandBudget(attempts.start.command);
127
+ if (budget === undefined)
128
+ return undefined;
129
+ const spent = sessionCost(attempts.ends);
130
+ return Math.max(0, Number((budget - (spent ?? 0)).toFixed(12)));
131
+ }
132
+ function commandBudget(original) {
133
+ const separator = original.indexOf("--");
134
+ const command = separator < 0 ? original : original.slice(0, separator);
135
+ const index = command.findLastIndex((part) => part === "--max-budget-usd" || part.startsWith("--max-budget-usd="));
136
+ if (index < 0)
137
+ return undefined;
138
+ const argument = command[index] ?? "";
139
+ const budget = Number(argument.includes("=") ? argument.split("=")[1] : command[index + 1]);
140
+ if (!Number.isFinite(budget) || budget < 0)
141
+ return undefined;
142
+ return budget;
143
+ }
144
+ export function attemptEstimate(attempts, result) {
145
+ const worker = attempts.start.worker ?? "claude";
146
+ if (!nativeHarness(worker))
147
+ return null;
148
+ const models = result.end.result?.models;
149
+ const prices = attempts.options.tokenPrices ?? {};
150
+ return estimatedCostUsd(result.usage, worker === "gemini" && models !== undefined
151
+ ? { worker, models, prices }
152
+ : {
153
+ worker,
154
+ price: priceForModel(prices, result.end.result?.pricingModel === undefined
155
+ ? result.model
156
+ : result.end.result.pricingModel),
157
+ });
158
+ }
159
+ export function kindOf(attempts, end) {
160
+ const { worker, output } = attempts.start;
161
+ if (output === "text" || !["claude", "codex"].includes(worker ?? "claude"))
162
+ return null;
163
+ if (worker !== "codex")
164
+ return end.retryKind ?? retryKind(end.result);
165
+ return capacityRefusal(end.result) ? "capacity" : null;
166
+ }
@@ -1,5 +1,6 @@
1
+ import type { Recorded } from "./operation-journal.ts";
1
2
  import { type WorkTree } from "./work-tree.ts";
2
- import type { StreamResult } from "./claude-turn.ts";
3
+ import { type StreamResult, type TurnEnd } from "./claude-turn.ts";
3
4
  interface ReportLimits {
4
5
  readonly summaryCharacters: number;
5
6
  readonly resultBytes: number;
@@ -15,4 +16,10 @@ export declare function turnReport(start: {
15
16
  readonly text?: string;
16
17
  readonly reason?: string;
17
18
  }>;
19
+ export declare function turnOutcome(running: Parameters<typeof turnReport>[0] & {
20
+ readonly stopping: {
21
+ readonly requested: boolean;
22
+ readonly stoppedBy?: "daemon-shutdown";
23
+ };
24
+ }, end: TurnEnd): Promise<Recorded>;
18
25
  export {};
@@ -2,6 +2,7 @@ import { ticketStatus } from "../ticket-status.js";
2
2
  import { reviewReport } from "../review-subject.js";
3
3
  import { sumPrices } from "../worker-usage.js";
4
4
  import { changes } from "./work-tree.js";
5
+ import { succeeded } from "./claude-turn.js";
5
6
  function tailReport(fields, limit) {
6
7
  let text = JSON.stringify({ ...fields, summary: "" });
7
8
  if (Buffer.byteLength(text) > limit)
@@ -77,3 +78,41 @@ export async function turnReport(start, result) {
77
78
  turns: result.turns,
78
79
  }, { ...harness, limit: limits.resultBytes });
79
80
  }
81
+ export async function turnOutcome(running, end) {
82
+ const endedAt = new Date().toISOString();
83
+ if (end.stopped === true && running.stopping.stoppedBy === "daemon-shutdown")
84
+ return stoppedOutcome(running.stopping, endedAt);
85
+ const { result } = end;
86
+ const report = result === undefined
87
+ ? {}
88
+ : await turnReport({
89
+ tree: running.tree,
90
+ harness: running.harness,
91
+ limits: running.limits,
92
+ }, result);
93
+ const { text, reason } = report;
94
+ if (succeeded(end) && reason === undefined && text !== undefined)
95
+ return { outcome: "completed", result: text, endedAt };
96
+ if (running.stopping.requested)
97
+ return stoppedOutcome(running.stopping, endedAt);
98
+ return failedOutcome(end, { ...report, endedAt });
99
+ }
100
+ function failedOutcome(end, report) {
101
+ const { text, reason, endedAt } = report;
102
+ return {
103
+ outcome: "failed",
104
+ reason: end.reason ?? reason ?? "claude-turn-failed",
105
+ ...(end.detail === undefined ? {} : { detail: end.detail }),
106
+ ...(text === undefined ? {} : { result: text }),
107
+ endedAt,
108
+ };
109
+ }
110
+ function stoppedOutcome(stopping, endedAt) {
111
+ return {
112
+ outcome: "stopped",
113
+ endedAt,
114
+ ...(stopping.stoppedBy === undefined
115
+ ? {}
116
+ : { stoppedBy: stopping.stoppedBy }),
117
+ };
118
+ }
@@ -25,3 +25,12 @@ export declare function treePlace(request: Pick<TreeRequest, "worktrees" | "targ
25
25
  export declare function workTree(request: TreeRequest): Promise<WorkTree>;
26
26
  export declare function treeFailure(error: unknown): string;
27
27
  export declare function changes(tree: WorkTree): Promise<Changes>;
28
+ export declare function firstTurn(settings: {
29
+ readonly journal: string;
30
+ }, opening: {
31
+ readonly tree: WorkTree;
32
+ readonly intent: {
33
+ readonly target: string;
34
+ readonly runId: string;
35
+ };
36
+ }): Promise<WorkTree>;
@@ -1,3 +1,4 @@
1
+ import { readRecord, writeRecord, operationKey } from "./operation-journal.js";
1
2
  import { execFile, spawn } from "node:child_process";
2
3
  import { existsSync } from "node:fs";
3
4
  import { mkdir, realpath } from "node:fs/promises";
@@ -207,3 +208,22 @@ async function changeLines(call) {
207
208
  .slice(0, lineLimit)
208
209
  .map((line) => line.slice(0, lineLength));
209
210
  }
211
+ export async function firstTurn(settings, opening) {
212
+ const { tree, intent } = opening;
213
+ const { target, runId } = intent;
214
+ const folder = target.startsWith("branch:")
215
+ ? join(settings.journal, "runs", operationKey(runId), "targets")
216
+ : join(settings.journal, "targets");
217
+ const name = `${operationKey(target)}.json`;
218
+ const record = await readRecord(folder, name);
219
+ const startCommit = typeof record === "object" && record !== null
220
+ ? Reflect.get(record, "startCommit")
221
+ : undefined;
222
+ if (typeof startCommit === "string")
223
+ return { ...tree, startCommit };
224
+ await writeRecord(folder, {
225
+ name,
226
+ value: { target, startCommit: tree.startCommit },
227
+ });
228
+ return tree;
229
+ }
@@ -0,0 +1,8 @@
1
+ import { type HarnessSettings } from "../harness-defaults.ts";
2
+ import type { TurnProfile, TurnProfiles } from "../turn-profile.ts";
3
+ import type { ProtectedIntent } from "../broker/actor/delivery-intents.ts";
4
+ export interface WorkerProfiles extends HarnessSettings {
5
+ readonly profiles?: TurnProfiles;
6
+ readonly workflowId?: (runId: string) => Promise<string | undefined>;
7
+ }
8
+ export declare function selectedProfile(settings: WorkerProfiles, intent: ProtectedIntent): Promise<TurnProfile | string>;
@@ -0,0 +1,40 @@
1
+ import { turnHarness } from "../harness-defaults.js";
2
+ async function runWorkflow(settings, runId) {
3
+ try {
4
+ return await settings.workflowId?.(runId);
5
+ }
6
+ catch {
7
+ return undefined;
8
+ }
9
+ }
10
+ function unsupportedProfile(profile, harness) {
11
+ if (harness.output === "text" && profile.model !== undefined)
12
+ return "profile-model-not-supported";
13
+ if (harness.worker === "claude")
14
+ return undefined;
15
+ return [
16
+ profile.allowedTools,
17
+ profile.permissionMode,
18
+ profile.maxBudgetUsd,
19
+ ].some((value) => value !== undefined)
20
+ ? "profile-needs-claude"
21
+ : undefined;
22
+ }
23
+ export async function selectedProfile(settings, intent) {
24
+ if (intent.method === "run-turn")
25
+ return {};
26
+ const name = intent.method.slice("run-turn:".length);
27
+ const profiles = settings.profiles ?? {};
28
+ const profile = Object.hasOwn(profiles, name) ? profiles[name] : undefined;
29
+ if (profile === undefined)
30
+ return "unknown-profile";
31
+ const unsupported = unsupportedProfile(profile, turnHarness(settings, profile));
32
+ if (unsupported !== undefined)
33
+ return unsupported;
34
+ if (profile.workflows === undefined)
35
+ return profile;
36
+ const workflowId = await runWorkflow(settings, intent.runId);
37
+ if (workflowId === undefined || !profile.workflows.includes(workflowId))
38
+ return "profile-not-allowed";
39
+ return profile;
40
+ }
@@ -1,10 +1,12 @@
1
1
  import type { WorkerPort } from "../service/worker-port.ts";
2
2
  import type { DeclaredWorkflow } from "../workflow-declaration.ts";
3
+ import type { SchedulePort } from "../schedule-progress.ts";
3
4
  interface ScheduleSettings {
4
5
  readonly directory: string;
5
6
  readonly runtimeDirectory: string;
6
7
  readonly declarations?: readonly DeclaredWorkflow[];
7
8
  readonly scheduleClock?: () => number;
9
+ readonly scheduleObservationClock?: () => number;
8
10
  readonly submit: WorkerPort["submit"];
9
11
  }
10
12
  export declare function scheduledDeclarations(settings: {
@@ -23,5 +25,6 @@ export declare function scheduledDeclarations(settings: {
23
25
  };
24
26
  export declare function workflowSchedules(settings: ScheduleSettings): Promise<{
25
27
  readonly stop: () => Promise<void>;
28
+ readonly request: SchedulePort;
26
29
  }>;
27
30
  export {};
@@ -1,10 +1,12 @@
1
1
  import { join } from "node:path";
2
2
  import { setTimeout as delay } from "node:timers/promises";
3
3
  import { mutate } from "../cli/client.js";
4
- import { record } from "../protocol.js";
4
+ import { record, } from "../protocol.js";
5
5
  import { runIdentity } from "../service/submission-handler.js";
6
6
  import { configuredSchedules } from "../workflow-schedule.js";
7
7
  import { declaredInput } from "./declared-input.js";
8
+ import { finishedScheduleRun } from "../schedule-progress.js";
9
+ import { scheduleControl } from "./schedule-control.js";
8
10
  import { scheduleJournal, } from "./schedule-journal.js";
9
11
  export function scheduledDeclarations(settings, limits) {
10
12
  try {
@@ -60,6 +62,8 @@ async function pending(settings, entry) {
60
62
  const { pending: planned, ...rest } = progress;
61
63
  if (planned === undefined)
62
64
  return progress;
65
+ if (progress.state !== "active")
66
+ throw new Error("invalid-schedule-state");
63
67
  const identity = commandId(workflowId, progress.lastSlot);
64
68
  if (planned.kind === "skip") {
65
69
  const receipt = await settings.submit({
@@ -86,10 +90,7 @@ async function pending(settings, entry) {
86
90
  throw new Error(reply.error.code);
87
91
  return { ...rest, activeCommandId: identity };
88
92
  }
89
- async function active(settings, progress) {
90
- if (progress.activeCommandId === undefined)
91
- return undefined;
92
- const runId = runIdentity(progress.activeCommandId);
93
+ async function scheduledRunStatus(settings, runId) {
93
94
  const reply = await request(settings, {
94
95
  operation: "status",
95
96
  parameters: { runId },
@@ -99,45 +100,76 @@ async function active(settings, progress) {
99
100
  const run = record(reply.result["run"]);
100
101
  if (typeof run?.["state"] !== "string")
101
102
  throw new Error("invalid-schedule-run");
103
+ return run;
104
+ }
105
+ async function active(settings, progress) {
106
+ if (progress.activeCommandId === undefined)
107
+ return progress;
108
+ const now = (settings.scheduleClock ?? Date.now)();
109
+ const observedAt = settings.observationClock();
110
+ const next = settings.nextObservations.get(progress.activeCommandId) ?? 0;
111
+ const due = progress.state === "active" && now >= progress.nextAt;
112
+ if (!due && observedAt < next)
113
+ return progress;
114
+ const runId = runIdentity(progress.activeCommandId);
115
+ const run = await scheduledRunStatus(settings, runId);
116
+ settings.nextObservations.set(progress.activeCommandId, observedAt + 5000);
102
117
  if (run["condition"] === "cancelling")
103
- return runId;
104
- return ["completed", "failed", "cancelled"].includes(run["state"])
118
+ return progress;
119
+ if (!["completed", "failed", "cancelled"].includes(String(run["state"])))
120
+ return progress;
121
+ settings.nextObservations.delete(progress.activeCommandId);
122
+ return finishedScheduleRun(progress, {
123
+ runId,
124
+ status: run,
125
+ now: (settings.scheduleClock ?? Date.now)(),
126
+ });
127
+ }
128
+ async function advance(settings, declaration) {
129
+ settings.signal.throwIfAborted();
130
+ const { workflowId, schedule } = declaration;
131
+ if (schedule === undefined)
132
+ return;
133
+ let progress = settings.journal.entries.get(workflowId);
134
+ if (progress === undefined)
135
+ throw new Error("missing-schedule-state");
136
+ if (progress.pending !== undefined) {
137
+ progress = await pending(settings, { workflowId, progress });
138
+ settings.journal.entries.set(workflowId, progress);
139
+ await settings.journal.save();
140
+ if (settings.now < progress.nextAt)
141
+ return;
142
+ }
143
+ const observed = await active(settings, progress);
144
+ if (observed !== progress) {
145
+ progress = observed;
146
+ settings.journal.entries.set(workflowId, progress);
147
+ await settings.journal.save();
148
+ }
149
+ if (progress.state !== "active" || settings.now < progress.nextAt)
150
+ return;
151
+ const runId = progress.activeCommandId === undefined
105
152
  ? undefined
106
- : runId;
153
+ : runIdentity(progress.activeCommandId);
154
+ const planned = runId === undefined
155
+ ? { kind: "run", input: schedule.input }
156
+ : { kind: "skip", runId };
157
+ const elapsed = Math.floor((settings.now - progress.nextAt) / (schedule.everySeconds * 1000)) + 1;
158
+ progress = {
159
+ ...progress,
160
+ lastSlot: progress.lastSlot + elapsed,
161
+ nextAt: progress.nextAt + elapsed * schedule.everySeconds * 1000,
162
+ pending: planned,
163
+ };
164
+ settings.journal.entries.set(workflowId, progress);
165
+ await settings.journal.save();
166
+ settings.journal.entries.set(workflowId, await pending(settings, { workflowId, progress }));
167
+ await settings.journal.save();
107
168
  }
108
169
  async function tick(settings, journal) {
109
170
  const now = (settings.scheduleClock ?? Date.now)();
110
- for (const declaration of settings.declarations ?? []) {
111
- settings.signal.throwIfAborted();
112
- const { workflowId, schedule } = declaration;
113
- if (schedule === undefined)
114
- continue;
115
- let progress = journal.entries.get(workflowId);
116
- if (progress === undefined)
117
- throw new Error("missing-schedule-state");
118
- if (progress.pending !== undefined) {
119
- progress = await pending(settings, { workflowId, progress });
120
- journal.entries.set(workflowId, progress);
121
- await journal.save();
122
- }
123
- if (now < progress.nextAt)
124
- continue;
125
- const runId = await active(settings, progress);
126
- const planned = runId === undefined
127
- ? { kind: "run", input: schedule.input }
128
- : { kind: "skip", runId };
129
- const elapsed = Math.floor((now - progress.nextAt) / (schedule.everySeconds * 1000)) + 1;
130
- progress = {
131
- ...progress,
132
- lastSlot: progress.lastSlot + elapsed,
133
- nextAt: progress.nextAt + elapsed * schedule.everySeconds * 1000,
134
- pending: planned,
135
- };
136
- journal.entries.set(workflowId, progress);
137
- await journal.save();
138
- journal.entries.set(workflowId, await pending(settings, { workflowId, progress }));
139
- await journal.save();
140
- }
171
+ for (const declaration of settings.declarations ?? [])
172
+ await advance({ ...settings, journal, now }, declaration);
141
173
  }
142
174
  async function initialized(settings) {
143
175
  const journal = await scheduleJournal(join(settings.directory, "state"));
@@ -150,36 +182,57 @@ async function initialized(settings) {
150
182
  if (prior?.everySeconds === schedule.everySeconds)
151
183
  continue;
152
184
  journal.entries.set(workflowId, {
153
- ...prior,
185
+ ...(prior ?? {
186
+ lastSlot: 0,
187
+ state: "active",
188
+ failuresInRow: 0,
189
+ failedRunIds: [],
190
+ }),
154
191
  everySeconds: schedule.everySeconds,
155
- lastSlot: prior?.lastSlot ?? 0,
156
192
  nextAt: now + schedule.everySeconds * 1000,
157
193
  });
158
194
  }
159
- await journal.save();
195
+ if (settings.declarations?.some((entry) => entry.schedule !== undefined))
196
+ await journal.save();
160
197
  return journal;
161
198
  }
162
199
  export async function workflowSchedules(settings) {
163
- if (!(settings.declarations ?? []).some((entry) => entry.schedule !== undefined))
164
- return { stop: () => Promise.resolve() };
200
+ const declarations = settings.declarations ?? [];
165
201
  const journal = await initialized(settings);
166
202
  const stopping = new AbortController();
167
203
  const stopped = () => stopping.signal.aborted;
204
+ const context = {
205
+ ...settings,
206
+ signal: stopping.signal,
207
+ nextObservations: new Map(),
208
+ observationClock: settings.scheduleObservationClock ?? (() => performance.now()),
209
+ };
210
+ const control = scheduleControl({
211
+ journal,
212
+ declarations,
213
+ clock: settings.scheduleClock ?? Date.now,
214
+ signal: stopping.signal,
215
+ recoverPending: (entry) => pending(context, entry),
216
+ tick: () => tick(context, journal),
217
+ });
168
218
  const running = (async () => {
169
219
  while (!stopped()) {
170
220
  await delay(250, undefined, { signal: stopping.signal }).catch(() => undefined);
171
221
  if (stopped())
172
222
  return;
173
- await tick({ ...settings, signal: stopping.signal }, journal);
223
+ await control.tick();
174
224
  }
175
225
  })().catch((error) => {
176
226
  if (!stopped())
177
227
  process.stderr.write(`Schedules stopped: ${String(error)}\n`);
228
+ stopping.abort();
178
229
  });
179
230
  return {
231
+ request: control.request,
180
232
  stop: async () => {
181
233
  stopping.abort();
182
234
  await running;
235
+ await control.drain();
183
236
  },
184
237
  };
185
238
  }
@@ -0,0 +1,9 @@
1
+ export declare function recordedProcessDirectory(processId: number): Promise<string | undefined>;
2
+ interface StopRequest {
3
+ readonly directory: string;
4
+ readonly folder: string;
5
+ readonly signal: AbortSignal;
6
+ readonly stopMilliseconds?: number;
7
+ }
8
+ export declare function stopTreeProcesses(request: StopRequest): Promise<boolean>;
9
+ export {};