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,10 +1,14 @@
1
1
  import { join } from "node:path";
2
2
  import { mkdir } from "node:fs/promises";
3
3
  import { setTimeout as delay } from "node:timers/promises";
4
- import { priceOf, sumUsage, usageOf } from "../worker-usage.js";
5
- import { capacityRefusal, startTurn, } from "./claude-turn.js";
4
+ import { priceOf, sumUsage, usageOf, } from "../worker-usage.js";
5
+ import { commandModel, replaceCommandModel, estimatedCostUsd, priceForModel, } from "../token-prices.js";
6
+ import { capacityRefusal, retryKind, startTurn, } from "./claude-turn.js";
7
+ import { turnHead, retryEvidence, indexFailure } from "./retry-worktree.js";
6
8
  import { readRecord, writeRecord } from "./operation-journal.js";
7
- const waits = [60_000, 180_000];
9
+ import { nativeHarness } from "../harness-defaults.js";
10
+ const waits = { capacity: [60_000, 180_000], network: [600_000, 2_400_000] };
11
+ const networkContinuation = "An earlier attempt stopped because the network was not available. Continue from the current state of the work tree. Check each earlier commit, push, review comment and message. Do not repeat a write that is done. Stop and report a write whose result is not known.";
8
12
  const continuation = "An earlier attempt stopped because the model was at capacity; continue from the current state of the work tree.\n\n";
9
13
  function written(folder, entry) {
10
14
  return writeRecord(folder, { ...entry, permissions: "private" });
@@ -14,10 +18,9 @@ function total(values) {
14
18
  return null;
15
19
  return priceOf(values.reduce((sum, value) => sum + (value ?? 0), 0));
16
20
  }
17
- function combined(ends) {
21
+ function combined(attempts) {
22
+ const { ends } = attempts;
18
23
  const last = ends.at(-1) ?? { exitCode: null, result: undefined };
19
- if (ends.length < 2)
20
- return last;
21
24
  const result = last.result ?? ends.find((end) => end.result)?.result;
22
25
  if (result === undefined)
23
26
  return last;
@@ -25,6 +28,7 @@ function combined(ends) {
25
28
  ...last,
26
29
  result: {
27
30
  ...result,
31
+ attempts: ends.map((end, index) => attemptUsage(attempts, { end, attempt: index + 1 })),
28
32
  ...(last.result === undefined ? { failed: true, text: "" } : {}),
29
33
  usage: sumUsage(ends.map((end) => end.result?.usage ?? usageOf(null))),
30
34
  costUsd: total(ends.map((end) => end.result?.costUsd ?? null)),
@@ -45,14 +49,89 @@ function controlled(attempts, start) {
45
49
  }),
46
50
  };
47
51
  }
48
- async function launched(attempts) {
52
+ function attemptCommand(attempts, attempt) {
53
+ const { start, options } = attempts;
54
+ const original = start.command;
55
+ const previous = attempts.ends[attempt - 2];
56
+ const fallback = previous !== undefined && kindOf(attempts, previous) === "capacity"
57
+ ? options.fallbackModels?.[attempt - 3]
58
+ : undefined;
59
+ const command = fallback === undefined ? original : replaceCommandModel(original, fallback);
60
+ const model = start.output === "text" ? null : commandModel(command);
61
+ return {
62
+ command,
63
+ model,
64
+ ...(fallback !== undefined && model === null
65
+ ? { fallbackReason: "fallback-model-unavailable" }
66
+ : {}),
67
+ };
68
+ }
69
+ function attemptUsage(attempts, completion) {
70
+ const { end, attempt } = completion;
71
+ const result = end.result ?? {
72
+ model: null,
73
+ usage: usageOf(null),
74
+ costUsd: null,
75
+ pricingModel: undefined,
76
+ };
77
+ const model = result.model ?? attemptCommand(attempts, attempt).model;
78
+ const usage = result.usage;
79
+ return {
80
+ attempt,
81
+ retryKind: kindOf(attempts, end),
82
+ model,
83
+ ...(end.result?.models === undefined ? {} : { models: end.result.models }),
84
+ usage,
85
+ costUsd: result.costUsd,
86
+ estimatedCostUsd: attemptEstimate(attempts, { end, model, usage }),
87
+ };
88
+ }
89
+ function attemptEstimate(attempts, result) {
90
+ const worker = attempts.start.worker ?? "claude";
91
+ if (!nativeHarness(worker))
92
+ return null;
93
+ const models = result.end.result?.models;
94
+ const prices = attempts.options.tokenPrices ?? {};
95
+ return estimatedCostUsd(result.usage, worker === "gemini" && models !== undefined
96
+ ? { worker, models, prices }
97
+ : {
98
+ worker,
99
+ price: priceForModel(prices, result.end.result?.pricingModel === undefined
100
+ ? result.model
101
+ : result.end.result.pricingModel),
102
+ });
103
+ }
104
+ function kindOf(attempts, end) {
105
+ const { worker, output } = attempts.start;
106
+ if (output === "text" || !["claude", "codex"].includes(worker ?? "claude"))
107
+ return null;
108
+ if (worker !== "codex")
109
+ return retryKind(end.result);
110
+ return capacityRefusal(end.result) ? "capacity" : null;
111
+ }
112
+ async function promptOf(attempts) {
113
+ const { start, ends, stopping, turnStartCommit } = attempts;
114
+ if (ends.length === 0)
115
+ return start.prompt;
116
+ if (!ends.some((end) => kindOf(attempts, end) === "network"))
117
+ return continuation + start.prompt;
118
+ const evidence = await retryEvidence({ directory: start.directory, signal: stopping.signal }, turnStartCommit);
119
+ return `${networkContinuation}\n\nCommits since the start of this turn:\n${evidence}\n\n${start.prompt}`;
120
+ }
121
+ async function launched(attempts, prompt = attempts.start.prompt) {
49
122
  const { start, options, ends } = attempts;
50
123
  const attempt = ends.length + 1;
51
- const folder = start.mode === "analysis" || attempt === 1
124
+ const selected = attemptCommand(attempts, attempt);
125
+ const folder = attempt === 1
52
126
  ? start.folder
53
127
  : join(start.folder, `attempt-${String(attempt)}`);
54
128
  const entry = {
55
129
  ...options.metadata,
130
+ turnStartCommit: attempts.turnStartCommit,
131
+ model: selected.model,
132
+ ...(selected.fallbackReason === undefined
133
+ ? {}
134
+ : { fallbackReason: selected.fallbackReason }),
56
135
  attempt,
57
136
  startedAt: attempt === 1 ? attempts.startedAt : new Date().toISOString(),
58
137
  };
@@ -70,9 +149,10 @@ async function launched(attempts) {
70
149
  return undefined;
71
150
  const turn = controlled(attempts, {
72
151
  ...start,
152
+ command: selected.command,
73
153
  folder,
74
154
  ...(attempt === 1 ? {} : { activityFolder: start.folder }),
75
- prompt: attempt === 1 ? start.prompt : continuation + start.prompt,
155
+ prompt,
76
156
  });
77
157
  try {
78
158
  const value = { ...entry, phase: "running", processId: turn.processId };
@@ -96,6 +176,7 @@ async function recordedEnd(attempts, completion) {
96
176
  const { start, ends, options } = attempts;
97
177
  const { processId, end } = completion;
98
178
  const attempt = ends.length;
179
+ const selected = attemptCommand(attempts, attempt);
99
180
  const name = `attempt-${String(attempt)}.json`;
100
181
  const started = await readRecord(start.folder, name);
101
182
  const startedAt = Reflect.get(Object(started), "startedAt");
@@ -105,14 +186,17 @@ async function recordedEnd(attempts, completion) {
105
186
  name,
106
187
  value: {
107
188
  ...options.metadata,
189
+ turnStartCommit: attempts.turnStartCommit,
190
+ ...attemptUsage(attempts, { end, attempt }),
191
+ ...(selected.fallbackReason === undefined
192
+ ? {}
193
+ : { fallbackReason: selected.fallbackReason }),
108
194
  attempt,
109
195
  processId,
110
196
  startedAt,
111
197
  endedAt: new Date().toISOString(),
112
198
  exitCode: end.exitCode,
113
199
  capacity: capacityRefusal(end.result),
114
- usage: end.result?.usage ?? usageOf(null),
115
- costUsd: end.result?.costUsd ?? null,
116
200
  },
117
201
  });
118
202
  }
@@ -122,6 +206,7 @@ async function waited(attempts, milliseconds) {
122
206
  name: "started.json",
123
207
  value: {
124
208
  ...options.metadata,
209
+ turnStartCommit: attempts.turnStartCommit,
125
210
  startedAt: attempts.startedAt,
126
211
  attempt: ends.length,
127
212
  phase: "waiting",
@@ -137,6 +222,27 @@ async function waited(attempts, milliseconds) {
137
222
  throw error;
138
223
  });
139
224
  }
225
+ async function preparedRetry(attempts) {
226
+ const prompt = await promptOf(attempts);
227
+ const failure = await indexFailure({
228
+ directory: attempts.start.directory,
229
+ signal: attempts.stopping.signal,
230
+ });
231
+ if (cancelled(attempts))
232
+ return { ...combined(attempts), stopped: true };
233
+ if (failure !== null) {
234
+ await written(attempts.start.folder, {
235
+ name: "retry-failure.json",
236
+ value: failure,
237
+ });
238
+ return {
239
+ ...combined(attempts),
240
+ reason: failure.reason,
241
+ detail: `${failure.fix}${failure.lockPath === undefined ? "" : ` Lock: ${failure.lockPath}`}`,
242
+ };
243
+ }
244
+ return prompt;
245
+ }
140
246
  async function finished(attempts, first) {
141
247
  const { ends } = attempts;
142
248
  let turn = first;
@@ -144,18 +250,20 @@ async function finished(attempts, first) {
144
250
  const end = await turn.ended;
145
251
  ends.push(end);
146
252
  await recordedEnd(attempts, { processId: turn.processId, end });
147
- const milliseconds = waits[ends.length - 1];
148
- if (cancelled(attempts) ||
149
- !capacityRefusal(end.result) ||
150
- milliseconds === undefined)
253
+ const kind = kindOf(attempts, end);
254
+ const milliseconds = kind === null ? undefined : waits[kind][ends.length - 1];
255
+ if (cancelled(attempts) || milliseconds === undefined)
151
256
  break;
152
257
  await waited(attempts, milliseconds);
153
258
  if (cancelled(attempts))
154
- return { ...combined(ends), stopped: true };
155
- turn = await launched(attempts);
259
+ return { ...combined(attempts), stopped: true };
260
+ const prepared = await preparedRetry(attempts);
261
+ if (typeof prepared !== "string")
262
+ return prepared;
263
+ turn = await launched(attempts, prepared);
156
264
  }
157
265
  return {
158
- ...combined(ends),
266
+ ...combined(attempts),
159
267
  ...(cancelled(attempts) || turn === undefined ? { stopped: true } : {}),
160
268
  };
161
269
  }
@@ -163,17 +271,33 @@ function cancelled(attempts) {
163
271
  return attempts.stopping.signal.aborted;
164
272
  }
165
273
  export async function startRetriedTurn(start, options) {
274
+ const stopping = options.stopping ?? new AbortController();
275
+ const turnStartCommit = await turnHead({
276
+ directory: start.directory,
277
+ signal: stopping.signal,
278
+ });
166
279
  const attempts = {
280
+ turnStartCommit,
167
281
  start,
168
282
  startedAt: new Date().toISOString(),
169
283
  options,
170
- stopping: new AbortController(),
284
+ stopping,
171
285
  ends: [],
172
- grace: { milliseconds: 2_000 },
286
+ grace: { milliseconds: options.stopMilliseconds ?? 2_000 },
173
287
  };
174
288
  const turn = await launched(attempts);
175
289
  if (turn === undefined)
176
- throw new Error("turn-start-stopped");
290
+ return {
291
+ processId: null,
292
+ ended: Promise.resolve({
293
+ exitCode: null,
294
+ result: undefined,
295
+ stopped: true,
296
+ }),
297
+ stop: () => {
298
+ stopping.abort();
299
+ },
300
+ };
177
301
  return {
178
302
  processId: turn.processId,
179
303
  ended: finished(attempts, turn),
@@ -0,0 +1,19 @@
1
+ import { type Fields } from "../protocol.ts";
2
+ export type PendingSlot = {
3
+ readonly kind: "run";
4
+ readonly input: Fields;
5
+ } | {
6
+ readonly kind: "skip";
7
+ readonly runId: string;
8
+ };
9
+ export interface ScheduleProgress {
10
+ readonly everySeconds: number;
11
+ readonly nextAt: number;
12
+ readonly lastSlot: number;
13
+ readonly activeCommandId?: string;
14
+ readonly pending?: PendingSlot;
15
+ }
16
+ export declare function scheduleJournal(directory: string): Promise<{
17
+ readonly entries: Map<string, ScheduleProgress>;
18
+ readonly save: () => Promise<void>;
19
+ }>;
@@ -0,0 +1,57 @@
1
+ import { readFile, rename, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { record } from "../protocol.js";
4
+ import { isCommandId, isRecordKey } from "../authority/commands.js";
5
+ function pendingSlot(value) {
6
+ const fields = record(value);
7
+ if (fields?.["kind"] === "run")
8
+ return record(fields["input"]) !== undefined;
9
+ return fields?.["kind"] === "skip" && isRecordKey(fields["runId"]);
10
+ }
11
+ function whole(value) {
12
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
13
+ }
14
+ function timing(fields) {
15
+ const { everySeconds, nextAt, lastSlot } = fields;
16
+ return (whole(everySeconds) &&
17
+ everySeconds >= 60 &&
18
+ everySeconds <= 86400 &&
19
+ whole(nextAt) &&
20
+ whole(lastSlot));
21
+ }
22
+ function isProgress(value) {
23
+ const fields = record(value);
24
+ if (fields === undefined)
25
+ return false;
26
+ const { activeCommandId, pending } = fields;
27
+ return (timing(fields) &&
28
+ (activeCommandId === undefined || isCommandId(activeCommandId)) &&
29
+ (pending === undefined || pendingSlot(pending)));
30
+ }
31
+ export async function scheduleJournal(directory) {
32
+ const file = join(directory, "schedules.json");
33
+ const text = await readFile(file, "utf8").catch((error) => {
34
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
35
+ return "{}";
36
+ throw error;
37
+ });
38
+ const parsed = record(JSON.parse(text));
39
+ if (parsed === undefined)
40
+ throw new Error("invalid-schedule-state");
41
+ const entries = new Map();
42
+ for (const [workflowId, value] of Object.entries(parsed)) {
43
+ if (!isProgress(value))
44
+ throw new Error("invalid-schedule-state");
45
+ entries.set(workflowId, value);
46
+ }
47
+ return {
48
+ entries,
49
+ save: async () => {
50
+ await writeFile(`${file}.tmp`, JSON.stringify(Object.fromEntries(entries)) + "\n", {
51
+ mode: 0o600,
52
+ flush: true,
53
+ });
54
+ await rename(`${file}.tmp`, file);
55
+ },
56
+ };
57
+ }
@@ -0,0 +1,18 @@
1
+ import type { ChildProcessWithoutNullStreams } from "node:child_process";
2
+ import type { WriteStream } from "node:fs";
3
+ export declare function textOutput(child: ChildProcessWithoutNullStreams, options: {
4
+ readonly output: WriteStream;
5
+ readonly limit: number;
6
+ }): (exitCode: number | null) => Promise<{
7
+ text: string;
8
+ failed: boolean;
9
+ model: null;
10
+ costUsd: null;
11
+ usage: import("../worker-usage.ts").WorkerUsage;
12
+ sessionId: null;
13
+ turns: null;
14
+ reviewFeedback?: string;
15
+ reviewVerdict: import("../review-subject.ts").ReviewVerdict | null;
16
+ ticketStatus: import("../ticket-status.ts").TicketStatus;
17
+ ticketStatusTooLarge?: true;
18
+ }>;
@@ -0,0 +1,44 @@
1
+ import { usageOf } from "../worker-usage.js";
2
+ import { reviewReportStream } from "../review-subject.js";
3
+ import { ticketStatusStream } from "../ticket-status-stream.js";
4
+ export function textOutput(child, options) {
5
+ const { output, limit } = options;
6
+ const status = ticketStatusStream(limit);
7
+ const verdict = reviewReportStream(limit);
8
+ let text = "";
9
+ let error = "";
10
+ child.stderr.setEncoding("utf8");
11
+ child.stderr.on("data", (chunk) => {
12
+ error = (error + chunk).slice(-limit);
13
+ });
14
+ child.stdout.setEncoding("utf8");
15
+ child.stdout.on("data", (chunk) => {
16
+ text = (text + chunk).slice(-limit);
17
+ status.write(chunk);
18
+ verdict.write(chunk);
19
+ if (!output.write(chunk)) {
20
+ child.stdout.pause();
21
+ output.once("drain", () => {
22
+ child.stdout.resume();
23
+ });
24
+ }
25
+ });
26
+ return async (exitCode) => {
27
+ await new Promise((resolve) => output.end(resolve));
28
+ const review = verdict.result();
29
+ return {
30
+ ...status.result(),
31
+ reviewVerdict: review.reviewVerdict,
32
+ ...(review.reviewVerdict === null
33
+ ? {}
34
+ : { reviewFeedback: review.feedback }),
35
+ text: exitCode === 0 ? text : error,
36
+ failed: exitCode !== 0,
37
+ model: null,
38
+ costUsd: null,
39
+ usage: usageOf(null),
40
+ sessionId: null,
41
+ turns: null,
42
+ };
43
+ };
44
+ }
@@ -0,0 +1,18 @@
1
+ import { type Fields } from "../protocol.ts";
2
+ interface Source {
3
+ readonly repository: string;
4
+ readonly command: readonly string[] | undefined;
5
+ readonly githubCommand?: readonly string[] | undefined;
6
+ }
7
+ export declare class TicketDependencyReadError extends Error {
8
+ }
9
+ export declare function ticketDependencyWaits(source: Source): {
10
+ readonly check: (candidate: {
11
+ readonly ticketId: string;
12
+ readonly ticket: string;
13
+ readonly signal: AbortSignal;
14
+ }) => Promise<readonly string[]>;
15
+ readonly refresh: (signal: AbortSignal) => Promise<readonly string[]>;
16
+ readonly skipped: () => readonly Fields[];
17
+ };
18
+ export {};
@@ -0,0 +1,60 @@
1
+ import { hardDependencies } from "../ticket-dependencies.js";
2
+ import { issueIdentity } from "../issue-identity.js";
3
+ import { record } from "../protocol.js";
4
+ import { calls } from "./github-calls.js";
5
+ import { ticketText } from "./ticket-source.js";
6
+ export class TicketDependencyReadError extends Error {
7
+ }
8
+ async function openDependencies(source, candidate) {
9
+ const github = calls({ repository: source.repository, gh: source.githubCommand ?? ["gh"] }, candidate.signal);
10
+ const issue = issueIdentity(candidate.ticket);
11
+ const repository = issue === null ? "{owner}/{repo}" : `${issue.owner}/${issue.repository}`;
12
+ const open = [];
13
+ for (const id of hardDependencies(candidate.ticket)) {
14
+ const response = JSON.parse(await github.gh(["api", `repos/${repository}/issues/${id}`]).catch(() => {
15
+ throw new TicketDependencyReadError("github-call-failed");
16
+ }));
17
+ const state = record(response)?.["state"];
18
+ if (state !== "open" && state !== "closed")
19
+ throw new Error("invalid-dependency-state");
20
+ if (state === "open")
21
+ open.push(id);
22
+ }
23
+ return open;
24
+ }
25
+ export function ticketDependencyWaits(source) {
26
+ const waiting = new Map();
27
+ let nextRefresh;
28
+ const check = async (candidate) => {
29
+ const open = await openDependencies(source, candidate);
30
+ if (open.length === 0)
31
+ waiting.delete(candidate.ticketId);
32
+ else
33
+ waiting.set(candidate.ticketId, open);
34
+ return open;
35
+ };
36
+ return {
37
+ check,
38
+ refresh: async (signal) => {
39
+ const tickets = [...waiting.keys()];
40
+ const ticketId = nextRefresh !== undefined && waiting.has(nextRefresh)
41
+ ? nextRefresh
42
+ : tickets[0];
43
+ if (ticketId === undefined)
44
+ return [];
45
+ nextRefresh = tickets[tickets.indexOf(ticketId) + 1] ?? tickets[0];
46
+ if (source.command === undefined)
47
+ throw new Error("ticket-source-not-configured");
48
+ const read = await ticketText(source.command, { ticketId, signal });
49
+ if (read.kind === "failed")
50
+ throw new TicketDependencyReadError("ticket-not-available");
51
+ await check({ ticketId, ticket: read.text, signal });
52
+ return [...waiting.keys()];
53
+ },
54
+ skipped: () => [...waiting].map(([ticketId, dependencies]) => ({
55
+ ticketId,
56
+ reason: "ticket-dependency-open",
57
+ dependencies,
58
+ })),
59
+ };
60
+ }
@@ -1,8 +1,9 @@
1
- import type { DeclaredWorkflow } from "../workflow-declaration.ts";
1
+ import { type DeclaredWorkflow } from "../workflow-declaration.ts";
2
2
  import type { Resolver, WorkflowRegistration } from "../service/registry.ts";
3
- export declare const ticketWorkflow = "develop-ticket";
4
- export declare const promptWorkflow = "develop-prompt";
5
- export declare const issueWorkflow = "develop-issue";
3
+ import type { LocalCommands } from "../command-settings.ts";
4
+ export declare const ticketWorkflow: "develop-ticket";
5
+ export declare const promptWorkflow: "develop-prompt";
6
+ export declare const issueWorkflow: "develop-issue";
6
7
  export declare const ticketCapabilities: string[];
7
8
  export type TicketRegistrations = {
8
9
  readonly kind: "admitted";
@@ -15,12 +16,11 @@ export interface TicketSource {
15
16
  readonly repository: string;
16
17
  readonly command: readonly string[] | undefined;
17
18
  readonly nextCommand?: readonly string[] | undefined;
19
+ readonly githubCommand?: readonly string[] | undefined;
20
+ readonly skipTickets?: readonly string[];
18
21
  }
19
- export interface TicketRegistration {
20
- readonly workflowId: string;
22
+ export interface TicketRegistration extends Omit<WorkflowRegistration, "manifest" | "availability" | "admission"> {
21
23
  readonly functionName: string;
22
- readonly resolver: Resolver;
23
- readonly submission: WorkflowRegistration["submission"];
24
24
  readonly effectLimit: number;
25
25
  readonly capabilities?: readonly string[];
26
26
  }
@@ -30,4 +30,6 @@ export declare function promptResolver(repository: string): Resolver;
30
30
  export declare function ticketRegistrationTable(source: TicketSource, declarations?: readonly DeclaredWorkflow[]): readonly TicketRegistration[];
31
31
  export declare function ticketRegistrations(manifests: Readonly<Record<string, string | undefined>>, options: {
32
32
  readonly table: readonly TicketRegistration[];
33
+ readonly bundleDigest?: string;
34
+ readonly commands?: LocalCommands;
33
35
  }): Promise<TicketRegistrations>;