cloving 1.1.0 → 1.3.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 (568) hide show
  1. package/README.md +584 -144
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/agent-harness-shell.d.ts +12 -0
  16. package/dist/src/agent-harness-shell.js +90 -0
  17. package/dist/src/agent-harness-versions.d.ts +8 -0
  18. package/dist/src/agent-harness-versions.js +49 -0
  19. package/dist/src/agent-harnesses.d.ts +4 -0
  20. package/dist/src/agent-harnesses.js +13 -0
  21. package/dist/src/authority/commands.d.ts +2 -0
  22. package/dist/src/authority/commands.js +49 -8
  23. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  24. package/dist/src/authority/dispatch-decision.js +7 -4
  25. package/dist/src/authority/events.js +2 -2
  26. package/dist/src/authority/gate-reduction.d.ts +1 -0
  27. package/dist/src/authority/gate-reduction.js +18 -3
  28. package/dist/src/authority/gates.d.ts +2 -1
  29. package/dist/src/authority/gates.js +5 -1
  30. package/dist/src/authority/handoff-chain.d.ts +24 -0
  31. package/dist/src/authority/handoff-chain.js +46 -0
  32. package/dist/src/authority/operations.js +1 -1
  33. package/dist/src/authority/reconciliation.d.ts +1 -0
  34. package/dist/src/authority/reconciliation.js +18 -11
  35. package/dist/src/authority/reduction.d.ts +1 -1
  36. package/dist/src/authority/reduction.js +6 -1
  37. package/dist/src/authority/status-input.d.ts +1 -1
  38. package/dist/src/authority/status.d.ts +1 -0
  39. package/dist/src/authority/status.js +27 -3
  40. package/dist/src/authority/transitions.d.ts +5 -5
  41. package/dist/src/authority/transitions.js +9 -0
  42. package/dist/src/broker/actor/authority-delivery.js +1 -0
  43. package/dist/src/broker/actor/authority-queries.d.ts +11 -1
  44. package/dist/src/broker/actor/authority-queries.js +67 -3
  45. package/dist/src/broker/actor/authority-receipts.js +11 -1
  46. package/dist/src/broker/actor/authority-session.js +2 -2
  47. package/dist/src/broker/actor/authority-settings.js +4 -0
  48. package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
  49. package/dist/src/broker/actor/delivery-intents.js +4 -4
  50. package/dist/src/broker/actor/effect-delivery.js +13 -1
  51. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  52. package/dist/src/broker/actor/effect-queries.js +7 -0
  53. package/dist/src/broker/actor/pin-check.js +1 -1
  54. package/dist/src/broker/actor/stop-plan.js +1 -1
  55. package/dist/src/broker/actor/turn-state.js +1 -1
  56. package/dist/src/broker/authority-admission.js +26 -5
  57. package/dist/src/broker/authority-restore.js +1 -0
  58. package/dist/src/broker/decision-restore.js +4 -4
  59. package/dist/src/broker/socket-address.d.ts +3 -1
  60. package/dist/src/broker/socket-address.js +2 -2
  61. package/dist/src/cli/arguments.d.ts +11 -13
  62. package/dist/src/cli/arguments.js +37 -107
  63. package/dist/src/cli/command-effects.d.ts +7 -0
  64. package/dist/src/cli/command-effects.js +39 -0
  65. package/dist/src/cli/commands.js +11 -4
  66. package/dist/src/cli/config-arguments.d.ts +11 -0
  67. package/dist/src/cli/config-arguments.js +59 -0
  68. package/dist/src/cli/config-command.d.ts +2 -0
  69. package/dist/src/cli/config-command.js +105 -0
  70. package/dist/src/cli/config-file.d.ts +3 -0
  71. package/dist/src/cli/config-file.js +50 -0
  72. package/dist/src/cli/config-lock.d.ts +7 -0
  73. package/dist/src/cli/config-lock.js +61 -0
  74. package/dist/src/cli/config-notice.d.ts +5 -0
  75. package/dist/src/cli/config-notice.js +46 -0
  76. package/dist/src/cli/doctor-github.d.ts +9 -0
  77. package/dist/src/cli/doctor-github.js +138 -0
  78. package/dist/src/cli/doctor-harness.d.ts +13 -0
  79. package/dist/src/cli/doctor-harness.js +242 -0
  80. package/dist/src/cli/doctor-local.d.ts +18 -0
  81. package/dist/src/cli/doctor-local.js +77 -0
  82. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  83. package/dist/src/cli/doctor-runtime.js +176 -0
  84. package/dist/src/cli/doctor-service.d.ts +1 -0
  85. package/dist/src/cli/doctor-service.js +11 -0
  86. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  87. package/dist/src/cli/doctor-workflows.js +45 -0
  88. package/dist/src/cli/doctor.d.ts +15 -0
  89. package/dist/src/cli/doctor.js +190 -0
  90. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  91. package/dist/src/cli/github-ci-progress.js +83 -0
  92. package/dist/src/cli/github-retry.d.ts +6 -0
  93. package/dist/src/cli/github-retry.js +47 -0
  94. package/dist/src/cli/harness-probes.d.ts +22 -0
  95. package/dist/src/cli/harness-probes.js +183 -0
  96. package/dist/src/cli/main.d.ts +7 -1
  97. package/dist/src/cli/main.js +39 -61
  98. package/dist/src/cli/phone-arguments.d.ts +14 -0
  99. package/dist/src/cli/phone-arguments.js +37 -0
  100. package/dist/src/cli/phone-client.d.ts +2 -0
  101. package/dist/src/cli/phone-client.js +32 -0
  102. package/dist/src/cli/phone-command.d.ts +13 -0
  103. package/dist/src/cli/phone-command.js +101 -0
  104. package/dist/src/cli/probe-command.d.ts +36 -0
  105. package/dist/src/cli/probe-command.js +59 -0
  106. package/dist/src/cli/project-settings.d.ts +4 -0
  107. package/dist/src/cli/project-settings.js +33 -0
  108. package/dist/src/cli/render.d.ts +3 -1
  109. package/dist/src/cli/render.js +102 -39
  110. package/dist/src/cli/report-github.d.ts +18 -0
  111. package/dist/src/cli/report-github.js +200 -0
  112. package/dist/src/cli/report.d.ts +17 -0
  113. package/dist/src/cli/report.js +192 -0
  114. package/dist/src/cli/repository-arguments.d.ts +5 -0
  115. package/dist/src/cli/repository-arguments.js +34 -0
  116. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  117. package/dist/src/cli/runtime-arguments.js +15 -0
  118. package/dist/src/cli/runtime-directory.d.ts +6 -2
  119. package/dist/src/cli/runtime-directory.js +72 -14
  120. package/dist/src/cli/toolchain.d.ts +2 -0
  121. package/dist/src/cli/toolchain.js +22 -2
  122. package/dist/src/cli/usage-render.d.ts +5 -0
  123. package/dist/src/cli/usage-render.js +40 -1
  124. package/dist/src/cli/usage.d.ts +3 -3
  125. package/dist/src/cli/usage.js +74 -45
  126. package/dist/src/cli/watch-actions.d.ts +2 -0
  127. package/dist/src/cli/watch-actions.js +4 -4
  128. package/dist/src/cli/watch-board-view.d.ts +12 -1
  129. package/dist/src/cli/watch-board-view.js +64 -12
  130. package/dist/src/cli/watch-board.d.ts +7 -1
  131. package/dist/src/cli/watch-board.js +61 -16
  132. package/dist/src/cli/watch-card-forms.js +2 -2
  133. package/dist/src/cli/watch-client.d.ts +1 -1
  134. package/dist/src/cli/watch-client.js +12 -3
  135. package/dist/src/cli/watch-header-view.d.ts +27 -0
  136. package/dist/src/cli/watch-header-view.js +116 -0
  137. package/dist/src/cli/watch-model.d.ts +10 -4
  138. package/dist/src/cli/watch-model.js +49 -59
  139. package/dist/src/cli/watch-page.js +67 -14
  140. package/dist/src/cli/watch-phases.js +3 -3
  141. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  142. package/dist/src/cli/watch-phone-client.js +84 -0
  143. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  144. package/dist/src/cli/watch-phone-view.js +113 -0
  145. package/dist/src/cli/watch-phone.d.ts +5 -0
  146. package/dist/src/cli/watch-phone.js +53 -0
  147. package/dist/src/cli/watch-pr-command.d.ts +5 -2
  148. package/dist/src/cli/watch-pr-command.js +41 -4
  149. package/dist/src/cli/watch-pr-identity.d.ts +14 -2
  150. package/dist/src/cli/watch-pr-identity.js +25 -0
  151. package/dist/src/cli/watch-pr-observer.d.ts +1 -0
  152. package/dist/src/cli/watch-pr-observer.js +48 -6
  153. package/dist/src/cli/watch-pull-request.d.ts +12 -0
  154. package/dist/src/cli/watch-pull-request.js +134 -0
  155. package/dist/src/cli/watch-reads.d.ts +7 -1
  156. package/dist/src/cli/watch-reads.js +42 -20
  157. package/dist/src/cli/watch-render.d.ts +23 -2
  158. package/dist/src/cli/watch-render.js +2 -1
  159. package/dist/src/cli/watch-server.js +56 -7
  160. package/dist/src/cli/watch-turn.d.ts +4 -1
  161. package/dist/src/cli/watch-turn.js +38 -2
  162. package/dist/src/cli/watch-usage.js +5 -1
  163. package/dist/src/cli/watch-view.d.ts +10 -17
  164. package/dist/src/cli/watch-view.js +33 -77
  165. package/dist/src/cli.js +106 -23
  166. package/dist/src/command-settings.d.ts +16 -0
  167. package/dist/src/command-settings.js +42 -0
  168. package/dist/src/configuration-change.d.ts +11 -0
  169. package/dist/src/configuration-change.js +62 -0
  170. package/dist/src/configuration-display.d.ts +21 -0
  171. package/dist/src/configuration-display.js +69 -0
  172. package/dist/src/configuration-schema.d.ts +49 -0
  173. package/dist/src/configuration-schema.js +159 -0
  174. package/dist/src/daemon/claude-turn.d.ts +20 -5
  175. package/dist/src/daemon/claude-turn.js +116 -53
  176. package/dist/src/daemon/claude-worker.d.ts +3 -5
  177. package/dist/src/daemon/claude-worker.js +64 -80
  178. package/dist/src/daemon/command-journal.d.ts +5 -0
  179. package/dist/src/daemon/command-journal.js +50 -0
  180. package/dist/src/daemon/command-process.d.ts +28 -0
  181. package/dist/src/daemon/command-process.js +164 -0
  182. package/dist/src/daemon/command-worker.d.ts +19 -0
  183. package/dist/src/daemon/command-worker.js +182 -0
  184. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  185. package/dist/src/daemon/cursor-stream.js +154 -0
  186. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  187. package/dist/src/daemon/daemon-adapters.js +102 -0
  188. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  189. package/dist/src/daemon/daemon-loops.js +39 -0
  190. package/dist/src/daemon/daemon.d.ts +3 -30
  191. package/dist/src/daemon/daemon.js +132 -110
  192. package/dist/src/daemon/declared-input.d.ts +3 -0
  193. package/dist/src/daemon/declared-input.js +9 -0
  194. package/dist/src/daemon/delivery-router.js +7 -1
  195. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  196. package/dist/src/daemon/gemini-stream.js +129 -0
  197. package/dist/src/daemon/github-calls.d.ts +4 -0
  198. package/dist/src/daemon/github-calls.js +16 -7
  199. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  200. package/dist/src/daemon/github-ci-rerun.js +92 -0
  201. package/dist/src/daemon/github-ci.d.ts +6 -0
  202. package/dist/src/daemon/github-ci.js +251 -0
  203. package/dist/src/daemon/github-merge-call.d.ts +16 -0
  204. package/dist/src/daemon/github-merge-call.js +73 -0
  205. package/dist/src/daemon/github-merge.d.ts +3 -5
  206. package/dist/src/daemon/github-merge.js +59 -98
  207. package/dist/src/daemon/github-methods.d.ts +28 -0
  208. package/dist/src/daemon/github-methods.js +90 -16
  209. package/dist/src/daemon/github-operation.d.ts +3 -0
  210. package/dist/src/daemon/github-retry.d.ts +6 -0
  211. package/dist/src/daemon/github-retry.js +13 -0
  212. package/dist/src/daemon/github-ticket-status.js +27 -1
  213. package/dist/src/daemon/github-worker.js +2 -1
  214. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  215. package/dist/src/daemon/handoff-worker.js +232 -0
  216. package/dist/src/daemon/issue-queue.d.ts +2 -0
  217. package/dist/src/daemon/issue-queue.js +92 -63
  218. package/dist/src/daemon/notify-journal.d.ts +18 -0
  219. package/dist/src/daemon/notify-journal.js +108 -0
  220. package/dist/src/daemon/notify-message.js +2 -1
  221. package/dist/src/daemon/notify.js +177 -37
  222. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  223. package/dist/src/daemon/opencode-stream.js +87 -0
  224. package/dist/src/daemon/queue-status.d.ts +4 -0
  225. package/dist/src/daemon/queue-status.js +38 -0
  226. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  227. package/dist/src/daemon/retry-worktree.js +139 -0
  228. package/dist/src/daemon/retrying-turn.d.ts +5 -0
  229. package/dist/src/daemon/retrying-turn.js +145 -21
  230. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  231. package/dist/src/daemon/schedule-journal.js +57 -0
  232. package/dist/src/daemon/text-output.d.ts +18 -0
  233. package/dist/src/daemon/text-output.js +44 -0
  234. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  235. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  236. package/dist/src/daemon/ticket-registration.d.ts +10 -8
  237. package/dist/src/daemon/ticket-registration.js +146 -47
  238. package/dist/src/daemon/ticket-source.d.ts +4 -1
  239. package/dist/src/daemon/ticket-source.js +8 -2
  240. package/dist/src/daemon/turn-command.d.ts +10 -0
  241. package/dist/src/daemon/turn-command.js +33 -0
  242. package/dist/src/daemon/turn-report.d.ts +18 -0
  243. package/dist/src/daemon/turn-report.js +79 -0
  244. package/dist/src/daemon/work-tree.d.ts +2 -1
  245. package/dist/src/daemon/work-tree.js +15 -12
  246. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  247. package/dist/src/daemon/workflow-generations.js +57 -0
  248. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  249. package/dist/src/daemon/workflow-replay.js +58 -0
  250. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  251. package/dist/src/daemon/workflow-schedules.js +185 -0
  252. package/dist/src/decision-visibility.d.ts +2 -0
  253. package/dist/src/decision-visibility.js +10 -0
  254. package/dist/src/decision-wait.d.ts +1 -0
  255. package/dist/src/decision-wait.js +3 -0
  256. package/dist/src/delivery-backoff.d.ts +1 -0
  257. package/dist/src/delivery-backoff.js +3 -0
  258. package/dist/src/doctor-report.d.ts +24 -0
  259. package/dist/src/doctor-report.js +70 -0
  260. package/dist/src/execution-pin.d.ts +9 -0
  261. package/dist/src/execution-pin.js +86 -2
  262. package/dist/src/grok-result.d.ts +12 -0
  263. package/dist/src/grok-result.js +61 -0
  264. package/dist/src/harness-defaults.d.ts +35 -0
  265. package/dist/src/harness-defaults.js +121 -0
  266. package/dist/src/host/decision-resume.d.ts +35 -0
  267. package/dist/src/host/decision-resume.js +86 -0
  268. package/dist/src/host/gate-bridge.d.ts +48 -0
  269. package/dist/src/host/gate-bridge.js +124 -0
  270. package/dist/src/host/run-wait.d.ts +26 -0
  271. package/dist/src/host/run-wait.js +37 -0
  272. package/dist/src/host/start-delivery.d.ts +3 -2
  273. package/dist/src/host/start-delivery.js +11 -4
  274. package/dist/src/host/step-bridge-host.d.ts +6 -19
  275. package/dist/src/host/step-bridge-host.js +57 -55
  276. package/dist/src/host/world-reconciliation.d.ts +1 -0
  277. package/dist/src/host/world-reconciliation.js +3 -0
  278. package/dist/src/host/world-runs.js +5 -0
  279. package/dist/src/issue-identity.d.ts +6 -0
  280. package/dist/src/issue-identity.js +23 -0
  281. package/dist/src/merge-request.d.ts +19 -0
  282. package/dist/src/merge-request.js +32 -0
  283. package/dist/src/phone/canonical-json.d.ts +1 -0
  284. package/dist/src/phone/canonical-json.js +16 -0
  285. package/dist/src/phone/phone-link.d.ts +7 -0
  286. package/dist/src/phone/phone-link.js +21 -0
  287. package/dist/src/phone/qr-data.d.ts +8 -0
  288. package/dist/src/phone/qr-data.js +133 -0
  289. package/dist/src/phone/qr-matrix.d.ts +6 -0
  290. package/dist/src/phone/qr-matrix.js +175 -0
  291. package/dist/src/phone/qr-penalty.d.ts +3 -0
  292. package/dist/src/phone/qr-penalty.js +67 -0
  293. package/dist/src/phone/qr-picture.d.ts +5 -0
  294. package/dist/src/phone/qr-picture.js +24 -0
  295. package/dist/src/private-config.schema.json +263 -0
  296. package/dist/src/project-config.schema.json +65 -0
  297. package/dist/src/project-settings.d.ts +19 -0
  298. package/dist/src/project-settings.js +131 -0
  299. package/dist/src/relay/answer-check.d.ts +24 -0
  300. package/dist/src/relay/answer-check.js +145 -0
  301. package/dist/src/relay/answer-inbox.d.ts +15 -0
  302. package/dist/src/relay/answer-inbox.js +173 -0
  303. package/dist/src/relay/daemon-keys.d.ts +16 -0
  304. package/dist/src/relay/daemon-keys.js +75 -0
  305. package/dist/src/relay/decision-check.d.ts +3 -0
  306. package/dist/src/relay/decision-check.js +77 -0
  307. package/dist/src/relay/decision-close.d.ts +6 -0
  308. package/dist/src/relay/decision-close.js +72 -0
  309. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  310. package/dist/src/relay/decision-envelopes.js +93 -0
  311. package/dist/src/relay/decision-watch.d.ts +14 -0
  312. package/dist/src/relay/decision-watch.js +68 -0
  313. package/dist/src/relay/envelope-post.d.ts +8 -0
  314. package/dist/src/relay/envelope-post.js +71 -0
  315. package/dist/src/relay/envelope.d.ts +28 -0
  316. package/dist/src/relay/envelope.js +53 -0
  317. package/dist/src/relay/hpke.d.ts +25 -0
  318. package/dist/src/relay/hpke.js +108 -0
  319. package/dist/src/relay/pairing-checks.d.ts +42 -0
  320. package/dist/src/relay/pairing-checks.js +172 -0
  321. package/dist/src/relay/pairing-follow.d.ts +8 -0
  322. package/dist/src/relay/pairing-follow.js +95 -0
  323. package/dist/src/relay/pairing-session.d.ts +29 -0
  324. package/dist/src/relay/pairing-session.js +87 -0
  325. package/dist/src/relay/phone-delivery.d.ts +51 -0
  326. package/dist/src/relay/phone-delivery.js +139 -0
  327. package/dist/src/relay/phone-devices.d.ts +36 -0
  328. package/dist/src/relay/phone-devices.js +46 -0
  329. package/dist/src/relay/phone-inbox.d.ts +18 -0
  330. package/dist/src/relay/phone-inbox.js +17 -0
  331. package/dist/src/relay/phone-operations.d.ts +18 -0
  332. package/dist/src/relay/phone-operations.js +121 -0
  333. package/dist/src/relay/phone-outbox.d.ts +21 -0
  334. package/dist/src/relay/phone-outbox.js +25 -0
  335. package/dist/src/relay/phone-socket.d.ts +6 -0
  336. package/dist/src/relay/phone-socket.js +63 -0
  337. package/dist/src/relay/relay-control.d.ts +7 -0
  338. package/dist/src/relay/relay-control.js +24 -0
  339. package/dist/src/relay/relay-files.d.ts +2 -0
  340. package/dist/src/relay/relay-files.js +23 -0
  341. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  342. package/dist/src/relay/relay-heartbeat.js +81 -0
  343. package/dist/src/relay/relay-http.d.ts +14 -0
  344. package/dist/src/relay/relay-http.js +63 -0
  345. package/dist/src/relay/relay-registration.d.ts +15 -0
  346. package/dist/src/relay/relay-registration.js +63 -0
  347. package/dist/src/relay/relay-service.d.ts +25 -0
  348. package/dist/src/relay/relay-service.js +216 -0
  349. package/dist/src/relay/relay-store.d.ts +48 -0
  350. package/dist/src/relay/relay-store.js +131 -0
  351. package/dist/src/relay/sealed-post.d.ts +25 -0
  352. package/dist/src/relay/sealed-post.js +52 -0
  353. package/dist/src/relay.d.ts +1 -0
  354. package/dist/src/relay.js +8 -0
  355. package/dist/src/report-statistics.d.ts +50 -0
  356. package/dist/src/report-statistics.js +70 -0
  357. package/dist/src/report.d.ts +171 -0
  358. package/dist/src/report.js +119 -0
  359. package/dist/src/repository-identity.d.ts +4 -0
  360. package/dist/src/repository-identity.js +4 -0
  361. package/dist/src/review-subject.d.ts +41 -0
  362. package/dist/src/review-subject.js +91 -0
  363. package/dist/src/run-wait.d.ts +23 -0
  364. package/dist/src/run-wait.js +20 -0
  365. package/dist/src/service/active-tickets.d.ts +4 -0
  366. package/dist/src/service/active-tickets.js +49 -0
  367. package/dist/src/service/command-effects.d.ts +4 -0
  368. package/dist/src/service/command-effects.js +16 -0
  369. package/dist/src/service/decision-handler.d.ts +4 -0
  370. package/dist/src/service/decision-handler.js +39 -4
  371. package/dist/src/service/gateway.js +18 -3
  372. package/dist/src/service/queue-runs.d.ts +3 -0
  373. package/dist/src/service/queue-runs.js +39 -0
  374. package/dist/src/service/registry.d.ts +22 -3
  375. package/dist/src/service/registry.js +51 -8
  376. package/dist/src/service/replies.d.ts +10 -0
  377. package/dist/src/service/replies.js +12 -0
  378. package/dist/src/service/run-handlers.js +45 -54
  379. package/dist/src/service/run-metadata.d.ts +8 -0
  380. package/dist/src/service/run-metadata.js +53 -0
  381. package/dist/src/service/run-waits.d.ts +3 -0
  382. package/dist/src/service/run-waits.js +41 -0
  383. package/dist/src/service/service.d.ts +21 -2
  384. package/dist/src/service/service.js +23 -5
  385. package/dist/src/service/submission-handler.js +70 -19
  386. package/dist/src/service/worker-port.d.ts +1 -0
  387. package/dist/src/service/worker-totals.js +10 -1
  388. package/dist/src/step-bridge.d.ts +32 -0
  389. package/dist/src/steps/decision-gate.d.ts +2 -1
  390. package/dist/src/steps/decision-gate.js +7 -0
  391. package/dist/src/steps/handoff.d.ts +2 -0
  392. package/dist/src/steps/handoff.js +13 -0
  393. package/dist/src/steps/merge-by-person.d.ts +2 -0
  394. package/dist/src/steps/merge-by-person.js +18 -0
  395. package/dist/src/steps/merge-when-green.d.ts +2 -0
  396. package/dist/src/steps/merge-when-green.js +62 -0
  397. package/dist/src/steps/review-by-agent.d.ts +5 -0
  398. package/dist/src/steps/review-by-agent.js +124 -0
  399. package/dist/src/steps/review-by-person.d.ts +4 -0
  400. package/dist/src/steps/review-by-person.js +16 -0
  401. package/dist/src/steps/review-subject.d.ts +2 -0
  402. package/dist/src/steps/review-subject.js +11 -0
  403. package/dist/src/steps/run-command.d.ts +2 -0
  404. package/dist/src/steps/run-command.js +15 -0
  405. package/dist/src/steps/sleep.d.ts +3 -0
  406. package/dist/src/steps/sleep.js +19 -0
  407. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  408. package/dist/src/steps/wait-for-decision.js +71 -0
  409. package/dist/src/steps/wait-for-run.d.ts +5 -0
  410. package/dist/src/steps/wait-for-run.js +9 -0
  411. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  412. package/dist/src/storage/decision-snapshots.js +7 -1
  413. package/dist/src/submission.d.ts +4 -0
  414. package/dist/src/submission.js +6 -2
  415. package/dist/src/testing.d.ts +29 -0
  416. package/dist/src/testing.js +264 -0
  417. package/dist/src/ticket-dependencies.d.ts +1 -0
  418. package/dist/src/ticket-dependencies.js +15 -0
  419. package/dist/src/ticket-status-stream.d.ts +9 -0
  420. package/dist/src/ticket-status-stream.js +94 -0
  421. package/dist/src/ticket-status.js +7 -4
  422. package/dist/src/token-prices.d.ts +14 -4
  423. package/dist/src/token-prices.js +56 -11
  424. package/dist/src/turn-profile.d.ts +1 -0
  425. package/dist/src/turn-profile.js +8 -1
  426. package/dist/src/worker-usage.d.ts +25 -0
  427. package/dist/src/worker-usage.js +58 -1
  428. package/dist/src/workflow-admission.d.ts +6 -0
  429. package/dist/src/workflow-candidate.d.ts +7 -2
  430. package/dist/src/workflow-candidate.js +48 -5
  431. package/dist/src/workflow-contracts.d.ts +2 -0
  432. package/dist/src/workflow-contracts.js +8 -3
  433. package/dist/src/workflow-declaration.d.ts +31 -2
  434. package/dist/src/workflow-declaration.js +140 -16
  435. package/dist/src/workflow-discovery.d.ts +19 -0
  436. package/dist/src/workflow-discovery.js +36 -0
  437. package/dist/src/workflow-refusals.d.ts +6 -0
  438. package/dist/src/workflow-refusals.js +42 -0
  439. package/dist/src/workflow-schedule.d.ts +22 -0
  440. package/dist/src/workflow-schedule.js +53 -0
  441. package/dist/src/workflows.d.ts +12 -1
  442. package/dist/src/workflows.js +9 -0
  443. package/dist/tools/admit-workflow.d.ts +14 -0
  444. package/dist/tools/admit-workflow.js +107 -0
  445. package/dist/tools/doctor-adoption.d.ts +1 -0
  446. package/dist/tools/doctor-adoption.js +11 -0
  447. package/dist/tools/project-configuration.d.ts +4 -0
  448. package/dist/tools/project-configuration.js +47 -0
  449. package/dist/tools/self-host-processes.d.ts +1 -0
  450. package/dist/tools/self-host-processes.js +33 -22
  451. package/dist/tools/self-host-project.d.ts +21 -0
  452. package/dist/tools/self-host-project.js +224 -0
  453. package/dist/tools/self-host-runtime.d.ts +16 -0
  454. package/dist/tools/self-host-runtime.js +60 -0
  455. package/dist/tools/self-host-workflows.d.ts +1 -0
  456. package/dist/tools/self-host-workflows.js +36 -1
  457. package/dist/tools/self-host.js +106 -135
  458. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  459. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  460. package/dist/tools/workflow-bundles.d.ts +20 -0
  461. package/dist/tools/workflow-bundles.js +173 -0
  462. package/dist/tools/workflow-candidate-counts.d.ts +12 -0
  463. package/dist/tools/workflow-candidate-counts.js +266 -0
  464. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  465. package/dist/tools/workflow-candidate-fields.js +24 -0
  466. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  467. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  468. package/dist/tools/workflow-candidate-program.d.ts +13 -0
  469. package/dist/tools/workflow-candidate-program.js +106 -0
  470. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  471. package/dist/tools/workflow-candidate-source.js +169 -0
  472. package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
  473. package/dist/tools/workflow-candidate-syntax.js +263 -0
  474. package/dist/tools/workflow-command.d.ts +1 -0
  475. package/dist/tools/workflow-command.js +143 -0
  476. package/dist/tools/workflow-folder-capture.d.ts +18 -0
  477. package/dist/tools/workflow-folder-capture.js +261 -0
  478. package/dist/tools/workflow-folders.d.ts +49 -0
  479. package/dist/tools/workflow-folders.js +203 -0
  480. package/dist/tools/workflow-source-effects.d.ts +10 -0
  481. package/dist/tools/workflow-source-effects.js +213 -0
  482. package/dist/tools/workflow-test-hook.d.ts +7 -0
  483. package/dist/tools/workflow-test-hook.js +16 -0
  484. package/dist/tools/workflow-test-loader.d.ts +1 -0
  485. package/dist/tools/workflow-test-loader.js +10 -0
  486. package/dist/workflows/develop-prd.js +71 -3
  487. package/dist/workflows/develop-ticket.js +6 -1
  488. package/dist/workflows/ticket-prompts.js +17 -3
  489. package/package.json +66 -6
  490. package/templates/develop/README.md +78 -0
  491. package/templates/develop/develop/accept.ts +11 -0
  492. package/templates/develop/develop/flow-tests.ts +357 -0
  493. package/templates/develop/develop/local.ts +40 -0
  494. package/templates/develop/develop/option-tests.ts +174 -0
  495. package/templates/develop/develop/partial-choice.ts +29 -0
  496. package/templates/develop/develop/partial.ts +28 -0
  497. package/templates/develop/develop/pull.ts +152 -0
  498. package/templates/develop/develop/queue-partial.ts +39 -0
  499. package/templates/develop/develop/refusal-tests.ts +174 -0
  500. package/templates/develop/develop/report.ts +156 -0
  501. package/templates/develop/develop/round.ts +40 -0
  502. package/templates/develop/develop/scenarios.ts +87 -0
  503. package/templates/develop/develop/turn.ts +67 -0
  504. package/templates/develop/develop.declaration.json +24 -0
  505. package/templates/develop/develop.test.ts +287 -0
  506. package/templates/develop/develop.ts +30 -0
  507. package/templates/develop/template.json +153 -0
  508. package/dist/src/chats/analysis-batches.d.ts +0 -24
  509. package/dist/src/chats/analysis-batches.js +0 -83
  510. package/dist/src/chats/analysis-contract.d.ts +0 -80
  511. package/dist/src/chats/analysis-contract.js +0 -16
  512. package/dist/src/chats/analysis-data.d.ts +0 -3
  513. package/dist/src/chats/analysis-data.js +0 -85
  514. package/dist/src/chats/analysis-input.d.ts +0 -12
  515. package/dist/src/chats/analysis-input.js +0 -83
  516. package/dist/src/chats/analysis-links.d.ts +0 -2
  517. package/dist/src/chats/analysis-links.js +0 -25
  518. package/dist/src/chats/analysis-prompt.d.ts +0 -10
  519. package/dist/src/chats/analysis-prompt.js +0 -16
  520. package/dist/src/chats/analysis-proposal.d.ts +0 -2
  521. package/dist/src/chats/analysis-proposal.js +0 -32
  522. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  523. package/dist/src/chats/analysis-provenance.js +0 -99
  524. package/dist/src/chats/analysis-shape.d.ts +0 -3
  525. package/dist/src/chats/analysis-shape.js +0 -228
  526. package/dist/src/chats/analysis.d.ts +0 -3
  527. package/dist/src/chats/analysis.js +0 -42
  528. package/dist/src/chats/corpus-input.d.ts +0 -5
  529. package/dist/src/chats/corpus-input.js +0 -288
  530. package/dist/src/chats/destination.d.ts +0 -4
  531. package/dist/src/chats/destination.js +0 -96
  532. package/dist/src/chats/import.d.ts +0 -15
  533. package/dist/src/chats/import.js +0 -243
  534. package/dist/src/chats/input-file.d.ts +0 -3
  535. package/dist/src/chats/input-file.js +0 -32
  536. package/dist/src/chats/normalize.d.ts +0 -29
  537. package/dist/src/chats/normalize.js +0 -155
  538. package/dist/src/chats/previous-import.d.ts +0 -5
  539. package/dist/src/chats/previous-import.js +0 -34
  540. package/dist/src/chats/reader.d.ts +0 -21
  541. package/dist/src/chats/reader.js +0 -118
  542. package/dist/src/chats/redact-import.d.ts +0 -14
  543. package/dist/src/chats/redact-import.js +0 -141
  544. package/dist/src/chats/redaction.d.ts +0 -41
  545. package/dist/src/chats/redaction.js +0 -161
  546. package/dist/src/chats/revision-input.d.ts +0 -3
  547. package/dist/src/chats/revision-input.js +0 -180
  548. package/dist/src/chats/revision.d.ts +0 -48
  549. package/dist/src/chats/revision.js +0 -94
  550. package/dist/src/chats/selection.d.ts +0 -25
  551. package/dist/src/chats/selection.js +0 -109
  552. package/dist/src/chats/source.d.ts +0 -23
  553. package/dist/src/chats/source.js +0 -135
  554. package/dist/src/chats/structure.d.ts +0 -57
  555. package/dist/src/chats/structure.js +0 -216
  556. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  557. package/dist/src/daemon/analysis-launch.js +0 -81
  558. package/dist/src/daemon/analysis-token.d.ts +0 -6
  559. package/dist/src/daemon/analysis-token.js +0 -88
  560. package/dist/src/daemon/analysis-worker.d.ts +0 -22
  561. package/dist/src/daemon/analysis-worker.js +0 -219
  562. package/dist/src/daemon/chats-files.d.ts +0 -15
  563. package/dist/src/daemon/chats-files.js +0 -113
  564. package/dist/src/daemon/chats-worker.d.ts +0 -12
  565. package/dist/src/daemon/chats-worker.js +0 -200
  566. package/dist/workflows/analyze-chats.d.ts +0 -10
  567. package/dist/workflows/analyze-chats.declaration.json +0 -9
  568. package/dist/workflows/analyze-chats.js +0 -73
@@ -0,0 +1,121 @@
1
+ export const defaultCommand = [
2
+ "claude",
3
+ "-p",
4
+ "--output-format",
5
+ "stream-json",
6
+ "--verbose",
7
+ "--permission-mode",
8
+ "acceptEdits",
9
+ "--allowedTools",
10
+ "Bash,Read,Edit,Write,Glob,Grep,WebSearch,WebFetch",
11
+ "--max-budget-usd",
12
+ "5",
13
+ ];
14
+ export const defaultCodexCommand = [
15
+ "codex",
16
+ "exec",
17
+ "--json",
18
+ "--dangerously-bypass-approvals-and-sandbox",
19
+ "--skip-git-repo-check",
20
+ "-",
21
+ ];
22
+ export const defaultGeminiCommand = [
23
+ "gemini",
24
+ "--output-format",
25
+ "stream-json",
26
+ "--approval-mode",
27
+ "yolo",
28
+ ];
29
+ export const defaultCursorCommand = [
30
+ "cursor-agent",
31
+ "-p",
32
+ "--output-format",
33
+ "stream-json",
34
+ "--force",
35
+ ];
36
+ export const defaultOpencodeCommand = ["opencode", "run", "--format", "json"];
37
+ export const defaultGrokCommand = [
38
+ "grok",
39
+ "--output-format",
40
+ "streaming-messages-json",
41
+ "--always-approve",
42
+ "-p",
43
+ ];
44
+ const defaultCommands = {
45
+ claude: defaultCommand,
46
+ codex: defaultCodexCommand,
47
+ gemini: defaultGeminiCommand,
48
+ grok: defaultGrokCommand,
49
+ opencode: defaultOpencodeCommand,
50
+ "cursor-agent": defaultCursorCommand,
51
+ };
52
+ function matchingHarness(settings, name) {
53
+ return (settings.harness?.name ?? "claude") === name
54
+ ? (settings.harness ?? {})
55
+ : {};
56
+ }
57
+ function nativeCommand(settings, name) {
58
+ const command = settings.workerCommands?.[name];
59
+ if (command !== undefined)
60
+ return command;
61
+ if (name === (settings.worker ?? "claude") && settings.command !== undefined)
62
+ return settings.command;
63
+ const saved = matchingHarness(settings, name);
64
+ if (saved.command !== undefined)
65
+ return saved.command;
66
+ const defaults = harnessDefaults(name).command;
67
+ return [saved.path ?? name, ...defaults.slice(1)];
68
+ }
69
+ export function isTurnCommand(value) {
70
+ if (!Array.isArray(value))
71
+ return false;
72
+ const program = value[0];
73
+ return (typeof program === "string" &&
74
+ program !== "" &&
75
+ program !== "{prompt}" &&
76
+ value.every((part) => typeof part === "string" && !part.includes("\u0000")) &&
77
+ value.filter((part) => part === "{prompt}").length <= 1);
78
+ }
79
+ export function harnessDefaults(value) {
80
+ const name = typeof value === "string" && nativeHarness(value) ? value : "claude";
81
+ const variable = {
82
+ claude: "CLOVING_CLAUDE_COMMAND",
83
+ codex: "CLOVING_CODEX_COMMAND",
84
+ gemini: "CLOVING_GEMINI_COMMAND",
85
+ grok: "CLOVING_GROK_COMMAND",
86
+ opencode: "CLOVING_OPENCODE_COMMAND",
87
+ "cursor-agent": undefined,
88
+ }[name];
89
+ return {
90
+ command: defaultCommands[name],
91
+ ...(variable === undefined ? {} : { variable }),
92
+ };
93
+ }
94
+ function selectedCommand(settings, name) {
95
+ if (nativeHarness(name))
96
+ return { command: nativeCommand(settings, name) };
97
+ const saved = matchingHarness(settings, name);
98
+ if (saved.turn === undefined)
99
+ throw new Error(`harness-no-worker: ${name}`);
100
+ if (!isTurnCommand(saved.turn))
101
+ throw new Error("invalid-setting: harness.turn");
102
+ return {
103
+ command: saved.command ?? [
104
+ saved.path ?? saved.turn[0] ?? "",
105
+ ...saved.turn.slice(1),
106
+ ],
107
+ output: "text",
108
+ };
109
+ }
110
+ export function turnHarness(settings, profile = {}) {
111
+ const name = profile.harness ?? settings.worker ?? settings.harness?.name ?? "claude";
112
+ const saved = matchingHarness(settings, name);
113
+ return {
114
+ worker: name,
115
+ ...selectedCommand(settings, name),
116
+ ...(saved.kind === "shell" ? { shell: settings.shell ?? "/bin/sh" } : {}),
117
+ };
118
+ }
119
+ export function nativeHarness(name) {
120
+ return Object.hasOwn(defaultCommands, name);
121
+ }
@@ -0,0 +1,35 @@
1
+ interface RunIntent {
2
+ readonly runId: string;
3
+ readonly gateId?: string;
4
+ readonly decision?: string;
5
+ readonly answer?: string | null;
6
+ }
7
+ interface ResumeParts {
8
+ readonly runs: () => Promise<readonly {
9
+ readonly operationId: string | null;
10
+ readonly receipt: string;
11
+ }[]>;
12
+ readonly document: (digest: string) => Promise<string | undefined>;
13
+ }
14
+ export declare function reconciledDecision(parts: ResumeParts, intent: RunIntent): Promise<{
15
+ readonly kind: "accepted";
16
+ readonly receipt: string;
17
+ } | {
18
+ readonly kind: "absent";
19
+ }>;
20
+ export declare function deliveredDecision(parts: ResumeParts, request: {
21
+ readonly intent: RunIntent;
22
+ readonly signal: AbortSignal | undefined;
23
+ }): Promise<{
24
+ readonly receipt: string;
25
+ }>;
26
+ export declare function stoppedDecision(parts: ResumeParts & {
27
+ readonly cancel: (receipt: string) => Promise<string>;
28
+ }, intent: RunIntent): Promise<{
29
+ readonly kind: "stopped";
30
+ readonly receipt: string;
31
+ } | {
32
+ readonly kind: "unknown";
33
+ readonly evidence: string;
34
+ }>;
35
+ export {};
@@ -0,0 +1,86 @@
1
+ import { resumeHook } from "workflow/api";
2
+ import { getWorld } from "workflow/runtime";
3
+ import { setTimeout as delay } from "node:timers/promises";
4
+ import { decisionToken } from "../decision-wait.js";
5
+ import { namesRunIntent } from "../authority/operations.js";
6
+ async function runSubject(receipt, token) {
7
+ const world = await getWorld();
8
+ let page = await world.events.list({
9
+ runId: receipt,
10
+ resolveData: "none",
11
+ pagination: { limit: 1000, sortOrder: "asc" },
12
+ });
13
+ const events = [...page.data];
14
+ while (page.hasMore && page.cursor !== null) {
15
+ page = await world.events.list({
16
+ runId: receipt,
17
+ resolveData: "none",
18
+ pagination: { limit: 1000, sortOrder: "asc", cursor: page.cursor },
19
+ });
20
+ events.push(...page.data);
21
+ }
22
+ const created = events.find((event) => event.eventType === "hook_created" && event.eventData.token === token);
23
+ const hookId = created?.correlationId;
24
+ return {
25
+ runId: receipt,
26
+ token,
27
+ hookId,
28
+ received: hookId !== undefined &&
29
+ events.some((event) => event.eventType === "hook_received" && event.correlationId === hookId),
30
+ };
31
+ }
32
+ async function subject(parts, intent) {
33
+ if (intent.gateId === undefined)
34
+ throw new Error("missing-decision-gate");
35
+ const token = decisionToken(intent.runId, intent.gateId);
36
+ const runs = (await parts.runs()).filter((run) => namesRunIntent(run.operationId ?? "", intent.runId));
37
+ const latest = runs.at(-1);
38
+ if (latest === undefined)
39
+ throw new Error("missing-decision-run");
40
+ const matches = [];
41
+ for (const run of runs) {
42
+ const found = await runSubject(run.receipt, token);
43
+ if (found.hookId !== undefined)
44
+ matches.push(found);
45
+ }
46
+ if (matches.length > 1)
47
+ throw new Error("conflicting-decision-hooks");
48
+ return (matches[0] ?? {
49
+ runId: latest.receipt,
50
+ token,
51
+ hookId: undefined,
52
+ received: false,
53
+ });
54
+ }
55
+ export async function reconciledDecision(parts, intent) {
56
+ const found = await subject(parts, intent);
57
+ return found.received
58
+ ? { kind: "accepted", receipt: found.runId }
59
+ : { kind: "absent" };
60
+ }
61
+ export async function deliveredDecision(parts, request) {
62
+ const { intent, signal } = request;
63
+ let found = await subject(parts, intent);
64
+ while (!found.received && found.hookId === undefined) {
65
+ await delay(20, undefined, signal === undefined ? {} : { signal });
66
+ found = await subject(parts, intent);
67
+ }
68
+ if (found.received)
69
+ return { receipt: found.runId };
70
+ if (intent.decision === undefined)
71
+ throw new Error("missing-decision");
72
+ const answer = intent.answer === undefined || intent.answer === null
73
+ ? null
74
+ : await parts.document(intent.answer);
75
+ if (answer === undefined)
76
+ throw new Error("missing-decision-answer");
77
+ await resumeHook(found.token, { decision: intent.decision, answer });
78
+ return { receipt: found.runId };
79
+ }
80
+ export async function stoppedDecision(parts, intent) {
81
+ const found = await subject(parts, intent);
82
+ const status = await parts.cancel(found.runId);
83
+ return ["cancelled", "completed", "failed"].includes(status)
84
+ ? { kind: "stopped", receipt: found.runId }
85
+ : { kind: "unknown", evidence: `world-run:${found.runId} ${status}` };
86
+ }
@@ -0,0 +1,48 @@
1
+ import type { DecisionWait, GateRequest, GateResult } from "../step-bridge.ts";
2
+ export interface GateReceipt {
3
+ readonly kind: string;
4
+ readonly reason?: string;
5
+ }
6
+ export interface GateOpening {
7
+ readonly waitMode?: "hook";
8
+ readonly runId: string;
9
+ readonly commandId: string;
10
+ readonly expectedRevision: number;
11
+ readonly gateId: string;
12
+ readonly kind: "question" | "approval";
13
+ readonly prompt: string;
14
+ readonly subject: string;
15
+ readonly expiresAt?: string;
16
+ }
17
+ export interface WaitRegistration {
18
+ readonly runId: string;
19
+ readonly commandId: string;
20
+ readonly gateId: string;
21
+ }
22
+ interface GatePorts {
23
+ readonly stopped: AbortSignal;
24
+ readonly timing?: {
25
+ readonly pollMilliseconds: number;
26
+ readonly retryMilliseconds: number;
27
+ };
28
+ readonly state: () => Promise<{
29
+ readonly runs: Readonly<Record<string, {
30
+ readonly revision: number;
31
+ } | undefined>>;
32
+ readonly gates: Readonly<Record<string, unknown>>;
33
+ }>;
34
+ readonly openGate: (opening: GateOpening) => Promise<GateReceipt>;
35
+ readonly registerWait: (wait: WaitRegistration) => Promise<GateReceipt>;
36
+ }
37
+ interface GateSubject {
38
+ readonly waitMode?: "hook";
39
+ readonly runId: string;
40
+ readonly transport: string;
41
+ readonly request: GateRequest;
42
+ }
43
+ export declare function openBridgeGate(ports: GatePorts, subject: GateSubject): Promise<GateResult>;
44
+ export declare function waitForBridgeDecision(ports: GatePorts & {
45
+ readonly document: (digest: string) => Promise<string | undefined>;
46
+ readonly decisionReceived: (runId: string, gateId: string) => Promise<boolean>;
47
+ }, subject: GateSubject): Promise<DecisionWait>;
48
+ export {};
@@ -0,0 +1,124 @@
1
+ import { createHash } from "node:crypto";
2
+ import { setTimeout as delay } from "node:timers/promises";
3
+ import { gateKey } from "../authority/gates.js";
4
+ import { decisionToken } from "../decision-wait.js";
5
+ import { record } from "../protocol.js";
6
+ const committed = ["accepted", "duplicate"];
7
+ function promptDigest(request) {
8
+ return `sha256:${createHash("sha256").update(request.prompt).digest("hex")}`;
9
+ }
10
+ function sameHookSubject(value, request) {
11
+ const gate = record(value);
12
+ return (gate?.["subject"] === promptDigest(request) &&
13
+ gate["kind"] === request.kind &&
14
+ gate["wait"] === "hook");
15
+ }
16
+ async function paused(hold, milliseconds) {
17
+ await delay(milliseconds, undefined, { signal: hold.ports.stopped }).catch(() => undefined);
18
+ if (hold.ports.stopped.aborted)
19
+ await new Promise(() => undefined);
20
+ }
21
+ function verdict(hold, receipt) {
22
+ if (receipt === undefined || receipt.kind === "failed")
23
+ return hold.timing.retryMilliseconds;
24
+ if (committed.includes(receipt.kind))
25
+ return "committed";
26
+ if (receipt.reason === "service-busy")
27
+ return hold.timing.retryMilliseconds;
28
+ if (receipt.reason === "stale-revision")
29
+ return hold.timing.pollMilliseconds;
30
+ return { kind: "refused", reason: receipt.reason ?? receipt.kind };
31
+ }
32
+ async function gateCommand(hold, send) {
33
+ for (;;) {
34
+ await paused(hold, 0);
35
+ const result = verdict(hold, await send().catch(() => undefined));
36
+ if (result === "committed")
37
+ return undefined;
38
+ if (typeof result !== "number")
39
+ return result;
40
+ await paused(hold, result);
41
+ }
42
+ }
43
+ async function opening(hold, subject) {
44
+ const { runId, transport, request } = subject;
45
+ const { gateId, kind, prompt } = request;
46
+ const state = await hold.ports.state();
47
+ const run = state.runs[runId];
48
+ if (run === undefined)
49
+ return { kind: "rejected", reason: "unknown-run" };
50
+ const key = gateKey(runId, gateId);
51
+ const exists = Object.hasOwn(state.gates, key);
52
+ if (exists &&
53
+ subject.waitMode === "hook" &&
54
+ !sameHookSubject(state.gates[key], request))
55
+ return { kind: "rejected", reason: "gate-subject-changed" };
56
+ if (exists)
57
+ return { kind: "duplicate" };
58
+ return await hold.ports.openGate({
59
+ ...(subject.waitMode === undefined ? {} : { waitMode: subject.waitMode }),
60
+ runId,
61
+ commandId: `${transport}:open:${gateId}`,
62
+ expectedRevision: run.revision,
63
+ gateId,
64
+ kind,
65
+ prompt,
66
+ subject: promptDigest(request),
67
+ ...(request.expiresAt === undefined
68
+ ? {}
69
+ : { expiresAt: request.expiresAt }),
70
+ });
71
+ }
72
+ export async function openBridgeGate(ports, subject) {
73
+ const hold = {
74
+ ports,
75
+ timing: ports.timing ?? { pollMilliseconds: 20, retryMilliseconds: 1000 },
76
+ };
77
+ const refusal = await gateCommand(hold, () => opening(hold, subject));
78
+ if (refusal !== undefined)
79
+ return refusal;
80
+ if (subject.waitMode === "hook")
81
+ return {
82
+ kind: "opened",
83
+ decisionId: decisionToken(subject.runId, subject.request.gateId),
84
+ };
85
+ const waited = await gateCommand(hold, () => ports.registerWait({
86
+ runId: subject.runId,
87
+ commandId: `${subject.transport}:wait:${subject.request.gateId}`,
88
+ gateId: subject.request.gateId,
89
+ }));
90
+ return waited ?? { kind: "opened", decisionId: subject.request.gateId };
91
+ }
92
+ export async function waitForBridgeDecision(ports, subject) {
93
+ const hold = {
94
+ ports,
95
+ timing: ports.timing ?? { pollMilliseconds: 20, retryMilliseconds: 1000 },
96
+ };
97
+ await paused(hold, 0);
98
+ const state = await ports.state();
99
+ const key = gateKey(subject.runId, subject.request.gateId);
100
+ const gate = state.gates[key];
101
+ if (Object.hasOwn(state.gates, key) &&
102
+ !sameHookSubject(gate, subject.request))
103
+ throw new Error("gate-subject-changed");
104
+ const outcome = record(record(gate)?.["outcome"]);
105
+ if (outcome !== undefined &&
106
+ (await ports.decisionReceived(subject.runId, subject.request.gateId)))
107
+ return await storedDecision(ports, outcome);
108
+ const opening = await openBridgeGate(ports, { ...subject, waitMode: "hook" });
109
+ if (opening.kind !== "opened")
110
+ throw new Error(opening.reason);
111
+ return { token: opening.decisionId };
112
+ }
113
+ async function storedDecision(ports, outcome) {
114
+ const decision = ["approved", "denied", "answered", "expired"].find((value) => value === outcome["decision"]);
115
+ if (decision === undefined)
116
+ throw new Error("invalid-decision-outcome");
117
+ const digest = outcome["answer"];
118
+ if (digest !== null && typeof digest !== "string")
119
+ throw new Error("invalid-decision-answer");
120
+ const answer = digest === null ? null : await ports.document(digest);
121
+ if (answer === undefined)
122
+ throw new Error("missing-decision-answer");
123
+ return { decision, answer };
124
+ }
@@ -0,0 +1,26 @@
1
+ import { type RunWaitTarget } from "../run-wait.ts";
2
+ import type { RunWaitOutcome, RunWaitRequest } from "../step-bridge.ts";
3
+ export interface RunWaitPorts {
4
+ readonly now?: () => number;
5
+ readonly target: (runId: string) => Promise<RunWaitTarget | undefined>;
6
+ readonly observe: (report: {
7
+ readonly runId: string;
8
+ readonly commandId: string;
9
+ readonly condition: string;
10
+ readonly reason: string;
11
+ readonly evidence?: string;
12
+ readonly retryAt?: string;
13
+ readonly operationId?: string;
14
+ }) => Promise<{
15
+ readonly kind: string;
16
+ readonly reason?: string;
17
+ }>;
18
+ }
19
+ export declare function runWait(ports: RunWaitPorts, wait: {
20
+ readonly caller: {
21
+ readonly runId: string;
22
+ readonly stepId: string;
23
+ readonly startedAt: number;
24
+ };
25
+ readonly request: RunWaitRequest;
26
+ }): Promise<RunWaitOutcome>;
@@ -0,0 +1,37 @@
1
+ import { FatalError, RetryableError } from "workflow";
2
+ import { runWaitResult } from "../run-wait.js";
3
+ export async function runWait(ports, wait) {
4
+ const { caller, request } = wait;
5
+ const now = (ports.now ?? Date.now)();
6
+ const result = runWaitResult(request, {
7
+ callerRunId: caller.runId,
8
+ startedAt: caller.startedAt,
9
+ now,
10
+ target: await ports.target(request.runId),
11
+ });
12
+ const waiting = result.kind === "waiting";
13
+ const receipt = await ports.observe({
14
+ runId: caller.runId,
15
+ commandId: `${caller.stepId}:run-wait:${waiting ? "waiting" : "ended"}`,
16
+ condition: waiting ? "waiting-run" : "working",
17
+ reason: waiting ? "awaiting-run" : "in-progress",
18
+ operationId: caller.stepId,
19
+ ...(result.kind !== "waiting"
20
+ ? {}
21
+ : {
22
+ evidence: request.runId,
23
+ retryAt: new Date(result.deadline).toISOString(),
24
+ }),
25
+ });
26
+ if (!["accepted", "duplicate"].includes(receipt.kind))
27
+ throw new RetryableError("run-wait-observation-unavailable", {
28
+ retryAfter: 1000,
29
+ });
30
+ if (result.kind === "refused")
31
+ throw new FatalError(result.reason);
32
+ if (result.kind === "completed")
33
+ return result.outcome;
34
+ throw new RetryableError("awaiting-run", {
35
+ retryAfter: Math.max(1, Math.min(1000, result.deadline - now)),
36
+ });
37
+ }
@@ -9,6 +9,7 @@ export interface RunIntent extends Partial<Continuation> {
9
9
  readonly kind: string;
10
10
  readonly runId: string;
11
11
  readonly operationId: string;
12
+ readonly workflow: string;
12
13
  }
13
14
  export type RunOutcome = {
14
15
  readonly kind: "accepted";
@@ -27,12 +28,12 @@ export interface StartParts {
27
28
  readonly runs: () => Promise<readonly OperationRun[]>;
28
29
  readonly input: (runId: string) => Promise<string | undefined>;
29
30
  readonly document: (digest: string) => Promise<string | undefined>;
30
- readonly workflow: (runId: string) => Promise<WorkflowFunction | undefined>;
31
+ readonly workflow: (intent: RunIntent) => Promise<WorkflowFunction | undefined>;
31
32
  readonly cancel: (receipt: string) => Promise<string>;
32
33
  }
33
34
  export interface StartDelivery {
34
35
  readonly reconcile: (intent: RunIntent) => Promise<RunOutcome>;
35
- readonly deliver: (intent: RunIntent) => Promise<{
36
+ readonly deliver: (intent: RunIntent, signal?: AbortSignal) => Promise<{
36
37
  readonly receipt: string;
37
38
  }>;
38
39
  readonly stop: (intent: RunIntent) => Promise<RunOutcome>;
@@ -1,5 +1,6 @@
1
1
  import { start } from "workflow/api";
2
2
  import { operationTag, runTag } from "./world-runs.js";
3
+ import { deliveredDecision, reconciledDecision, stoppedDecision, } from "./decision-resume.js";
3
4
  const ends = ["cancelled", "completed", "failed"];
4
5
  async function segments(parts, intent) {
5
6
  return (await parts.runs()).filter((run) => run.operationId === intent.operationId);
@@ -31,7 +32,7 @@ async function continuation(parts, intent) {
31
32
  }
32
33
  async function delivered(parts, intent) {
33
34
  const continued = await continuation(parts, intent);
34
- const workflow = await parts.workflow(intent.runId);
35
+ const workflow = await parts.workflow(intent);
35
36
  const input = await parts.input(intent.runId);
36
37
  if (workflow === undefined || input === undefined)
37
38
  throw new Error(`start-not-available: ${intent.runId}`);
@@ -61,8 +62,14 @@ async function stopped(parts, intent) {
61
62
  }
62
63
  export function startDelivery(parts) {
63
64
  return {
64
- reconcile: (intent) => reconciled(parts, intent),
65
- deliver: (intent) => delivered(parts, intent),
66
- stop: (intent) => stopped(parts, intent),
65
+ reconcile: (intent) => intent.kind === "resume-hook"
66
+ ? reconciledDecision(parts, intent)
67
+ : reconciled(parts, intent),
68
+ deliver: (intent, signal) => intent.kind === "resume-hook"
69
+ ? deliveredDecision(parts, { intent, signal })
70
+ : delivered(parts, intent),
71
+ stop: (intent) => intent.kind === "resume-hook"
72
+ ? stoppedDecision(parts, intent)
73
+ : stopped(parts, intent),
67
74
  };
68
75
  }
@@ -1,8 +1,12 @@
1
+ import { type GateOpening, type GateReceipt, type WaitRegistration } from "./gate-bridge.ts";
2
+ export type { GateOpening, GateReceipt, WaitRegistration, } from "./gate-bridge.ts";
3
+ import { type RunWaitPorts } from "./run-wait.ts";
1
4
  import { type ProtectedRequest, type StepBridge } from "../step-bridge.ts";
2
5
  export interface StepCall {
3
6
  readonly worldRunId: string;
4
7
  readonly stepId: string;
5
8
  readonly attempt: number;
9
+ readonly startedAt?: number;
6
10
  }
7
11
  export declare function sdkStepCall(): StepCall;
8
12
  export interface OperationRead {
@@ -30,24 +34,6 @@ interface BridgeIdentity {
30
34
  export interface BridgeRequest extends ProtectedRequest, BridgeIdentity {
31
35
  readonly runId: string;
32
36
  }
33
- export interface GateReceipt {
34
- readonly kind: string;
35
- readonly reason?: string;
36
- }
37
- export interface GateOpening {
38
- readonly runId: string;
39
- readonly commandId: string;
40
- readonly expectedRevision: number;
41
- readonly gateId: string;
42
- readonly kind: "question" | "approval";
43
- readonly prompt: string;
44
- readonly subject: string;
45
- }
46
- export interface WaitRegistration {
47
- readonly runId: string;
48
- readonly commandId: string;
49
- readonly gateId: string;
50
- }
51
37
  export interface BridgeTiming {
52
38
  readonly lookupTries: number;
53
39
  readonly pollMilliseconds: number;
@@ -55,6 +41,8 @@ export interface BridgeTiming {
55
41
  }
56
42
  export declare const bridgeTiming: BridgeTiming;
57
43
  export interface BridgePorts {
44
+ readonly decisionReceived?: (runId: string, gateId: string) => Promise<boolean>;
45
+ readonly runWait?: RunWaitPorts;
58
46
  readonly call: () => StepCall;
59
47
  readonly run: (worldRunId: string) => Promise<{
60
48
  readonly runId: string;
@@ -76,4 +64,3 @@ export interface BridgePorts {
76
64
  }
77
65
  export declare function stepBridge(ports: BridgePorts): StepBridge;
78
66
  export declare function registerStepBridge(bridge: StepBridge): () => void;
79
- export {};