cloving 1.2.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 (518) hide show
  1. package/README.md +525 -185
  2. package/dist/src/agent-harness-shell.d.ts +12 -0
  3. package/dist/src/agent-harness-shell.js +90 -0
  4. package/dist/src/agent-harness-versions.d.ts +8 -0
  5. package/dist/src/agent-harness-versions.js +49 -0
  6. package/dist/src/agent-harnesses.d.ts +4 -0
  7. package/dist/src/agent-harnesses.js +13 -0
  8. package/dist/src/authority/commands.d.ts +1 -0
  9. package/dist/src/authority/commands.js +24 -4
  10. package/dist/src/authority/gate-reduction.d.ts +1 -0
  11. package/dist/src/authority/gate-reduction.js +18 -3
  12. package/dist/src/authority/gates.d.ts +2 -1
  13. package/dist/src/authority/gates.js +5 -1
  14. package/dist/src/authority/operations.js +1 -1
  15. package/dist/src/authority/reduction.d.ts +1 -1
  16. package/dist/src/authority/reduction.js +6 -1
  17. package/dist/src/authority/status-input.d.ts +1 -1
  18. package/dist/src/authority/status.d.ts +1 -0
  19. package/dist/src/authority/status.js +27 -3
  20. package/dist/src/authority/transitions.d.ts +5 -5
  21. package/dist/src/authority/transitions.js +6 -0
  22. package/dist/src/broker/actor/authority-delivery.js +1 -0
  23. package/dist/src/broker/actor/authority-queries.d.ts +7 -1
  24. package/dist/src/broker/actor/authority-queries.js +17 -2
  25. package/dist/src/broker/actor/authority-receipts.js +11 -1
  26. package/dist/src/broker/actor/authority-session.js +2 -2
  27. package/dist/src/broker/actor/authority-settings.js +4 -0
  28. package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
  29. package/dist/src/broker/actor/delivery-intents.js +4 -4
  30. package/dist/src/broker/actor/effect-delivery.js +4 -1
  31. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  32. package/dist/src/broker/actor/effect-queries.js +7 -0
  33. package/dist/src/broker/actor/pin-check.js +1 -1
  34. package/dist/src/broker/actor/stop-plan.js +1 -1
  35. package/dist/src/broker/actor/turn-state.js +1 -1
  36. package/dist/src/broker/authority-admission.js +22 -9
  37. package/dist/src/broker/authority-restore.js +1 -0
  38. package/dist/src/broker/decision-restore.js +4 -4
  39. package/dist/src/broker/socket-address.d.ts +3 -1
  40. package/dist/src/broker/socket-address.js +2 -2
  41. package/dist/src/cli/arguments.d.ts +11 -13
  42. package/dist/src/cli/arguments.js +37 -107
  43. package/dist/src/cli/command-effects.d.ts +7 -0
  44. package/dist/src/cli/command-effects.js +39 -0
  45. package/dist/src/cli/commands.js +11 -4
  46. package/dist/src/cli/config-arguments.d.ts +11 -0
  47. package/dist/src/cli/config-arguments.js +59 -0
  48. package/dist/src/cli/config-command.d.ts +2 -0
  49. package/dist/src/cli/config-command.js +105 -0
  50. package/dist/src/cli/config-file.d.ts +3 -0
  51. package/dist/src/cli/config-file.js +50 -0
  52. package/dist/src/cli/config-lock.d.ts +7 -0
  53. package/dist/src/cli/config-lock.js +61 -0
  54. package/dist/src/cli/config-notice.d.ts +5 -0
  55. package/dist/src/cli/config-notice.js +46 -0
  56. package/dist/src/cli/doctor-github.d.ts +9 -0
  57. package/dist/src/cli/doctor-github.js +138 -0
  58. package/dist/src/cli/doctor-harness.d.ts +13 -0
  59. package/dist/src/cli/doctor-harness.js +242 -0
  60. package/dist/src/cli/doctor-local.d.ts +18 -0
  61. package/dist/src/cli/doctor-local.js +77 -0
  62. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  63. package/dist/src/cli/doctor-runtime.js +176 -0
  64. package/dist/src/cli/doctor-service.d.ts +1 -0
  65. package/dist/src/cli/doctor-service.js +11 -0
  66. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  67. package/dist/src/cli/doctor-workflows.js +45 -0
  68. package/dist/src/cli/doctor.d.ts +15 -0
  69. package/dist/src/cli/doctor.js +190 -0
  70. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  71. package/dist/src/cli/github-ci-progress.js +83 -0
  72. package/dist/src/cli/github-retry.d.ts +6 -0
  73. package/dist/src/cli/github-retry.js +47 -0
  74. package/dist/src/cli/harness-probes.d.ts +22 -0
  75. package/dist/src/cli/harness-probes.js +183 -0
  76. package/dist/src/cli/main.d.ts +7 -1
  77. package/dist/src/cli/main.js +39 -61
  78. package/dist/src/cli/phone-arguments.d.ts +14 -0
  79. package/dist/src/cli/phone-arguments.js +37 -0
  80. package/dist/src/cli/phone-client.d.ts +2 -0
  81. package/dist/src/cli/phone-client.js +32 -0
  82. package/dist/src/cli/phone-command.d.ts +13 -0
  83. package/dist/src/cli/phone-command.js +101 -0
  84. package/dist/src/cli/probe-command.d.ts +36 -0
  85. package/dist/src/cli/probe-command.js +59 -0
  86. package/dist/src/cli/project-settings.d.ts +4 -0
  87. package/dist/src/cli/project-settings.js +33 -0
  88. package/dist/src/cli/render.d.ts +2 -1
  89. package/dist/src/cli/render.js +44 -28
  90. package/dist/src/cli/report-github.d.ts +18 -0
  91. package/dist/src/cli/report-github.js +200 -0
  92. package/dist/src/cli/report.d.ts +17 -0
  93. package/dist/src/cli/report.js +192 -0
  94. package/dist/src/cli/repository-arguments.d.ts +5 -0
  95. package/dist/src/cli/repository-arguments.js +34 -0
  96. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  97. package/dist/src/cli/runtime-arguments.js +15 -0
  98. package/dist/src/cli/runtime-directory.d.ts +6 -2
  99. package/dist/src/cli/runtime-directory.js +72 -14
  100. package/dist/src/cli/toolchain.d.ts +2 -0
  101. package/dist/src/cli/toolchain.js +22 -2
  102. package/dist/src/cli/usage-render.d.ts +5 -0
  103. package/dist/src/cli/usage-render.js +40 -1
  104. package/dist/src/cli/usage.d.ts +3 -3
  105. package/dist/src/cli/usage.js +70 -44
  106. package/dist/src/cli/watch-actions.d.ts +2 -0
  107. package/dist/src/cli/watch-actions.js +4 -4
  108. package/dist/src/cli/watch-board-view.d.ts +1 -1
  109. package/dist/src/cli/watch-board-view.js +8 -2
  110. package/dist/src/cli/watch-board.js +23 -10
  111. package/dist/src/cli/watch-card-forms.js +2 -2
  112. package/dist/src/cli/watch-client.d.ts +1 -1
  113. package/dist/src/cli/watch-client.js +7 -2
  114. package/dist/src/cli/watch-header-view.d.ts +27 -0
  115. package/dist/src/cli/watch-header-view.js +116 -0
  116. package/dist/src/cli/watch-model.js +17 -4
  117. package/dist/src/cli/watch-page.js +48 -12
  118. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  119. package/dist/src/cli/watch-phone-client.js +84 -0
  120. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  121. package/dist/src/cli/watch-phone-view.js +113 -0
  122. package/dist/src/cli/watch-phone.d.ts +5 -0
  123. package/dist/src/cli/watch-phone.js +53 -0
  124. package/dist/src/cli/watch-pull-request.d.ts +3 -1
  125. package/dist/src/cli/watch-pull-request.js +4 -0
  126. package/dist/src/cli/watch-render.d.ts +9 -1
  127. package/dist/src/cli/watch-server.js +23 -5
  128. package/dist/src/cli/watch-turn.d.ts +4 -1
  129. package/dist/src/cli/watch-turn.js +37 -1
  130. package/dist/src/cli/watch-usage.js +5 -1
  131. package/dist/src/cli/watch-view.d.ts +6 -20
  132. package/dist/src/cli/watch-view.js +14 -106
  133. package/dist/src/cli.js +106 -23
  134. package/dist/src/command-settings.d.ts +16 -0
  135. package/dist/src/command-settings.js +42 -0
  136. package/dist/src/configuration-change.d.ts +11 -0
  137. package/dist/src/configuration-change.js +62 -0
  138. package/dist/src/configuration-display.d.ts +21 -0
  139. package/dist/src/configuration-display.js +69 -0
  140. package/dist/src/configuration-schema.d.ts +49 -0
  141. package/dist/src/configuration-schema.js +159 -0
  142. package/dist/src/daemon/claude-turn.d.ts +19 -5
  143. package/dist/src/daemon/claude-turn.js +116 -53
  144. package/dist/src/daemon/claude-worker.d.ts +3 -3
  145. package/dist/src/daemon/claude-worker.js +65 -76
  146. package/dist/src/daemon/command-journal.d.ts +5 -0
  147. package/dist/src/daemon/command-journal.js +50 -0
  148. package/dist/src/daemon/command-process.d.ts +28 -0
  149. package/dist/src/daemon/command-process.js +164 -0
  150. package/dist/src/daemon/command-worker.d.ts +19 -0
  151. package/dist/src/daemon/command-worker.js +182 -0
  152. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  153. package/dist/src/daemon/cursor-stream.js +154 -0
  154. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  155. package/dist/src/daemon/daemon-adapters.js +102 -0
  156. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  157. package/dist/src/daemon/daemon-loops.js +39 -0
  158. package/dist/src/daemon/daemon.d.ts +2 -33
  159. package/dist/src/daemon/daemon.js +126 -132
  160. package/dist/src/daemon/declared-input.d.ts +3 -0
  161. package/dist/src/daemon/declared-input.js +9 -0
  162. package/dist/src/daemon/delivery-router.js +1 -1
  163. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  164. package/dist/src/daemon/gemini-stream.js +129 -0
  165. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  166. package/dist/src/daemon/github-ci-rerun.js +92 -0
  167. package/dist/src/daemon/github-ci.js +89 -8
  168. package/dist/src/daemon/github-merge-call.d.ts +2 -0
  169. package/dist/src/daemon/github-merge.js +7 -3
  170. package/dist/src/daemon/github-methods.js +10 -0
  171. package/dist/src/daemon/github-operation.d.ts +1 -0
  172. package/dist/src/daemon/github-retry.js +8 -44
  173. package/dist/src/daemon/issue-queue.d.ts +1 -0
  174. package/dist/src/daemon/issue-queue.js +3 -26
  175. package/dist/src/daemon/notify.js +2 -1
  176. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  177. package/dist/src/daemon/opencode-stream.js +87 -0
  178. package/dist/src/daemon/queue-status.d.ts +4 -0
  179. package/dist/src/daemon/queue-status.js +38 -0
  180. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  181. package/dist/src/daemon/retry-worktree.js +139 -0
  182. package/dist/src/daemon/retrying-turn.d.ts +2 -0
  183. package/dist/src/daemon/retrying-turn.js +108 -30
  184. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  185. package/dist/src/daemon/schedule-journal.js +57 -0
  186. package/dist/src/daemon/text-output.d.ts +18 -0
  187. package/dist/src/daemon/text-output.js +44 -0
  188. package/dist/src/daemon/ticket-registration.d.ts +5 -7
  189. package/dist/src/daemon/ticket-registration.js +85 -40
  190. package/dist/src/daemon/turn-command.d.ts +10 -0
  191. package/dist/src/daemon/turn-command.js +33 -0
  192. package/dist/src/daemon/turn-report.d.ts +18 -0
  193. package/dist/src/daemon/turn-report.js +79 -0
  194. package/dist/src/daemon/work-tree.d.ts +2 -1
  195. package/dist/src/daemon/work-tree.js +15 -12
  196. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  197. package/dist/src/daemon/workflow-generations.js +57 -0
  198. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  199. package/dist/src/daemon/workflow-replay.js +58 -0
  200. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  201. package/dist/src/daemon/workflow-schedules.js +185 -0
  202. package/dist/src/decision-wait.d.ts +1 -0
  203. package/dist/src/decision-wait.js +3 -0
  204. package/dist/src/delivery-backoff.d.ts +1 -0
  205. package/dist/src/delivery-backoff.js +3 -0
  206. package/dist/src/doctor-report.d.ts +24 -0
  207. package/dist/src/doctor-report.js +70 -0
  208. package/dist/src/execution-pin.d.ts +5 -0
  209. package/dist/src/execution-pin.js +67 -4
  210. package/dist/src/grok-result.d.ts +12 -0
  211. package/dist/src/grok-result.js +61 -0
  212. package/dist/src/harness-defaults.d.ts +35 -0
  213. package/dist/src/harness-defaults.js +121 -0
  214. package/dist/src/host/decision-resume.d.ts +35 -0
  215. package/dist/src/host/decision-resume.js +86 -0
  216. package/dist/src/host/gate-bridge.d.ts +48 -0
  217. package/dist/src/host/gate-bridge.js +124 -0
  218. package/dist/src/host/run-wait.d.ts +26 -0
  219. package/dist/src/host/run-wait.js +37 -0
  220. package/dist/src/host/start-delivery.d.ts +1 -1
  221. package/dist/src/host/start-delivery.js +10 -3
  222. package/dist/src/host/step-bridge-host.d.ts +6 -20
  223. package/dist/src/host/step-bridge-host.js +44 -58
  224. package/dist/src/merge-request.d.ts +19 -0
  225. package/dist/src/merge-request.js +32 -0
  226. package/dist/src/phone/canonical-json.d.ts +1 -0
  227. package/dist/src/phone/canonical-json.js +16 -0
  228. package/dist/src/phone/phone-link.d.ts +7 -0
  229. package/dist/src/phone/phone-link.js +21 -0
  230. package/dist/src/phone/qr-data.d.ts +8 -0
  231. package/dist/src/phone/qr-data.js +133 -0
  232. package/dist/src/phone/qr-matrix.d.ts +6 -0
  233. package/dist/src/phone/qr-matrix.js +175 -0
  234. package/dist/src/phone/qr-penalty.d.ts +3 -0
  235. package/dist/src/phone/qr-penalty.js +67 -0
  236. package/dist/src/phone/qr-picture.d.ts +5 -0
  237. package/dist/src/phone/qr-picture.js +24 -0
  238. package/dist/src/private-config.schema.json +263 -0
  239. package/dist/src/project-config.schema.json +65 -0
  240. package/dist/src/project-settings.d.ts +19 -0
  241. package/dist/src/project-settings.js +131 -0
  242. package/dist/src/relay/answer-check.d.ts +24 -0
  243. package/dist/src/relay/answer-check.js +145 -0
  244. package/dist/src/relay/answer-inbox.d.ts +15 -0
  245. package/dist/src/relay/answer-inbox.js +173 -0
  246. package/dist/src/relay/daemon-keys.d.ts +16 -0
  247. package/dist/src/relay/daemon-keys.js +75 -0
  248. package/dist/src/relay/decision-check.d.ts +3 -0
  249. package/dist/src/relay/decision-check.js +77 -0
  250. package/dist/src/relay/decision-close.d.ts +6 -0
  251. package/dist/src/relay/decision-close.js +72 -0
  252. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  253. package/dist/src/relay/decision-envelopes.js +93 -0
  254. package/dist/src/relay/decision-watch.d.ts +14 -0
  255. package/dist/src/relay/decision-watch.js +68 -0
  256. package/dist/src/relay/envelope-post.d.ts +8 -0
  257. package/dist/src/relay/envelope-post.js +71 -0
  258. package/dist/src/relay/envelope.d.ts +28 -0
  259. package/dist/src/relay/envelope.js +53 -0
  260. package/dist/src/relay/hpke.d.ts +25 -0
  261. package/dist/src/relay/hpke.js +108 -0
  262. package/dist/src/relay/pairing-checks.d.ts +42 -0
  263. package/dist/src/relay/pairing-checks.js +172 -0
  264. package/dist/src/relay/pairing-follow.d.ts +8 -0
  265. package/dist/src/relay/pairing-follow.js +95 -0
  266. package/dist/src/relay/pairing-session.d.ts +29 -0
  267. package/dist/src/relay/pairing-session.js +87 -0
  268. package/dist/src/relay/phone-delivery.d.ts +51 -0
  269. package/dist/src/relay/phone-delivery.js +139 -0
  270. package/dist/src/relay/phone-devices.d.ts +36 -0
  271. package/dist/src/relay/phone-devices.js +46 -0
  272. package/dist/src/relay/phone-inbox.d.ts +18 -0
  273. package/dist/src/relay/phone-inbox.js +17 -0
  274. package/dist/src/relay/phone-operations.d.ts +18 -0
  275. package/dist/src/relay/phone-operations.js +121 -0
  276. package/dist/src/relay/phone-outbox.d.ts +21 -0
  277. package/dist/src/relay/phone-outbox.js +25 -0
  278. package/dist/src/relay/phone-socket.d.ts +6 -0
  279. package/dist/src/relay/phone-socket.js +63 -0
  280. package/dist/src/relay/relay-control.d.ts +7 -0
  281. package/dist/src/relay/relay-control.js +24 -0
  282. package/dist/src/relay/relay-files.d.ts +2 -0
  283. package/dist/src/relay/relay-files.js +23 -0
  284. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  285. package/dist/src/relay/relay-heartbeat.js +81 -0
  286. package/dist/src/relay/relay-http.d.ts +14 -0
  287. package/dist/src/relay/relay-http.js +63 -0
  288. package/dist/src/relay/relay-registration.d.ts +15 -0
  289. package/dist/src/relay/relay-registration.js +63 -0
  290. package/dist/src/relay/relay-service.d.ts +25 -0
  291. package/dist/src/relay/relay-service.js +216 -0
  292. package/dist/src/relay/relay-store.d.ts +48 -0
  293. package/dist/src/relay/relay-store.js +131 -0
  294. package/dist/src/relay/sealed-post.d.ts +25 -0
  295. package/dist/src/relay/sealed-post.js +52 -0
  296. package/dist/src/relay.d.ts +1 -0
  297. package/dist/src/relay.js +8 -0
  298. package/dist/src/report-statistics.d.ts +50 -0
  299. package/dist/src/report-statistics.js +70 -0
  300. package/dist/src/report.d.ts +171 -0
  301. package/dist/src/report.js +119 -0
  302. package/dist/src/repository-identity.d.ts +4 -0
  303. package/dist/src/repository-identity.js +4 -0
  304. package/dist/src/review-subject.d.ts +41 -0
  305. package/dist/src/review-subject.js +91 -0
  306. package/dist/src/run-wait.d.ts +23 -0
  307. package/dist/src/run-wait.js +20 -0
  308. package/dist/src/service/active-tickets.d.ts +4 -0
  309. package/dist/src/service/active-tickets.js +49 -0
  310. package/dist/src/service/command-effects.d.ts +4 -0
  311. package/dist/src/service/command-effects.js +16 -0
  312. package/dist/src/service/decision-handler.d.ts +4 -0
  313. package/dist/src/service/decision-handler.js +39 -4
  314. package/dist/src/service/gateway.js +18 -3
  315. package/dist/src/service/registry.d.ts +16 -3
  316. package/dist/src/service/registry.js +34 -3
  317. package/dist/src/service/replies.d.ts +9 -1
  318. package/dist/src/service/replies.js +12 -0
  319. package/dist/src/service/run-handlers.js +14 -55
  320. package/dist/src/service/run-metadata.d.ts +8 -0
  321. package/dist/src/service/run-metadata.js +53 -0
  322. package/dist/src/service/run-waits.d.ts +3 -0
  323. package/dist/src/service/run-waits.js +41 -0
  324. package/dist/src/service/service.d.ts +18 -2
  325. package/dist/src/service/service.js +23 -7
  326. package/dist/src/service/submission-handler.d.ts +0 -1
  327. package/dist/src/service/submission-handler.js +6 -34
  328. package/dist/src/service/worker-port.d.ts +1 -0
  329. package/dist/src/service/worker-totals.js +8 -23
  330. package/dist/src/step-bridge.d.ts +23 -0
  331. package/dist/src/steps/decision-gate.d.ts +2 -1
  332. package/dist/src/steps/decision-gate.js +7 -0
  333. package/dist/src/steps/merge-by-person.d.ts +2 -0
  334. package/dist/src/steps/merge-by-person.js +18 -0
  335. package/dist/src/steps/merge-when-green.d.ts +2 -0
  336. package/dist/src/steps/merge-when-green.js +62 -0
  337. package/dist/src/steps/review-by-agent.d.ts +5 -0
  338. package/dist/src/steps/review-by-agent.js +124 -0
  339. package/dist/src/steps/review-by-person.d.ts +4 -0
  340. package/dist/src/steps/review-by-person.js +16 -0
  341. package/dist/src/steps/review-subject.d.ts +2 -0
  342. package/dist/src/steps/review-subject.js +11 -0
  343. package/dist/src/steps/run-command.d.ts +2 -0
  344. package/dist/src/steps/run-command.js +15 -0
  345. package/dist/src/steps/sleep.d.ts +3 -0
  346. package/dist/src/steps/sleep.js +19 -0
  347. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  348. package/dist/src/steps/wait-for-decision.js +71 -0
  349. package/dist/src/steps/wait-for-run.d.ts +5 -0
  350. package/dist/src/steps/wait-for-run.js +9 -0
  351. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  352. package/dist/src/storage/decision-snapshots.js +7 -1
  353. package/dist/src/submission.d.ts +4 -0
  354. package/dist/src/submission.js +6 -2
  355. package/dist/src/testing.d.ts +29 -0
  356. package/dist/src/testing.js +264 -0
  357. package/dist/src/ticket-status-stream.d.ts +9 -0
  358. package/dist/src/ticket-status-stream.js +94 -0
  359. package/dist/src/token-prices.d.ts +12 -4
  360. package/dist/src/token-prices.js +15 -2
  361. package/dist/src/turn-profile.d.ts +1 -0
  362. package/dist/src/turn-profile.js +8 -1
  363. package/dist/src/worker-usage.d.ts +16 -0
  364. package/dist/src/worker-usage.js +57 -0
  365. package/dist/src/workflow-admission.d.ts +5 -0
  366. package/dist/src/workflow-candidate.d.ts +7 -2
  367. package/dist/src/workflow-candidate.js +47 -5
  368. package/dist/src/workflow-declaration.d.ts +21 -3
  369. package/dist/src/workflow-declaration.js +77 -9
  370. package/dist/src/workflow-discovery.d.ts +2 -1
  371. package/dist/src/workflow-discovery.js +4 -1
  372. package/dist/src/workflow-refusals.js +3 -0
  373. package/dist/src/workflow-schedule.d.ts +22 -0
  374. package/dist/src/workflow-schedule.js +53 -0
  375. package/dist/src/workflows.d.ts +11 -1
  376. package/dist/src/workflows.js +8 -0
  377. package/dist/tools/admit-workflow.d.ts +1 -0
  378. package/dist/tools/admit-workflow.js +18 -5
  379. package/dist/tools/doctor-adoption.d.ts +1 -0
  380. package/dist/tools/doctor-adoption.js +11 -0
  381. package/dist/tools/project-configuration.d.ts +4 -0
  382. package/dist/tools/project-configuration.js +47 -0
  383. package/dist/tools/self-host-processes.d.ts +1 -0
  384. package/dist/tools/self-host-processes.js +33 -22
  385. package/dist/tools/self-host-project.d.ts +4 -0
  386. package/dist/tools/self-host-project.js +61 -14
  387. package/dist/tools/self-host-runtime.d.ts +16 -0
  388. package/dist/tools/self-host-runtime.js +60 -0
  389. package/dist/tools/self-host-workflows.d.ts +1 -0
  390. package/dist/tools/self-host-workflows.js +36 -1
  391. package/dist/tools/self-host.js +86 -61
  392. package/dist/tools/workflow-candidate-counts.d.ts +6 -2
  393. package/dist/tools/workflow-candidate-counts.js +31 -16
  394. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  395. package/dist/tools/workflow-candidate-fields.js +24 -0
  396. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  397. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  398. package/dist/tools/workflow-candidate-program.d.ts +2 -0
  399. package/dist/tools/workflow-candidate-program.js +36 -8
  400. package/dist/tools/workflow-candidate-source.js +77 -15
  401. package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
  402. package/dist/tools/workflow-candidate-syntax.js +70 -26
  403. package/dist/tools/workflow-command.d.ts +1 -0
  404. package/dist/tools/workflow-command.js +143 -0
  405. package/dist/tools/workflow-folder-capture.d.ts +1 -0
  406. package/dist/tools/workflow-folder-capture.js +47 -2
  407. package/dist/tools/workflow-folders.d.ts +17 -1
  408. package/dist/tools/workflow-folders.js +59 -6
  409. package/dist/tools/workflow-test-hook.d.ts +7 -0
  410. package/dist/tools/workflow-test-hook.js +16 -0
  411. package/dist/tools/workflow-test-loader.d.ts +1 -0
  412. package/dist/tools/workflow-test-loader.js +10 -0
  413. package/dist/workflows/develop-ticket.js +1 -1
  414. package/dist/workflows/ticket-prompts.js +5 -1
  415. package/package.json +46 -4
  416. package/templates/develop/README.md +78 -0
  417. package/templates/develop/develop/accept.ts +11 -0
  418. package/templates/develop/develop/flow-tests.ts +357 -0
  419. package/templates/develop/develop/local.ts +40 -0
  420. package/templates/develop/develop/option-tests.ts +174 -0
  421. package/templates/develop/develop/partial-choice.ts +29 -0
  422. package/templates/develop/develop/partial.ts +28 -0
  423. package/templates/develop/develop/pull.ts +152 -0
  424. package/templates/develop/develop/queue-partial.ts +39 -0
  425. package/templates/develop/develop/refusal-tests.ts +174 -0
  426. package/templates/develop/develop/report.ts +156 -0
  427. package/templates/develop/develop/round.ts +40 -0
  428. package/templates/develop/develop/scenarios.ts +87 -0
  429. package/templates/develop/develop/turn.ts +67 -0
  430. package/templates/develop/develop.declaration.json +24 -0
  431. package/templates/develop/develop.test.ts +287 -0
  432. package/templates/develop/develop.ts +30 -0
  433. package/templates/develop/template.json +153 -0
  434. package/dist/src/chats/analysis-batches.d.ts +0 -42
  435. package/dist/src/chats/analysis-batches.js +0 -97
  436. package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
  437. package/dist/src/chats/analysis-checkpoint.js +0 -31
  438. package/dist/src/chats/analysis-contract.d.ts +0 -80
  439. package/dist/src/chats/analysis-contract.js +0 -16
  440. package/dist/src/chats/analysis-data.d.ts +0 -3
  441. package/dist/src/chats/analysis-data.js +0 -85
  442. package/dist/src/chats/analysis-input.d.ts +0 -18
  443. package/dist/src/chats/analysis-input.js +0 -97
  444. package/dist/src/chats/analysis-links.d.ts +0 -2
  445. package/dist/src/chats/analysis-links.js +0 -25
  446. package/dist/src/chats/analysis-merge.d.ts +0 -16
  447. package/dist/src/chats/analysis-merge.js +0 -134
  448. package/dist/src/chats/analysis-prompt.d.ts +0 -18
  449. package/dist/src/chats/analysis-prompt.js +0 -42
  450. package/dist/src/chats/analysis-proposal.d.ts +0 -4
  451. package/dist/src/chats/analysis-proposal.js +0 -41
  452. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  453. package/dist/src/chats/analysis-provenance.js +0 -99
  454. package/dist/src/chats/analysis-shape.d.ts +0 -4
  455. package/dist/src/chats/analysis-shape.js +0 -235
  456. package/dist/src/chats/analysis.d.ts +0 -3
  457. package/dist/src/chats/analysis.js +0 -42
  458. package/dist/src/chats/corpus-input.d.ts +0 -5
  459. package/dist/src/chats/corpus-input.js +0 -288
  460. package/dist/src/chats/destination.d.ts +0 -4
  461. package/dist/src/chats/destination.js +0 -96
  462. package/dist/src/chats/import.d.ts +0 -15
  463. package/dist/src/chats/import.js +0 -243
  464. package/dist/src/chats/input-file.d.ts +0 -3
  465. package/dist/src/chats/input-file.js +0 -32
  466. package/dist/src/chats/normalize.d.ts +0 -29
  467. package/dist/src/chats/normalize.js +0 -155
  468. package/dist/src/chats/previous-import.d.ts +0 -5
  469. package/dist/src/chats/previous-import.js +0 -34
  470. package/dist/src/chats/reader.d.ts +0 -21
  471. package/dist/src/chats/reader.js +0 -118
  472. package/dist/src/chats/redact-import.d.ts +0 -14
  473. package/dist/src/chats/redact-import.js +0 -141
  474. package/dist/src/chats/redaction.d.ts +0 -41
  475. package/dist/src/chats/redaction.js +0 -161
  476. package/dist/src/chats/reference-mapping.d.ts +0 -16
  477. package/dist/src/chats/reference-mapping.js +0 -153
  478. package/dist/src/chats/revision-input.d.ts +0 -3
  479. package/dist/src/chats/revision-input.js +0 -180
  480. package/dist/src/chats/revision.d.ts +0 -48
  481. package/dist/src/chats/revision.js +0 -94
  482. package/dist/src/chats/selection.d.ts +0 -25
  483. package/dist/src/chats/selection.js +0 -109
  484. package/dist/src/chats/source.d.ts +0 -23
  485. package/dist/src/chats/source.js +0 -135
  486. package/dist/src/chats/structure.d.ts +0 -57
  487. package/dist/src/chats/structure.js +0 -216
  488. package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
  489. package/dist/src/chats/workflow-generation-projection.js +0 -75
  490. package/dist/src/chats/workflow-generation-source.d.ts +0 -25
  491. package/dist/src/chats/workflow-generation-source.js +0 -124
  492. package/dist/src/chats/workflow-generation-text.d.ts +0 -23
  493. package/dist/src/chats/workflow-generation-text.js +0 -74
  494. package/dist/src/chats/workflow-generation.d.ts +0 -69
  495. package/dist/src/chats/workflow-generation.js +0 -142
  496. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  497. package/dist/src/daemon/analysis-launch.js +0 -81
  498. package/dist/src/daemon/analysis-token.d.ts +0 -6
  499. package/dist/src/daemon/analysis-token.js +0 -88
  500. package/dist/src/daemon/analysis-worker.d.ts +0 -20
  501. package/dist/src/daemon/analysis-worker.js +0 -271
  502. package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
  503. package/dist/src/daemon/chats-batch-binding.js +0 -99
  504. package/dist/src/daemon/chats-capture.d.ts +0 -18
  505. package/dist/src/daemon/chats-capture.js +0 -194
  506. package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
  507. package/dist/src/daemon/chats-checkpoints.js +0 -186
  508. package/dist/src/daemon/chats-files.d.ts +0 -42
  509. package/dist/src/daemon/chats-files.js +0 -252
  510. package/dist/src/daemon/chats-follow-up.d.ts +0 -38
  511. package/dist/src/daemon/chats-follow-up.js +0 -180
  512. package/dist/src/daemon/chats-question.d.ts +0 -15
  513. package/dist/src/daemon/chats-question.js +0 -93
  514. package/dist/src/daemon/chats-worker.d.ts +0 -13
  515. package/dist/src/daemon/chats-worker.js +0 -201
  516. package/dist/workflows/analyze-chats.d.ts +0 -15
  517. package/dist/workflows/analyze-chats.declaration.json +0 -22
  518. package/dist/workflows/analyze-chats.js +0 -250
@@ -1,9 +1,12 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { admitCompiled } from "../cli/validate.js";
3
+ import { isCommandWaits, workflowQueueRefusals, } from "../workflow-declaration.js";
3
4
  import { ticketCommandText, ticketText } from "./ticket-source.js";
5
+ import { declaredInput } from "./declared-input.js";
4
6
  import { bundledWorkflowIds } from "../workflow-discovery.js";
5
7
  import { declaredManifest } from "../execution-pin.js";
6
8
  import { record } from "../protocol.js";
9
+ import { hasTicketField } from "../submission.js";
7
10
  import { issueIdentity } from "../issue-identity.js";
8
11
  import { ticketDependencyWaits, TicketDependencyReadError, } from "./ticket-dependency-waits.js";
9
12
  export const ticketWorkflow = bundledWorkflowIds.ticket;
@@ -155,54 +158,48 @@ export function ticketRegistrationTable(source, declarations = []) {
155
158
  submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
156
159
  resolver: promptResolver(source.repository),
157
160
  },
158
- ...declarations.map((declaration) => ({
159
- workflowId: declaration.workflowId,
160
- functionName: declaration.functionName,
161
- effectLimit: declaration.effectLimit,
162
- capabilities: declaration.capabilities,
163
- submission: declaration.input,
164
- ...(declaration.stages === undefined
165
- ? {}
166
- : { stages: declaration.stages }),
167
- ...(declaration.handoffs === undefined
168
- ? {}
169
- : { handoffs: declaration.handoffs }),
170
- resolver: declaredResolver(source.repository),
161
+ ...declarations.map(({ input, ...declaration }) => ({
162
+ ...declaration,
163
+ submission: input,
164
+ resolver: declaredResolver(source, input),
171
165
  })),
172
166
  ];
173
167
  }
174
- function declaredResolver(repository) {
168
+ function declaredResolver(source, contract) {
169
+ const tickets = hasTicketField(contract) ? issueResolver(source) : undefined;
175
170
  return {
176
171
  id: "declared-input",
177
172
  version: "1",
178
- resolve: (request) => Promise.resolve({
179
- kind: "resolved",
180
- input: {
181
- cycleId: `task-${digest(request.commandId).slice(0, 12)}`,
182
- repository,
183
- input: request.submission,
184
- },
185
- }),
173
+ ...(tickets?.skippedTickets === undefined
174
+ ? {}
175
+ : { skippedTickets: tickets.skippedTickets }),
176
+ resolve: async (request) => {
177
+ const resolution = tickets !== undefined && Object.hasOwn(request.submission, "ticket")
178
+ ? await tickets.resolve(request)
179
+ : undefined;
180
+ if (resolution?.kind === "rejected")
181
+ return resolution;
182
+ const ticket = resolution === undefined ? undefined : (record(resolution.input) ?? {});
183
+ const input = ticket === undefined
184
+ ? request.submission
185
+ : {
186
+ ...request.submission,
187
+ ticket: { id: ticket["ticketId"], text: ticket["ticket"] },
188
+ };
189
+ return {
190
+ kind: "resolved",
191
+ input: declaredInput(source.repository, {
192
+ commandId: request.commandId,
193
+ submission: input,
194
+ }),
195
+ };
196
+ },
186
197
  };
187
198
  }
188
199
  export async function ticketRegistrations(manifests, options) {
189
- const ids = new Set();
190
- for (const row of options.table) {
191
- if (ids.has(row.workflowId))
192
- return {
193
- kind: "rejected",
194
- detail: `duplicate-workflow-id: ${row.workflowId}`,
195
- };
196
- ids.add(row.workflowId);
197
- }
198
- for (const row of options.table) {
199
- const unknown = row.handoffs?.find((target) => !ids.has(target));
200
- if (unknown !== undefined)
201
- return {
202
- kind: "rejected",
203
- detail: `unknown-handoff-target: ${row.workflowId} -> ${unknown}`,
204
- };
205
- }
200
+ const refusal = registrationRefusal(options.table, options.commands ?? {});
201
+ if (refusal !== undefined)
202
+ return { kind: "rejected", detail: refusal };
206
203
  const registrations = [];
207
204
  for (const row of options.table) {
208
205
  const { functionName, capabilities = ticketCapabilities, ...registration } = row;
@@ -223,9 +220,57 @@ export async function ticketRegistrations(manifests, options) {
223
220
  };
224
221
  registrations.push({
225
222
  ...registration,
226
- manifest: declaredManifest(admission.manifest, row),
223
+ manifest: declaredManifest(admission.manifest, {
224
+ ...row,
225
+ bundleDigest: options.bundleDigest,
226
+ }),
227
227
  availability: "available",
228
228
  });
229
229
  }
230
230
  return { kind: "admitted", registrations };
231
231
  }
232
+ function registrationRefusal(table, commands) {
233
+ const queueRefusal = queueRegistrationRefusal(table);
234
+ if (queueRefusal !== undefined)
235
+ return queueRefusal;
236
+ const ids = new Set();
237
+ for (const row of table) {
238
+ if (ids.has(row.workflowId))
239
+ return `duplicate-workflow-id: ${row.workflowId}`;
240
+ ids.add(row.workflowId);
241
+ }
242
+ for (const row of table) {
243
+ const unknown = row.handoffs?.find((target) => !ids.has(target));
244
+ if (unknown !== undefined)
245
+ return `unknown-handoff-target: ${row.workflowId} -> ${unknown}`;
246
+ }
247
+ for (const row of table) {
248
+ const refusal = commandRegistrationRefusal(row, commands);
249
+ if (refusal !== undefined)
250
+ return refusal;
251
+ }
252
+ return undefined;
253
+ }
254
+ function commandRegistrationRefusal(row, commands) {
255
+ if (Object.hasOwn(row, "commandWaits") &&
256
+ !isCommandWaits(row.commandWaits, {
257
+ capabilities: row.capabilities ?? ticketCapabilities,
258
+ commands: row.commands ?? [],
259
+ }))
260
+ return `invalid-command-waits: ${row.workflowId}`;
261
+ const unknown = row.commands?.find((name) => !Object.hasOwn(commands, name));
262
+ return unknown === undefined
263
+ ? undefined
264
+ : `command-unknown: ${row.workflowId} -> ${unknown}`;
265
+ }
266
+ function queueRegistrationRefusal(table) {
267
+ const queued = table.filter((row) => row.queue === true);
268
+ if (queued.length > 1)
269
+ return `queue-workflow-conflict: ${queued.map((row) => row.workflowId).join(", ")}`;
270
+ for (const row of queued) {
271
+ const codes = workflowQueueRefusals({ queue: true, input: row.submission });
272
+ if (codes.length > 0)
273
+ return `${codes.join(", ")}: ${row.workflowId}`;
274
+ }
275
+ return undefined;
276
+ }
@@ -0,0 +1,10 @@
1
+ export interface CommandStart {
2
+ readonly output?: string | undefined;
3
+ readonly worker?: string | undefined;
4
+ readonly command: readonly string[];
5
+ readonly prompt: string;
6
+ }
7
+ export declare function turnCommand(start: CommandStart): {
8
+ readonly parts: readonly string[];
9
+ readonly standardInput: string | undefined;
10
+ };
@@ -0,0 +1,33 @@
1
+ function argumentPrompt(prompt) {
2
+ return Buffer.byteLength(prompt, "utf8") < 64 * 1024;
3
+ }
4
+ export function turnCommand(start) {
5
+ if (start.output === "text")
6
+ return {
7
+ parts: start.command.map((part) => part === "{prompt}" ? start.prompt : part),
8
+ standardInput: start.command.includes("{prompt}")
9
+ ? undefined
10
+ : start.prompt,
11
+ };
12
+ if (start.worker === "gemini" && argumentPrompt(start.prompt))
13
+ return {
14
+ parts: [...start.command, "-p", start.prompt],
15
+ standardInput: undefined,
16
+ };
17
+ if (start.worker === "opencode")
18
+ return {
19
+ parts: [...start.command, start.prompt],
20
+ standardInput: undefined,
21
+ };
22
+ if (start.worker === "cursor-agent" && argumentPrompt(start.prompt))
23
+ return {
24
+ parts: [...start.command, start.prompt],
25
+ standardInput: undefined,
26
+ };
27
+ if (start.worker !== "grok")
28
+ return { parts: start.command, standardInput: start.prompt };
29
+ const command = [...start.command];
30
+ const index = command.findIndex((argument, position) => position > 0 && ["-p", "--single"].includes(argument));
31
+ command.splice(index < 0 ? command.length : index + 1, 0, start.prompt);
32
+ return { parts: command, standardInput: undefined };
33
+ }
@@ -0,0 +1,18 @@
1
+ import { type WorkTree } from "./work-tree.ts";
2
+ import type { StreamResult } from "./claude-turn.ts";
3
+ interface ReportLimits {
4
+ readonly summaryCharacters: number;
5
+ readonly resultBytes: number;
6
+ }
7
+ export declare function turnReport(start: {
8
+ readonly harness: {
9
+ readonly worker: string;
10
+ readonly output?: "text";
11
+ };
12
+ readonly tree: WorkTree;
13
+ readonly limits: ReportLimits;
14
+ }, result: StreamResult): Promise<{
15
+ readonly text?: string;
16
+ readonly reason?: string;
17
+ }>;
18
+ export {};
@@ -0,0 +1,79 @@
1
+ import { ticketStatus } from "../ticket-status.js";
2
+ import { reviewReport } from "../review-subject.js";
3
+ import { sumPrices } from "../worker-usage.js";
4
+ import { changes } from "./work-tree.js";
5
+ function tailReport(fields, limit) {
6
+ let text = JSON.stringify({ ...fields, summary: "" });
7
+ if (Buffer.byteLength(text) > limit)
8
+ return undefined;
9
+ let minimum = 1;
10
+ let maximum = fields.summary.length;
11
+ while (minimum <= maximum) {
12
+ const kept = Math.floor((minimum + maximum) / 2);
13
+ const candidate = JSON.stringify({
14
+ ...fields,
15
+ summary: fields.summary.slice(-kept),
16
+ });
17
+ if (Buffer.byteLength(candidate) > limit) {
18
+ maximum = kept - 1;
19
+ continue;
20
+ }
21
+ text = candidate;
22
+ minimum = kept + 1;
23
+ }
24
+ return text;
25
+ }
26
+ function boundedReport(fields, options) {
27
+ const text = JSON.stringify(fields);
28
+ const excess = Buffer.byteLength(text) - options.limit;
29
+ if (excess <= 0)
30
+ return { text };
31
+ if (options.output === "text") {
32
+ const shortened = tailReport(fields, options.limit);
33
+ return shortened === undefined
34
+ ? { reason: "claude-result-too-large" }
35
+ : { text: shortened };
36
+ }
37
+ const kept = Math.max(0, fields.summary.length - excess);
38
+ const shortened = JSON.stringify({
39
+ ...fields,
40
+ summary: fields.summary.slice(0, kept),
41
+ });
42
+ if (Buffer.byteLength(shortened) <= options.limit)
43
+ return { text: shortened };
44
+ const metadata = JSON.stringify({
45
+ ...fields,
46
+ ticketStatus: undefined,
47
+ summary: "",
48
+ });
49
+ return {
50
+ reason: "claude-result-too-large",
51
+ ...(Buffer.byteLength(metadata) <= options.limit ? { text: metadata } : {}),
52
+ };
53
+ }
54
+ export async function turnReport(start, result) {
55
+ if (result.ticketStatusTooLarge === true)
56
+ return { reason: "claude-result-too-large" };
57
+ const { harness, tree, limits } = start;
58
+ const review = reviewReport(result.text);
59
+ const feedback = result.reviewFeedback ?? review.feedback;
60
+ return boundedReport({
61
+ harness: harness.worker,
62
+ ticketStatus: ticketStatus(result.text, result.ticketStatus),
63
+ reviewVerdict: result.reviewVerdict === undefined
64
+ ? review.reviewVerdict
65
+ : result.reviewVerdict,
66
+ summary: harness.output === "text"
67
+ ? feedback.slice(-limits.summaryCharacters)
68
+ : feedback.slice(0, limits.summaryCharacters),
69
+ ...(await changes(tree)),
70
+ worktree: tree.path,
71
+ costUsd: result.costUsd,
72
+ usage: result.usage,
73
+ model: result.model,
74
+ ...(result.attempts === undefined ? {} : { attempts: result.attempts }),
75
+ estimatedCostUsd: sumPrices((result.attempts ?? []).map((attempt) => attempt.estimatedCostUsd)),
76
+ sessionId: result.sessionId,
77
+ turns: result.turns,
78
+ }, { ...harness, limit: limits.resultBytes });
79
+ }
@@ -12,9 +12,10 @@ export interface TreeRequest {
12
12
  }
13
13
  export interface Changes {
14
14
  readonly branch: string;
15
+ readonly commit: string | null;
15
16
  readonly commits: readonly string[];
16
17
  readonly files: readonly string[];
17
- readonly uncommitted: readonly string[];
18
+ readonly uncommitted: readonly string[] | null;
18
19
  }
19
20
  export declare function treeName(target: string): string;
20
21
  export declare function treePlace(request: Pick<TreeRequest, "worktrees" | "target">): {
@@ -186,21 +186,24 @@ export function treeFailure(error) {
186
186
  : "work-tree-not-available";
187
187
  }
188
188
  export async function changes(tree) {
189
- const lines = async (parts) => (await git({ directory: tree.path, parts }).catch(() => ""))
190
- .split("\n")
191
- .filter((line) => line.trim() !== "")
192
- .slice(0, lineLimit)
193
- .map((line) => line.slice(0, lineLength));
189
+ const lines = (parts) => changeLines({ directory: tree.path, parts });
194
190
  const range = `${tree.startCommit}..HEAD`;
195
- const [branch = tree.branch] = await lines([
196
- "rev-parse",
197
- "--abbrev-ref",
198
- "HEAD",
199
- ]);
191
+ const branch = (await lines(["rev-parse", "--abbrev-ref", "HEAD"]))?.[0] ?? tree.branch;
200
192
  return {
201
193
  branch,
202
- commits: await lines(["log", "--oneline", range]),
203
- files: await lines(["diff", "--stat", range]),
194
+ commit: (await lines(["rev-parse", "HEAD"]))?.[0] ?? null,
195
+ commits: (await lines(["log", "--oneline", range])) ?? [],
196
+ files: (await lines(["diff", "--stat", range])) ?? [],
204
197
  uncommitted: await lines(["status", "--short"]),
205
198
  };
206
199
  }
200
+ async function changeLines(call) {
201
+ const output = await git(call).catch(() => null);
202
+ if (output === null)
203
+ return null;
204
+ return output
205
+ .split("\n")
206
+ .filter((line) => line.trim() !== "")
207
+ .slice(0, lineLimit)
208
+ .map((line) => line.slice(0, lineLength));
209
+ }
@@ -0,0 +1,32 @@
1
+ import type { HostPorts } from "../service/service.ts";
2
+ import type { WorkflowFunction } from "../host/start-delivery.ts";
3
+ import type { WorkflowHandler } from "../host/world-host.ts";
4
+ import type { ExecutionManifest } from "../workflow-admission.ts";
5
+ import { type WorkflowRegistration } from "../service/registry.ts";
6
+ export interface WorkflowGeneration {
7
+ readonly workflows: Readonly<Record<string, unknown>>;
8
+ readonly handler: WorkflowHandler;
9
+ }
10
+ export type WorkflowBundleLoader = (directory: string) => Promise<WorkflowGeneration>;
11
+ export declare function workflowGenerations(settings: {
12
+ readonly directory: string;
13
+ readonly repository: string;
14
+ readonly registrations: readonly WorkflowRegistration[];
15
+ readonly table: readonly {
16
+ readonly workflowId: string;
17
+ readonly functionName: string;
18
+ }[];
19
+ readonly workflows: Readonly<Record<string, WorkflowFunction | undefined>>;
20
+ readonly handler: WorkflowHandler;
21
+ readonly loadBundle?: WorkflowBundleLoader;
22
+ }): {
23
+ resolve: (manifest: ExecutionManifest | undefined) => Promise<{
24
+ workflow: WorkflowFunction;
25
+ handler: WorkflowHandler;
26
+ } | undefined>;
27
+ available: (manifest: ExecutionManifest) => Promise<ExecutionManifest | undefined>;
28
+ };
29
+ export declare function prepareWorkflowGenerations(ports: {
30
+ readonly state: HostPorts["state"];
31
+ readonly workflow: Pick<HostPorts["workflow"], "manifest">;
32
+ }, generations: Pick<ReturnType<typeof workflowGenerations>, "resolve">): Promise<void>;
@@ -0,0 +1,57 @@
1
+ import { join } from "node:path";
2
+ import { workflowRegistry, } from "../service/registry.js";
3
+ import { workflowPin } from "../broker/workflow-pin.js";
4
+ export function workflowGenerations(settings) {
5
+ const functions = Object.fromEntries(settings.table.map((row) => [
6
+ row.workflowId,
7
+ settings.workflows[row.functionName],
8
+ ]));
9
+ const registry = workflowRegistry(settings.registrations, {
10
+ workflowBundles: {
11
+ directory: join(settings.directory, "workflow-bundles"),
12
+ repository: settings.repository,
13
+ },
14
+ });
15
+ const resolve = async (manifest) => {
16
+ if (manifest === undefined)
17
+ return undefined;
18
+ const registered = registry.byPin(workflowPin(manifest));
19
+ if (registered !== undefined) {
20
+ const workflow = functions[registered.workflowId];
21
+ return workflow === undefined
22
+ ? undefined
23
+ : { workflow, handler: settings.handler };
24
+ }
25
+ if (manifest.bundleDigest === undefined ||
26
+ settings.loadBundle === undefined)
27
+ return undefined;
28
+ const directory = await registry.bundle(manifest);
29
+ if (directory === undefined)
30
+ return undefined;
31
+ try {
32
+ const generation = await settings.loadBundle(directory);
33
+ const workflow = Object.values(generation.workflows).find((candidate) => typeof candidate === "function" &&
34
+ Reflect.get(candidate, "workflowId") === manifest.workflowId);
35
+ return workflow === undefined
36
+ ? undefined
37
+ : { workflow, handler: generation.handler };
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ };
43
+ return {
44
+ resolve,
45
+ available: async (manifest) => (await resolve(manifest)) === undefined ? undefined : manifest,
46
+ };
47
+ }
48
+ export async function prepareWorkflowGenerations(ports, generations) {
49
+ const prepared = new Set();
50
+ for (const run of Object.values((await ports.state()).runs)) {
51
+ if (["completed", "failed", "cancelled"].includes(run.status) ||
52
+ prepared.has(run.workflow))
53
+ continue;
54
+ prepared.add(run.workflow);
55
+ await generations.resolve(await ports.workflow.manifest(run.runId));
56
+ }
57
+ }
@@ -0,0 +1,16 @@
1
+ import type { WorkflowHandler } from "../host/world-host.ts";
2
+ import type { AuthorityState } from "../authority/transitions.ts";
3
+ interface ReplayRun {
4
+ readonly runId: string;
5
+ readonly workflowId?: string;
6
+ }
7
+ interface ReplayPorts {
8
+ readonly state: () => Promise<Pick<AuthorityState, "details">>;
9
+ readonly run: (receipt: string) => Promise<ReplayRun | undefined>;
10
+ readonly available: (runId: string, workflowId?: string) => Promise<boolean>;
11
+ readonly submit: (command: Readonly<Record<string, unknown>>) => Promise<{
12
+ readonly kind: "accepted" | "duplicate" | "failed" | "rejected";
13
+ }>;
14
+ }
15
+ export declare function pinnedWorkflowHandler(handler: (request: Request, runId: string) => Promise<Response>, ports: ReplayPorts): WorkflowHandler;
16
+ export {};
@@ -0,0 +1,58 @@
1
+ import { record } from "../protocol.js";
2
+ import { setTimeout as delay } from "node:timers/promises";
3
+ function seeded(value) {
4
+ const input = record(record(value)?.["runInput"]);
5
+ const runId = record(input?.["attributes"])?.["cloving.run"];
6
+ const workflowId = input?.["workflowName"];
7
+ return typeof runId === "string" && typeof workflowId === "string"
8
+ ? { runId, workflowId }
9
+ : undefined;
10
+ }
11
+ async function located(ports, receipt) {
12
+ for (let attempt = 0; attempt < 20; attempt += 1) {
13
+ const run = await ports.run(receipt);
14
+ if (run !== undefined)
15
+ return run;
16
+ await delay(5);
17
+ }
18
+ return undefined;
19
+ }
20
+ async function observedReplay(ports, replay) {
21
+ const { runId, receipt, available } = replay;
22
+ const observation = (await ports.state()).details[runId]?.observation;
23
+ const unavailable = observation?.reason === "pinned-workflow-unavailable";
24
+ if (available !== unavailable)
25
+ return true;
26
+ const expectedObservation = observation?.sequence ?? 0;
27
+ const outcome = await ports.submit({
28
+ kind: "report-observation",
29
+ runId,
30
+ commandId: `pinned-workflow-${available ? "restored" : "unavailable"}:${receipt}:${String(expectedObservation)}`,
31
+ condition: available ? "working" : "infrastructure-failure",
32
+ reason: available ? "in-progress" : "pinned-workflow-unavailable",
33
+ expectedObservation,
34
+ });
35
+ return outcome.kind === "accepted" || outcome.kind === "duplicate";
36
+ }
37
+ export function pinnedWorkflowHandler(handler, ports) {
38
+ return async (request) => {
39
+ const value = await request
40
+ .clone()
41
+ .json()
42
+ .catch(() => undefined);
43
+ const receipt = record(value)?.["runId"];
44
+ if (typeof receipt !== "string")
45
+ return new Response("invalid-workflow-message", { status: 400 });
46
+ const run = (await ports.run(receipt)) ??
47
+ seeded(value) ??
48
+ (await located(ports, receipt));
49
+ if (run === undefined)
50
+ return new Response("unknown-world-run", { status: 503 });
51
+ const available = await ports.available(run.runId, run.workflowId);
52
+ if (!(await observedReplay(ports, { runId: run.runId, receipt, available })))
53
+ return new Response("workflow-observation-unavailable", { status: 503 });
54
+ if (available)
55
+ return handler(request, run.runId);
56
+ return new Response("pinned-workflow-unavailable", { status: 503 });
57
+ };
58
+ }
@@ -0,0 +1,27 @@
1
+ import type { WorkerPort } from "../service/worker-port.ts";
2
+ import type { DeclaredWorkflow } from "../workflow-declaration.ts";
3
+ interface ScheduleSettings {
4
+ readonly directory: string;
5
+ readonly runtimeDirectory: string;
6
+ readonly declarations?: readonly DeclaredWorkflow[];
7
+ readonly scheduleClock?: () => number;
8
+ readonly submit: WorkerPort["submit"];
9
+ }
10
+ export declare function scheduledDeclarations(settings: {
11
+ readonly declarations?: readonly DeclaredWorkflow[];
12
+ readonly schedules?: unknown;
13
+ }, limits?: {
14
+ readonly repository: string;
15
+ readonly documentBytes: number;
16
+ }): {
17
+ readonly kind: "configured";
18
+ readonly declarations: readonly DeclaredWorkflow[];
19
+ } | {
20
+ readonly kind: "refused";
21
+ readonly reason: string;
22
+ readonly detail: string;
23
+ };
24
+ export declare function workflowSchedules(settings: ScheduleSettings): Promise<{
25
+ readonly stop: () => Promise<void>;
26
+ }>;
27
+ export {};