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
@@ -1,28 +1,10 @@
1
1
  import { existsSync } from "node:fs";
2
- import { setTimeout as delay } from "node:timers/promises";
3
2
  import { readRecord, writeRecord } from "./operation-journal.js";
4
- import { changeChecked, defaultBranch, existingTree, field, githubTiming, removeWorktree, repositoryPath, } from "./github-operation.js";
3
+ import { changeChecked, defaultBranch, existingTree, field, removeWorktree, repositoryPath, } from "./github-operation.js";
5
4
  import { treePlace } from "./work-tree.js";
6
- function commitOf(value, name) {
7
- if (typeof value !== "object" || value === null)
8
- throw new Error("github-call-failed");
9
- const commit = Reflect.get(value, name);
10
- if (typeof commit !== "string")
11
- throw new Error("github-call-failed");
12
- return commit;
13
- }
14
- async function knownMerge(operation, expected) {
15
- const pull = JSON.parse(await operation.calls.gh([
16
- "api",
17
- `${repositoryPath}/pulls/${String(expected.number)}`,
18
- ]));
19
- const head = commitOf(field(pull, "head"), "sha");
20
- if (field(pull, "merged") !== true)
21
- return { head, merged: undefined };
22
- if (head !== expected.commit && head !== expected.updated)
23
- throw new Error("merged-other-commit");
24
- return { head, merged: commitOf(pull, "merge_commit_sha") };
25
- }
5
+ import { waitForCi } from "./github-ci.js";
6
+ import { githubText } from "./github-calls.js";
7
+ import { knownMerge, mergePull, } from "./github-merge-call.js";
26
8
  async function abortMerge(operation, tree) {
27
9
  const path = (await operation.calls.git(tree.path, [
28
10
  "rev-parse",
@@ -69,25 +51,31 @@ async function updatedTree(operation, place) {
69
51
  place.base,
70
52
  ]);
71
53
  }
72
- catch {
54
+ catch (error) {
73
55
  const conflicts = await calls.git(place.tree.path, [
74
56
  "diff",
75
57
  "--name-only",
76
58
  "--diff-filter=U",
77
59
  ]);
78
60
  await calls.git(place.tree.path, ["merge", "--abort"]);
79
- throw new Error("merge-conflict", { cause: conflicts.trim() });
61
+ const output = commandOutput(error instanceof Error ? error.cause : error);
62
+ throw Object.assign(new Error("merge-conflict", { cause: error }), {
63
+ output: githubText(output + conflicts, operation.settings)
64
+ .slice(-6_000)
65
+ .trim(),
66
+ });
80
67
  }
81
68
  }
82
69
  async function checked(operation, place) {
83
70
  await changeChecked(operation, place);
84
71
  const head = await headOf(operation, place.tree);
85
- if (operation.settings.check !== undefined)
86
- await operation.calls.run(operation.settings.check, place.tree.path);
72
+ const command = place.check === null ? undefined : operation.settings.check;
73
+ if (command !== undefined)
74
+ await operation.calls.run(command, place.tree.path);
87
75
  await clean(operation, place.tree);
88
76
  if ((await headOf(operation, place.tree)) !== head)
89
77
  throw new Error("uncommitted-change");
90
- if (head !== place.commit && operation.settings.check === undefined)
78
+ if (head !== place.commit && command === undefined && place.check !== null)
91
79
  throw new Error("check-required");
92
80
  return head;
93
81
  }
@@ -115,52 +103,6 @@ async function refreshed(operation, place) {
115
103
  }
116
104
  throw new Error("base-moved");
117
105
  }
118
- async function mergedNow(operation, pull) {
119
- const reply = JSON.parse(await operation.calls.gh([
120
- "api",
121
- "-X",
122
- "PUT",
123
- `${repositoryPath}/pulls/${String(pull.number)}/merge`,
124
- "-f",
125
- "merge_method=merge",
126
- "-f",
127
- `sha=${pull.commit}`,
128
- ]));
129
- return commitOf(reply, "sha");
130
- }
131
- async function waitForHead(operation, pull) {
132
- const timing = operation.settings.timing ?? githubTiming;
133
- for (let attempt = 0; attempt < 30; attempt += 1) {
134
- if (attempt > 0)
135
- await delay(timing.pollMilliseconds, undefined, {
136
- signal: operation.signal,
137
- });
138
- const current = JSON.parse(await operation.calls.gh([
139
- "api",
140
- `${repositoryPath}/pulls/${String(pull.number)}`,
141
- ]));
142
- if (commitOf(field(current, "head"), "sha") === pull.commit)
143
- return;
144
- }
145
- throw new Error("head-not-updated");
146
- }
147
- async function mergeUpdated(operation, pull) {
148
- const timing = operation.settings.timing ?? githubTiming;
149
- for (let attempt = 0;; attempt += 1) {
150
- await waitForHead(operation, pull);
151
- try {
152
- return await mergedNow(operation, pull);
153
- }
154
- catch (error) {
155
- const status = field(error, "status");
156
- if (attempt === 2 || (status !== 405 && status !== 409))
157
- throw error;
158
- await delay(timing.pollMilliseconds, undefined, {
159
- signal: operation.signal,
160
- });
161
- }
162
- }
163
- }
164
106
  async function removed(operation, place) {
165
107
  const { settings, calls } = operation;
166
108
  await calls
@@ -191,37 +133,52 @@ async function recordedHead(operation, commit) {
191
133
  }
192
134
  async function readyHead(operation, pull) {
193
135
  const tree = existingTree(operation);
194
- const updated = await refreshed(operation, {
195
- tree,
196
- commit: pull.commit,
197
- recorded: pull.recorded,
198
- });
199
- if (updated === pull.commit)
200
- return updated;
201
- if (pull.recorded !== updated)
202
- await writeRecord(operation.folder, {
203
- name: "updated-head.json",
204
- value: { commit: pull.commit, updated },
136
+ let recorded = pull.recorded;
137
+ let remote = pull.remote;
138
+ for (let attempt = 0; attempt < 3; attempt += 1) {
139
+ const updated = await refreshed(operation, {
140
+ tree,
141
+ commit: pull.commit,
142
+ recorded,
143
+ check: pull.check,
205
144
  });
206
- if (pull.remote !== updated)
207
- await operation.calls.git(tree.path, [
208
- "push",
209
- "--quiet",
210
- "origin",
211
- `${updated}:refs/heads/${tree.branch}`,
212
- ]);
213
- return updated;
145
+ if (updated !== pull.commit && recorded !== updated)
146
+ await writeRecord(operation.folder, {
147
+ name: "updated-head.json",
148
+ value: { commit: pull.commit, updated },
149
+ });
150
+ if (updated !== pull.commit && remote !== updated)
151
+ await operation.calls.git(tree.path, [
152
+ "push",
153
+ "--quiet",
154
+ "origin",
155
+ `${updated}:refs/heads/${tree.branch}`,
156
+ ]);
157
+ const ci = await waitForCi(operation, updated);
158
+ if (ci !== undefined)
159
+ return ci;
160
+ const newest = await fetched(operation, await defaultBranch(operation));
161
+ if ((await operation.calls.git(tree.path, ["merge-base", updated, newest])).trim() === newest)
162
+ return updated;
163
+ recorded = updated;
164
+ remote = updated;
165
+ }
166
+ throw new Error("base-moved");
214
167
  }
215
168
  function checkOutput(cause) {
169
+ return commandOutput(cause).slice(-6_000);
170
+ }
171
+ function commandOutput(cause) {
216
172
  return ["stdout", "stderr"]
217
173
  .map((name) => {
218
174
  const value = field(cause, name);
219
175
  return typeof value === "string" ? value : "";
220
176
  })
221
- .join("")
222
- .slice(-6_000);
177
+ .join("");
223
178
  }
224
179
  export async function merge(operation, pull) {
180
+ if (pull.check === "beforeMerge" && operation.settings.check === undefined)
181
+ throw new Error("check-not-configured");
225
182
  try {
226
183
  return await completedMerge(operation, pull);
227
184
  }
@@ -232,10 +189,13 @@ export async function merge(operation, pull) {
232
189
  const reason = error.message;
233
190
  if (reason !== "check-failed" && reason !== "merge-conflict")
234
191
  throw error;
235
- const conflicts = typeof error.cause === "string" ? error.cause : "";
192
+ const detail = field(error, "output");
193
+ const conflicts = typeof detail === "string" ? detail : "";
236
194
  return {
237
195
  reason,
238
- output: reason === "check-failed" ? checkOutput(error.cause) : conflicts,
196
+ output: reason === "check-failed"
197
+ ? checkOutput(error.cause)
198
+ : githubText(conflicts, operation.settings),
239
199
  };
240
200
  }
241
201
  }
@@ -252,8 +212,9 @@ async function completedMerge(operation, pull) {
252
212
  const updated = known.merged === undefined
253
213
  ? await readyHead(operation, { ...pull, recorded, remote: known.head })
254
214
  : (recorded ?? pull.commit);
255
- const mergeCall = updated === pull.commit ? mergedNow : mergeUpdated;
256
- const merged = known.merged ?? (await mergeCall(operation, { ...pull, commit: updated }));
215
+ if (typeof updated !== "string")
216
+ return updated;
217
+ const merged = known.merged ?? (await mergePull(operation, { ...pull, updated }));
257
218
  await removed(operation, place);
258
219
  return { number: pull.number, commit: pull.commit, updated, merged };
259
220
  }
@@ -1,5 +1,33 @@
1
+ import { type Finding, type Scored } from "./github-calls.ts";
1
2
  import { type Operation } from "./github-operation.ts";
2
3
  export type { GithubTiming, MethodSettings } from "./github-operation.ts";
3
4
  export declare const methodReasons: ReadonlySet<string>;
5
+ export interface ReviewResult extends Scored {
6
+ readonly number: number;
7
+ readonly commit: string;
8
+ readonly findings: readonly Finding[];
9
+ }
10
+ interface ReviewFailure {
11
+ readonly call: "read-review" | "request-review";
12
+ readonly reason: "github-call-failed" | "invalid-review-response";
13
+ readonly status?: number;
14
+ }
15
+ interface ReviewClock {
16
+ readonly now: () => number;
17
+ readonly sleep: (milliseconds: number, signal: AbortSignal) => Promise<void>;
18
+ }
19
+ interface ReviewWait {
20
+ readonly clock: ReviewClock;
21
+ failedReads: number;
22
+ requests: number;
23
+ acceptedRequests: number;
24
+ requestedAt: number;
25
+ lastFailure: ReviewFailure | null;
26
+ }
27
+ export declare class ReviewTimeout extends Error {
28
+ readonly detail: string;
29
+ constructor(wait: ReviewWait);
30
+ }
31
+ export declare function waitReview(operation: Operation, clock?: ReviewClock): Promise<ReviewResult>;
4
32
  export type Method = (operation: Operation) => Promise<unknown>;
5
33
  export declare const methods: ReadonlyMap<string, Method>;
@@ -1,22 +1,27 @@
1
1
  import { setTimeout as delay } from "node:timers/promises";
2
- import { findingsOf, scoreOf } from "./github-calls.js";
2
+ import { appendFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { findingsOf, scoreOf, } from "./github-calls.js";
3
5
  import { closeIssue, partialIssue } from "./github-ticket-status.js";
4
6
  import { merge } from "./github-merge.js";
5
7
  import { createIssue, discard } from "./github-issue-methods.js";
6
8
  import { existingTree, defaultBranch, changeChecked, field, githubTiming, repositoryPath, text, } from "./github-operation.js";
7
9
  import { workTree } from "./work-tree.js";
8
10
  const triggerText = "@greptileai";
11
+ const maximumReviewRequests = 3;
9
12
  export const methodReasons = new Set([
10
13
  "draft-not-available",
11
14
  "invalid-draft",
12
15
  "post-uncertain",
13
16
  "private-texts-not-set",
14
17
  "github-call-failed",
18
+ "github-network-failed",
15
19
  "github-issue-conflict",
16
20
  "git-call-failed",
17
21
  "check-failed",
18
22
  "merge-conflict",
19
23
  "check-required",
24
+ "check-not-configured",
20
25
  "base-moved",
21
26
  "head-not-updated",
22
27
  "uncommitted-change",
@@ -33,6 +38,14 @@ function integer(operation, name) {
33
38
  throw new Error("invalid-payload");
34
39
  return value;
35
40
  }
41
+ function mergeCheck(operation) {
42
+ if (!Object.hasOwn(operation.payload, "check"))
43
+ return undefined;
44
+ const value = operation.payload["check"];
45
+ if (value === null || value === "beforeMerge")
46
+ return value;
47
+ throw new Error("invalid-payload");
48
+ }
36
49
  async function prepare(operation) {
37
50
  const { settings, calls, target, signal } = operation;
38
51
  await calls.git(settings.repository, ["fetch", "--quiet", "origin"]);
@@ -157,30 +170,90 @@ async function reviewed(operation, pull) {
157
170
  const lines = await read(`pulls/${String(number)}/comments?per_page=100`);
158
171
  return { number, commit, ...scored, findings: findingsOf(lines, commit) };
159
172
  }
160
- async function waitReview(operation) {
173
+ const reviewClock = {
174
+ now: () => Date.now(),
175
+ sleep: async (milliseconds, signal) => {
176
+ await delay(milliseconds, undefined, { signal });
177
+ },
178
+ };
179
+ export class ReviewTimeout extends Error {
180
+ detail;
181
+ constructor(wait) {
182
+ super("review-not-received");
183
+ this.detail = JSON.stringify({
184
+ failedReads: wait.failedReads,
185
+ requests: wait.requests,
186
+ acceptedRequests: wait.acceptedRequests,
187
+ lastFailure: wait.lastFailure,
188
+ });
189
+ }
190
+ }
191
+ async function reviewFailure(operation, failed) {
192
+ const { wait, call, error } = failed;
193
+ const status = field(error, "status");
194
+ const failure = {
195
+ call,
196
+ reason: error instanceof SyntaxError
197
+ ? "invalid-review-response"
198
+ : "github-call-failed",
199
+ ...(typeof status === "number" &&
200
+ Number.isInteger(status) &&
201
+ status >= 400 &&
202
+ status <= 599
203
+ ? { status }
204
+ : {}),
205
+ };
206
+ wait.lastFailure = failure;
207
+ await appendFile(join(operation.folder, "review-failures.jsonl"), JSON.stringify(failure) + "\n", { mode: 0o600 }).catch(() => undefined);
208
+ }
209
+ async function requestReview(operation, request) {
210
+ const { wait, number } = request;
211
+ wait.requests++;
212
+ try {
213
+ await operation.calls.gh([
214
+ "pr",
215
+ "comment",
216
+ String(number),
217
+ "--body",
218
+ triggerText,
219
+ ]);
220
+ wait.acceptedRequests++;
221
+ wait.requestedAt = wait.clock.now();
222
+ }
223
+ catch (error) {
224
+ await reviewFailure(operation, { wait, call: "request-review", error });
225
+ }
226
+ }
227
+ export async function waitReview(operation, clock = reviewClock) {
161
228
  const pull = {
162
229
  number: integer(operation, "number"),
163
230
  commit: text(operation, "commit"),
164
231
  };
165
232
  const timing = operation.settings.timing ?? githubTiming;
166
- const startedAt = Date.now();
167
- let triggered = false;
233
+ const startedAt = clock.now();
234
+ const wait = {
235
+ clock,
236
+ failedReads: 0,
237
+ requests: 0,
238
+ acceptedRequests: 0,
239
+ requestedAt: startedAt,
240
+ lastFailure: null,
241
+ };
168
242
  for (;;) {
169
- const review = await reviewed(operation, pull).catch(() => undefined);
243
+ const review = await reviewed(operation, pull).catch(async (error) => {
244
+ wait.failedReads++;
245
+ await reviewFailure(operation, { wait, call: "read-review", error });
246
+ return undefined;
247
+ });
170
248
  if (review !== undefined)
171
249
  return review;
172
- const waited = Date.now() - startedAt;
250
+ const waited = clock.now() - startedAt;
173
251
  if (waited >= timing.limitMilliseconds)
174
- throw new Error("review-not-received");
175
- if (!triggered && waited >= timing.triggerMilliseconds) {
176
- triggered = true;
177
- await operation.calls
178
- .gh(["pr", "comment", String(pull.number), "--body", triggerText])
179
- .catch(() => undefined);
180
- }
181
- await delay(timing.pollMilliseconds, undefined, {
182
- signal: operation.signal,
183
- });
252
+ throw new ReviewTimeout(wait);
253
+ if (wait.acceptedRequests < maximumReviewRequests &&
254
+ clock.now() - wait.requestedAt >= timing.triggerMilliseconds)
255
+ await requestReview(operation, { wait, number: pull.number });
256
+ await clock.sleep(timing.pollMilliseconds, operation.signal);
184
257
  }
185
258
  }
186
259
  export const methods = new Map([
@@ -197,6 +270,7 @@ export const methods = new Map([
197
270
  (operation) => merge(operation, {
198
271
  number: integer(operation, "number"),
199
272
  commit: text(operation, "commit"),
273
+ check: mergeCheck(operation),
200
274
  }),
201
275
  ],
202
276
  ]);
@@ -3,11 +3,14 @@ export interface GithubTiming {
3
3
  readonly pollMilliseconds: number;
4
4
  readonly triggerMilliseconds: number;
5
5
  readonly limitMilliseconds: number;
6
+ readonly ciLimitMilliseconds?: number;
7
+ readonly ciGraceMilliseconds?: number;
6
8
  }
7
9
  export declare const githubTiming: GithubTiming;
8
10
  export interface MethodSettings extends CallSettings {
9
11
  readonly worktrees: string;
10
12
  readonly timing?: GithubTiming;
13
+ readonly requiredChecks?: readonly string[] | null;
11
14
  readonly check?: readonly string[];
12
15
  }
13
16
  export interface Operation {
@@ -0,0 +1,6 @@
1
+ import { type Operation } from "./github-operation.ts";
2
+ export declare function retryGithub<Result>(operation: Operation, retry: {
3
+ readonly action: (attempt: number) => Promise<Result>;
4
+ readonly statuses?: readonly number[];
5
+ }): Promise<Result>;
6
+ export declare function githubRead(operation: Operation, parts: readonly string[]): Promise<string>;
@@ -0,0 +1,13 @@
1
+ import { githubRetry } from "../cli/github-retry.js";
2
+ import { githubTiming } from "./github-operation.js";
3
+ export function retryGithub(operation, retry) {
4
+ return githubRetry({
5
+ ...retry,
6
+ signal: operation.signal,
7
+ pollMilliseconds: (operation.settings.timing ?? githubTiming)
8
+ .pollMilliseconds,
9
+ });
10
+ }
11
+ export function githubRead(operation, parts) {
12
+ return retryGithub(operation, { action: () => operation.calls.gh(parts) });
13
+ }
@@ -87,12 +87,38 @@ function statusText(history) {
87
87
  lines.push(`Completed in pull request #${String(history.completedPullRequest)}.`);
88
88
  return `## Cloving status\n${lines.join("\n")}\n\n`;
89
89
  }
90
+ function legacyFence(line) {
91
+ const marker = /^( {0,3}(?:[-+*]|\d{1,9}[.)])[ \t]+)? {0,3}(`{3,}|~{3,})/.exec(line);
92
+ if (marker === null || marker[2] === undefined)
93
+ return undefined;
94
+ const delimiter = marker[2];
95
+ if (delimiter.startsWith("`") && line.slice(marker[0].length).includes("`"))
96
+ return undefined;
97
+ const indentation = (marker[1]?.length ?? 0) + 3;
98
+ return new RegExp(`^ {0,${String(indentation)}}${delimiter.charAt(0)}{${String(delimiter.length)},}[ \\t]*\\r?\\n?$`);
99
+ }
100
+ function legacyStatusStart(body) {
101
+ let fence;
102
+ let offset = 0;
103
+ for (const line of body.split(/(?<=\n)/)) {
104
+ const start = offset;
105
+ offset += line.length;
106
+ if (fence !== undefined) {
107
+ fence = fence.test(line) ? undefined : fence;
108
+ continue;
109
+ }
110
+ if (line.trimEnd() === "## Cloving status")
111
+ return start;
112
+ fence = legacyFence(line);
113
+ }
114
+ return body.length;
115
+ }
90
116
  function statusSection(body) {
91
117
  const empty = { version: 1, partialRuns: [] };
92
118
  const marker = /^<!-- cloving-status(?=\s|-->|$)/gm;
93
119
  const start = [...body.matchAll(marker)].at(-1)?.index;
94
120
  if (start === undefined)
95
- return { outside: body, history: empty };
121
+ return { outside: body.slice(0, legacyStatusStart(body)), history: empty };
96
122
  const tail = body.slice(start);
97
123
  const end = tail.indexOf("-->");
98
124
  if (end !== -1 && tail.slice(end + 3).trim() !== "")
@@ -1,7 +1,7 @@
1
1
  import { readdir } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
  import { calls } from "./github-calls.js";
4
- import { methodReasons, methods, } from "./github-methods.js";
4
+ import { methodReasons, methods, ReviewTimeout, } from "./github-methods.js";
5
5
  import { interrupted, located, readRecord, replied, reportOf, writeRecord, } from "./operation-journal.js";
6
6
  const worker = "github";
7
7
  const closing = "github-worker-closed";
@@ -62,6 +62,7 @@ async function outcome(parts, run) {
62
62
  return {
63
63
  ...interrupted(methodReasons.has(reason) ? reason : "github-call-failed"),
64
64
  ...(typeof detail === "string" ? { detail } : {}),
65
+ ...(error instanceof ReviewTimeout ? { result: error.detail } : {}),
65
66
  };
66
67
  }
67
68
  }
@@ -0,0 +1,10 @@
1
+ import type { EffectDelivery } from "./delivery-router.ts";
2
+ interface Settings {
3
+ readonly runtimeDirectory: string;
4
+ readonly journal: string;
5
+ readonly document: (digest: string) => Promise<string | undefined>;
6
+ readonly runStatus: (runId: string) => Promise<string | undefined>;
7
+ readonly retryMilliseconds?: number;
8
+ }
9
+ export declare function handoffWorker(settings: Settings): EffectDelivery;
10
+ export {};