cloving 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/README.md +584 -144
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/agent-harness-shell.d.ts +12 -0
  16. package/dist/src/agent-harness-shell.js +90 -0
  17. package/dist/src/agent-harness-versions.d.ts +8 -0
  18. package/dist/src/agent-harness-versions.js +49 -0
  19. package/dist/src/agent-harnesses.d.ts +4 -0
  20. package/dist/src/agent-harnesses.js +13 -0
  21. package/dist/src/authority/commands.d.ts +2 -0
  22. package/dist/src/authority/commands.js +49 -8
  23. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  24. package/dist/src/authority/dispatch-decision.js +7 -4
  25. package/dist/src/authority/events.js +2 -2
  26. package/dist/src/authority/gate-reduction.d.ts +1 -0
  27. package/dist/src/authority/gate-reduction.js +18 -3
  28. package/dist/src/authority/gates.d.ts +2 -1
  29. package/dist/src/authority/gates.js +5 -1
  30. package/dist/src/authority/handoff-chain.d.ts +24 -0
  31. package/dist/src/authority/handoff-chain.js +46 -0
  32. package/dist/src/authority/operations.js +1 -1
  33. package/dist/src/authority/reconciliation.d.ts +1 -0
  34. package/dist/src/authority/reconciliation.js +18 -11
  35. package/dist/src/authority/reduction.d.ts +1 -1
  36. package/dist/src/authority/reduction.js +6 -1
  37. package/dist/src/authority/status-input.d.ts +1 -1
  38. package/dist/src/authority/status.d.ts +1 -0
  39. package/dist/src/authority/status.js +27 -3
  40. package/dist/src/authority/transitions.d.ts +5 -5
  41. package/dist/src/authority/transitions.js +9 -0
  42. package/dist/src/broker/actor/authority-delivery.js +1 -0
  43. package/dist/src/broker/actor/authority-queries.d.ts +11 -1
  44. package/dist/src/broker/actor/authority-queries.js +67 -3
  45. package/dist/src/broker/actor/authority-receipts.js +11 -1
  46. package/dist/src/broker/actor/authority-session.js +2 -2
  47. package/dist/src/broker/actor/authority-settings.js +4 -0
  48. package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
  49. package/dist/src/broker/actor/delivery-intents.js +4 -4
  50. package/dist/src/broker/actor/effect-delivery.js +13 -1
  51. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  52. package/dist/src/broker/actor/effect-queries.js +7 -0
  53. package/dist/src/broker/actor/pin-check.js +1 -1
  54. package/dist/src/broker/actor/stop-plan.js +1 -1
  55. package/dist/src/broker/actor/turn-state.js +1 -1
  56. package/dist/src/broker/authority-admission.js +26 -5
  57. package/dist/src/broker/authority-restore.js +1 -0
  58. package/dist/src/broker/decision-restore.js +4 -4
  59. package/dist/src/broker/socket-address.d.ts +3 -1
  60. package/dist/src/broker/socket-address.js +2 -2
  61. package/dist/src/cli/arguments.d.ts +11 -13
  62. package/dist/src/cli/arguments.js +37 -107
  63. package/dist/src/cli/command-effects.d.ts +7 -0
  64. package/dist/src/cli/command-effects.js +39 -0
  65. package/dist/src/cli/commands.js +11 -4
  66. package/dist/src/cli/config-arguments.d.ts +11 -0
  67. package/dist/src/cli/config-arguments.js +59 -0
  68. package/dist/src/cli/config-command.d.ts +2 -0
  69. package/dist/src/cli/config-command.js +105 -0
  70. package/dist/src/cli/config-file.d.ts +3 -0
  71. package/dist/src/cli/config-file.js +50 -0
  72. package/dist/src/cli/config-lock.d.ts +7 -0
  73. package/dist/src/cli/config-lock.js +61 -0
  74. package/dist/src/cli/config-notice.d.ts +5 -0
  75. package/dist/src/cli/config-notice.js +46 -0
  76. package/dist/src/cli/doctor-github.d.ts +9 -0
  77. package/dist/src/cli/doctor-github.js +138 -0
  78. package/dist/src/cli/doctor-harness.d.ts +13 -0
  79. package/dist/src/cli/doctor-harness.js +242 -0
  80. package/dist/src/cli/doctor-local.d.ts +18 -0
  81. package/dist/src/cli/doctor-local.js +77 -0
  82. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  83. package/dist/src/cli/doctor-runtime.js +176 -0
  84. package/dist/src/cli/doctor-service.d.ts +1 -0
  85. package/dist/src/cli/doctor-service.js +11 -0
  86. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  87. package/dist/src/cli/doctor-workflows.js +45 -0
  88. package/dist/src/cli/doctor.d.ts +15 -0
  89. package/dist/src/cli/doctor.js +190 -0
  90. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  91. package/dist/src/cli/github-ci-progress.js +83 -0
  92. package/dist/src/cli/github-retry.d.ts +6 -0
  93. package/dist/src/cli/github-retry.js +47 -0
  94. package/dist/src/cli/harness-probes.d.ts +22 -0
  95. package/dist/src/cli/harness-probes.js +183 -0
  96. package/dist/src/cli/main.d.ts +7 -1
  97. package/dist/src/cli/main.js +39 -61
  98. package/dist/src/cli/phone-arguments.d.ts +14 -0
  99. package/dist/src/cli/phone-arguments.js +37 -0
  100. package/dist/src/cli/phone-client.d.ts +2 -0
  101. package/dist/src/cli/phone-client.js +32 -0
  102. package/dist/src/cli/phone-command.d.ts +13 -0
  103. package/dist/src/cli/phone-command.js +101 -0
  104. package/dist/src/cli/probe-command.d.ts +36 -0
  105. package/dist/src/cli/probe-command.js +59 -0
  106. package/dist/src/cli/project-settings.d.ts +4 -0
  107. package/dist/src/cli/project-settings.js +33 -0
  108. package/dist/src/cli/render.d.ts +3 -1
  109. package/dist/src/cli/render.js +102 -39
  110. package/dist/src/cli/report-github.d.ts +18 -0
  111. package/dist/src/cli/report-github.js +200 -0
  112. package/dist/src/cli/report.d.ts +17 -0
  113. package/dist/src/cli/report.js +192 -0
  114. package/dist/src/cli/repository-arguments.d.ts +5 -0
  115. package/dist/src/cli/repository-arguments.js +34 -0
  116. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  117. package/dist/src/cli/runtime-arguments.js +15 -0
  118. package/dist/src/cli/runtime-directory.d.ts +6 -2
  119. package/dist/src/cli/runtime-directory.js +72 -14
  120. package/dist/src/cli/toolchain.d.ts +2 -0
  121. package/dist/src/cli/toolchain.js +22 -2
  122. package/dist/src/cli/usage-render.d.ts +5 -0
  123. package/dist/src/cli/usage-render.js +40 -1
  124. package/dist/src/cli/usage.d.ts +3 -3
  125. package/dist/src/cli/usage.js +74 -45
  126. package/dist/src/cli/watch-actions.d.ts +2 -0
  127. package/dist/src/cli/watch-actions.js +4 -4
  128. package/dist/src/cli/watch-board-view.d.ts +12 -1
  129. package/dist/src/cli/watch-board-view.js +64 -12
  130. package/dist/src/cli/watch-board.d.ts +7 -1
  131. package/dist/src/cli/watch-board.js +61 -16
  132. package/dist/src/cli/watch-card-forms.js +2 -2
  133. package/dist/src/cli/watch-client.d.ts +1 -1
  134. package/dist/src/cli/watch-client.js +12 -3
  135. package/dist/src/cli/watch-header-view.d.ts +27 -0
  136. package/dist/src/cli/watch-header-view.js +116 -0
  137. package/dist/src/cli/watch-model.d.ts +10 -4
  138. package/dist/src/cli/watch-model.js +49 -59
  139. package/dist/src/cli/watch-page.js +67 -14
  140. package/dist/src/cli/watch-phases.js +3 -3
  141. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  142. package/dist/src/cli/watch-phone-client.js +84 -0
  143. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  144. package/dist/src/cli/watch-phone-view.js +113 -0
  145. package/dist/src/cli/watch-phone.d.ts +5 -0
  146. package/dist/src/cli/watch-phone.js +53 -0
  147. package/dist/src/cli/watch-pr-command.d.ts +5 -2
  148. package/dist/src/cli/watch-pr-command.js +41 -4
  149. package/dist/src/cli/watch-pr-identity.d.ts +14 -2
  150. package/dist/src/cli/watch-pr-identity.js +25 -0
  151. package/dist/src/cli/watch-pr-observer.d.ts +1 -0
  152. package/dist/src/cli/watch-pr-observer.js +48 -6
  153. package/dist/src/cli/watch-pull-request.d.ts +12 -0
  154. package/dist/src/cli/watch-pull-request.js +134 -0
  155. package/dist/src/cli/watch-reads.d.ts +7 -1
  156. package/dist/src/cli/watch-reads.js +42 -20
  157. package/dist/src/cli/watch-render.d.ts +23 -2
  158. package/dist/src/cli/watch-render.js +2 -1
  159. package/dist/src/cli/watch-server.js +56 -7
  160. package/dist/src/cli/watch-turn.d.ts +4 -1
  161. package/dist/src/cli/watch-turn.js +38 -2
  162. package/dist/src/cli/watch-usage.js +5 -1
  163. package/dist/src/cli/watch-view.d.ts +10 -17
  164. package/dist/src/cli/watch-view.js +33 -77
  165. package/dist/src/cli.js +106 -23
  166. package/dist/src/command-settings.d.ts +16 -0
  167. package/dist/src/command-settings.js +42 -0
  168. package/dist/src/configuration-change.d.ts +11 -0
  169. package/dist/src/configuration-change.js +62 -0
  170. package/dist/src/configuration-display.d.ts +21 -0
  171. package/dist/src/configuration-display.js +69 -0
  172. package/dist/src/configuration-schema.d.ts +49 -0
  173. package/dist/src/configuration-schema.js +159 -0
  174. package/dist/src/daemon/claude-turn.d.ts +20 -5
  175. package/dist/src/daemon/claude-turn.js +116 -53
  176. package/dist/src/daemon/claude-worker.d.ts +3 -5
  177. package/dist/src/daemon/claude-worker.js +64 -80
  178. package/dist/src/daemon/command-journal.d.ts +5 -0
  179. package/dist/src/daemon/command-journal.js +50 -0
  180. package/dist/src/daemon/command-process.d.ts +28 -0
  181. package/dist/src/daemon/command-process.js +164 -0
  182. package/dist/src/daemon/command-worker.d.ts +19 -0
  183. package/dist/src/daemon/command-worker.js +182 -0
  184. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  185. package/dist/src/daemon/cursor-stream.js +154 -0
  186. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  187. package/dist/src/daemon/daemon-adapters.js +102 -0
  188. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  189. package/dist/src/daemon/daemon-loops.js +39 -0
  190. package/dist/src/daemon/daemon.d.ts +3 -30
  191. package/dist/src/daemon/daemon.js +132 -110
  192. package/dist/src/daemon/declared-input.d.ts +3 -0
  193. package/dist/src/daemon/declared-input.js +9 -0
  194. package/dist/src/daemon/delivery-router.js +7 -1
  195. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  196. package/dist/src/daemon/gemini-stream.js +129 -0
  197. package/dist/src/daemon/github-calls.d.ts +4 -0
  198. package/dist/src/daemon/github-calls.js +16 -7
  199. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  200. package/dist/src/daemon/github-ci-rerun.js +92 -0
  201. package/dist/src/daemon/github-ci.d.ts +6 -0
  202. package/dist/src/daemon/github-ci.js +251 -0
  203. package/dist/src/daemon/github-merge-call.d.ts +16 -0
  204. package/dist/src/daemon/github-merge-call.js +73 -0
  205. package/dist/src/daemon/github-merge.d.ts +3 -5
  206. package/dist/src/daemon/github-merge.js +59 -98
  207. package/dist/src/daemon/github-methods.d.ts +28 -0
  208. package/dist/src/daemon/github-methods.js +90 -16
  209. package/dist/src/daemon/github-operation.d.ts +3 -0
  210. package/dist/src/daemon/github-retry.d.ts +6 -0
  211. package/dist/src/daemon/github-retry.js +13 -0
  212. package/dist/src/daemon/github-ticket-status.js +27 -1
  213. package/dist/src/daemon/github-worker.js +2 -1
  214. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  215. package/dist/src/daemon/handoff-worker.js +232 -0
  216. package/dist/src/daemon/issue-queue.d.ts +2 -0
  217. package/dist/src/daemon/issue-queue.js +92 -63
  218. package/dist/src/daemon/notify-journal.d.ts +18 -0
  219. package/dist/src/daemon/notify-journal.js +108 -0
  220. package/dist/src/daemon/notify-message.js +2 -1
  221. package/dist/src/daemon/notify.js +177 -37
  222. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  223. package/dist/src/daemon/opencode-stream.js +87 -0
  224. package/dist/src/daemon/queue-status.d.ts +4 -0
  225. package/dist/src/daemon/queue-status.js +38 -0
  226. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  227. package/dist/src/daemon/retry-worktree.js +139 -0
  228. package/dist/src/daemon/retrying-turn.d.ts +5 -0
  229. package/dist/src/daemon/retrying-turn.js +145 -21
  230. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  231. package/dist/src/daemon/schedule-journal.js +57 -0
  232. package/dist/src/daemon/text-output.d.ts +18 -0
  233. package/dist/src/daemon/text-output.js +44 -0
  234. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  235. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  236. package/dist/src/daemon/ticket-registration.d.ts +10 -8
  237. package/dist/src/daemon/ticket-registration.js +146 -47
  238. package/dist/src/daemon/ticket-source.d.ts +4 -1
  239. package/dist/src/daemon/ticket-source.js +8 -2
  240. package/dist/src/daemon/turn-command.d.ts +10 -0
  241. package/dist/src/daemon/turn-command.js +33 -0
  242. package/dist/src/daemon/turn-report.d.ts +18 -0
  243. package/dist/src/daemon/turn-report.js +79 -0
  244. package/dist/src/daemon/work-tree.d.ts +2 -1
  245. package/dist/src/daemon/work-tree.js +15 -12
  246. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  247. package/dist/src/daemon/workflow-generations.js +57 -0
  248. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  249. package/dist/src/daemon/workflow-replay.js +58 -0
  250. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  251. package/dist/src/daemon/workflow-schedules.js +185 -0
  252. package/dist/src/decision-visibility.d.ts +2 -0
  253. package/dist/src/decision-visibility.js +10 -0
  254. package/dist/src/decision-wait.d.ts +1 -0
  255. package/dist/src/decision-wait.js +3 -0
  256. package/dist/src/delivery-backoff.d.ts +1 -0
  257. package/dist/src/delivery-backoff.js +3 -0
  258. package/dist/src/doctor-report.d.ts +24 -0
  259. package/dist/src/doctor-report.js +70 -0
  260. package/dist/src/execution-pin.d.ts +9 -0
  261. package/dist/src/execution-pin.js +86 -2
  262. package/dist/src/grok-result.d.ts +12 -0
  263. package/dist/src/grok-result.js +61 -0
  264. package/dist/src/harness-defaults.d.ts +35 -0
  265. package/dist/src/harness-defaults.js +121 -0
  266. package/dist/src/host/decision-resume.d.ts +35 -0
  267. package/dist/src/host/decision-resume.js +86 -0
  268. package/dist/src/host/gate-bridge.d.ts +48 -0
  269. package/dist/src/host/gate-bridge.js +124 -0
  270. package/dist/src/host/run-wait.d.ts +26 -0
  271. package/dist/src/host/run-wait.js +37 -0
  272. package/dist/src/host/start-delivery.d.ts +3 -2
  273. package/dist/src/host/start-delivery.js +11 -4
  274. package/dist/src/host/step-bridge-host.d.ts +6 -19
  275. package/dist/src/host/step-bridge-host.js +57 -55
  276. package/dist/src/host/world-reconciliation.d.ts +1 -0
  277. package/dist/src/host/world-reconciliation.js +3 -0
  278. package/dist/src/host/world-runs.js +5 -0
  279. package/dist/src/issue-identity.d.ts +6 -0
  280. package/dist/src/issue-identity.js +23 -0
  281. package/dist/src/merge-request.d.ts +19 -0
  282. package/dist/src/merge-request.js +32 -0
  283. package/dist/src/phone/canonical-json.d.ts +1 -0
  284. package/dist/src/phone/canonical-json.js +16 -0
  285. package/dist/src/phone/phone-link.d.ts +7 -0
  286. package/dist/src/phone/phone-link.js +21 -0
  287. package/dist/src/phone/qr-data.d.ts +8 -0
  288. package/dist/src/phone/qr-data.js +133 -0
  289. package/dist/src/phone/qr-matrix.d.ts +6 -0
  290. package/dist/src/phone/qr-matrix.js +175 -0
  291. package/dist/src/phone/qr-penalty.d.ts +3 -0
  292. package/dist/src/phone/qr-penalty.js +67 -0
  293. package/dist/src/phone/qr-picture.d.ts +5 -0
  294. package/dist/src/phone/qr-picture.js +24 -0
  295. package/dist/src/private-config.schema.json +263 -0
  296. package/dist/src/project-config.schema.json +65 -0
  297. package/dist/src/project-settings.d.ts +19 -0
  298. package/dist/src/project-settings.js +131 -0
  299. package/dist/src/relay/answer-check.d.ts +24 -0
  300. package/dist/src/relay/answer-check.js +145 -0
  301. package/dist/src/relay/answer-inbox.d.ts +15 -0
  302. package/dist/src/relay/answer-inbox.js +173 -0
  303. package/dist/src/relay/daemon-keys.d.ts +16 -0
  304. package/dist/src/relay/daemon-keys.js +75 -0
  305. package/dist/src/relay/decision-check.d.ts +3 -0
  306. package/dist/src/relay/decision-check.js +77 -0
  307. package/dist/src/relay/decision-close.d.ts +6 -0
  308. package/dist/src/relay/decision-close.js +72 -0
  309. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  310. package/dist/src/relay/decision-envelopes.js +93 -0
  311. package/dist/src/relay/decision-watch.d.ts +14 -0
  312. package/dist/src/relay/decision-watch.js +68 -0
  313. package/dist/src/relay/envelope-post.d.ts +8 -0
  314. package/dist/src/relay/envelope-post.js +71 -0
  315. package/dist/src/relay/envelope.d.ts +28 -0
  316. package/dist/src/relay/envelope.js +53 -0
  317. package/dist/src/relay/hpke.d.ts +25 -0
  318. package/dist/src/relay/hpke.js +108 -0
  319. package/dist/src/relay/pairing-checks.d.ts +42 -0
  320. package/dist/src/relay/pairing-checks.js +172 -0
  321. package/dist/src/relay/pairing-follow.d.ts +8 -0
  322. package/dist/src/relay/pairing-follow.js +95 -0
  323. package/dist/src/relay/pairing-session.d.ts +29 -0
  324. package/dist/src/relay/pairing-session.js +87 -0
  325. package/dist/src/relay/phone-delivery.d.ts +51 -0
  326. package/dist/src/relay/phone-delivery.js +139 -0
  327. package/dist/src/relay/phone-devices.d.ts +36 -0
  328. package/dist/src/relay/phone-devices.js +46 -0
  329. package/dist/src/relay/phone-inbox.d.ts +18 -0
  330. package/dist/src/relay/phone-inbox.js +17 -0
  331. package/dist/src/relay/phone-operations.d.ts +18 -0
  332. package/dist/src/relay/phone-operations.js +121 -0
  333. package/dist/src/relay/phone-outbox.d.ts +21 -0
  334. package/dist/src/relay/phone-outbox.js +25 -0
  335. package/dist/src/relay/phone-socket.d.ts +6 -0
  336. package/dist/src/relay/phone-socket.js +63 -0
  337. package/dist/src/relay/relay-control.d.ts +7 -0
  338. package/dist/src/relay/relay-control.js +24 -0
  339. package/dist/src/relay/relay-files.d.ts +2 -0
  340. package/dist/src/relay/relay-files.js +23 -0
  341. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  342. package/dist/src/relay/relay-heartbeat.js +81 -0
  343. package/dist/src/relay/relay-http.d.ts +14 -0
  344. package/dist/src/relay/relay-http.js +63 -0
  345. package/dist/src/relay/relay-registration.d.ts +15 -0
  346. package/dist/src/relay/relay-registration.js +63 -0
  347. package/dist/src/relay/relay-service.d.ts +25 -0
  348. package/dist/src/relay/relay-service.js +216 -0
  349. package/dist/src/relay/relay-store.d.ts +48 -0
  350. package/dist/src/relay/relay-store.js +131 -0
  351. package/dist/src/relay/sealed-post.d.ts +25 -0
  352. package/dist/src/relay/sealed-post.js +52 -0
  353. package/dist/src/relay.d.ts +1 -0
  354. package/dist/src/relay.js +8 -0
  355. package/dist/src/report-statistics.d.ts +50 -0
  356. package/dist/src/report-statistics.js +70 -0
  357. package/dist/src/report.d.ts +171 -0
  358. package/dist/src/report.js +119 -0
  359. package/dist/src/repository-identity.d.ts +4 -0
  360. package/dist/src/repository-identity.js +4 -0
  361. package/dist/src/review-subject.d.ts +41 -0
  362. package/dist/src/review-subject.js +91 -0
  363. package/dist/src/run-wait.d.ts +23 -0
  364. package/dist/src/run-wait.js +20 -0
  365. package/dist/src/service/active-tickets.d.ts +4 -0
  366. package/dist/src/service/active-tickets.js +49 -0
  367. package/dist/src/service/command-effects.d.ts +4 -0
  368. package/dist/src/service/command-effects.js +16 -0
  369. package/dist/src/service/decision-handler.d.ts +4 -0
  370. package/dist/src/service/decision-handler.js +39 -4
  371. package/dist/src/service/gateway.js +18 -3
  372. package/dist/src/service/queue-runs.d.ts +3 -0
  373. package/dist/src/service/queue-runs.js +39 -0
  374. package/dist/src/service/registry.d.ts +22 -3
  375. package/dist/src/service/registry.js +51 -8
  376. package/dist/src/service/replies.d.ts +10 -0
  377. package/dist/src/service/replies.js +12 -0
  378. package/dist/src/service/run-handlers.js +45 -54
  379. package/dist/src/service/run-metadata.d.ts +8 -0
  380. package/dist/src/service/run-metadata.js +53 -0
  381. package/dist/src/service/run-waits.d.ts +3 -0
  382. package/dist/src/service/run-waits.js +41 -0
  383. package/dist/src/service/service.d.ts +21 -2
  384. package/dist/src/service/service.js +23 -5
  385. package/dist/src/service/submission-handler.js +70 -19
  386. package/dist/src/service/worker-port.d.ts +1 -0
  387. package/dist/src/service/worker-totals.js +10 -1
  388. package/dist/src/step-bridge.d.ts +32 -0
  389. package/dist/src/steps/decision-gate.d.ts +2 -1
  390. package/dist/src/steps/decision-gate.js +7 -0
  391. package/dist/src/steps/handoff.d.ts +2 -0
  392. package/dist/src/steps/handoff.js +13 -0
  393. package/dist/src/steps/merge-by-person.d.ts +2 -0
  394. package/dist/src/steps/merge-by-person.js +18 -0
  395. package/dist/src/steps/merge-when-green.d.ts +2 -0
  396. package/dist/src/steps/merge-when-green.js +62 -0
  397. package/dist/src/steps/review-by-agent.d.ts +5 -0
  398. package/dist/src/steps/review-by-agent.js +124 -0
  399. package/dist/src/steps/review-by-person.d.ts +4 -0
  400. package/dist/src/steps/review-by-person.js +16 -0
  401. package/dist/src/steps/review-subject.d.ts +2 -0
  402. package/dist/src/steps/review-subject.js +11 -0
  403. package/dist/src/steps/run-command.d.ts +2 -0
  404. package/dist/src/steps/run-command.js +15 -0
  405. package/dist/src/steps/sleep.d.ts +3 -0
  406. package/dist/src/steps/sleep.js +19 -0
  407. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  408. package/dist/src/steps/wait-for-decision.js +71 -0
  409. package/dist/src/steps/wait-for-run.d.ts +5 -0
  410. package/dist/src/steps/wait-for-run.js +9 -0
  411. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  412. package/dist/src/storage/decision-snapshots.js +7 -1
  413. package/dist/src/submission.d.ts +4 -0
  414. package/dist/src/submission.js +6 -2
  415. package/dist/src/testing.d.ts +29 -0
  416. package/dist/src/testing.js +264 -0
  417. package/dist/src/ticket-dependencies.d.ts +1 -0
  418. package/dist/src/ticket-dependencies.js +15 -0
  419. package/dist/src/ticket-status-stream.d.ts +9 -0
  420. package/dist/src/ticket-status-stream.js +94 -0
  421. package/dist/src/ticket-status.js +7 -4
  422. package/dist/src/token-prices.d.ts +14 -4
  423. package/dist/src/token-prices.js +56 -11
  424. package/dist/src/turn-profile.d.ts +1 -0
  425. package/dist/src/turn-profile.js +8 -1
  426. package/dist/src/worker-usage.d.ts +25 -0
  427. package/dist/src/worker-usage.js +58 -1
  428. package/dist/src/workflow-admission.d.ts +6 -0
  429. package/dist/src/workflow-candidate.d.ts +7 -2
  430. package/dist/src/workflow-candidate.js +48 -5
  431. package/dist/src/workflow-contracts.d.ts +2 -0
  432. package/dist/src/workflow-contracts.js +8 -3
  433. package/dist/src/workflow-declaration.d.ts +31 -2
  434. package/dist/src/workflow-declaration.js +140 -16
  435. package/dist/src/workflow-discovery.d.ts +19 -0
  436. package/dist/src/workflow-discovery.js +36 -0
  437. package/dist/src/workflow-refusals.d.ts +6 -0
  438. package/dist/src/workflow-refusals.js +42 -0
  439. package/dist/src/workflow-schedule.d.ts +22 -0
  440. package/dist/src/workflow-schedule.js +53 -0
  441. package/dist/src/workflows.d.ts +12 -1
  442. package/dist/src/workflows.js +9 -0
  443. package/dist/tools/admit-workflow.d.ts +14 -0
  444. package/dist/tools/admit-workflow.js +107 -0
  445. package/dist/tools/doctor-adoption.d.ts +1 -0
  446. package/dist/tools/doctor-adoption.js +11 -0
  447. package/dist/tools/project-configuration.d.ts +4 -0
  448. package/dist/tools/project-configuration.js +47 -0
  449. package/dist/tools/self-host-processes.d.ts +1 -0
  450. package/dist/tools/self-host-processes.js +33 -22
  451. package/dist/tools/self-host-project.d.ts +21 -0
  452. package/dist/tools/self-host-project.js +224 -0
  453. package/dist/tools/self-host-runtime.d.ts +16 -0
  454. package/dist/tools/self-host-runtime.js +60 -0
  455. package/dist/tools/self-host-workflows.d.ts +1 -0
  456. package/dist/tools/self-host-workflows.js +36 -1
  457. package/dist/tools/self-host.js +106 -135
  458. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  459. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  460. package/dist/tools/workflow-bundles.d.ts +20 -0
  461. package/dist/tools/workflow-bundles.js +173 -0
  462. package/dist/tools/workflow-candidate-counts.d.ts +12 -0
  463. package/dist/tools/workflow-candidate-counts.js +266 -0
  464. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  465. package/dist/tools/workflow-candidate-fields.js +24 -0
  466. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  467. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  468. package/dist/tools/workflow-candidate-program.d.ts +13 -0
  469. package/dist/tools/workflow-candidate-program.js +106 -0
  470. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  471. package/dist/tools/workflow-candidate-source.js +169 -0
  472. package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
  473. package/dist/tools/workflow-candidate-syntax.js +263 -0
  474. package/dist/tools/workflow-command.d.ts +1 -0
  475. package/dist/tools/workflow-command.js +143 -0
  476. package/dist/tools/workflow-folder-capture.d.ts +18 -0
  477. package/dist/tools/workflow-folder-capture.js +261 -0
  478. package/dist/tools/workflow-folders.d.ts +49 -0
  479. package/dist/tools/workflow-folders.js +203 -0
  480. package/dist/tools/workflow-source-effects.d.ts +10 -0
  481. package/dist/tools/workflow-source-effects.js +213 -0
  482. package/dist/tools/workflow-test-hook.d.ts +7 -0
  483. package/dist/tools/workflow-test-hook.js +16 -0
  484. package/dist/tools/workflow-test-loader.d.ts +1 -0
  485. package/dist/tools/workflow-test-loader.js +10 -0
  486. package/dist/workflows/develop-prd.js +71 -3
  487. package/dist/workflows/develop-ticket.js +6 -1
  488. package/dist/workflows/ticket-prompts.js +17 -3
  489. package/package.json +66 -6
  490. package/templates/develop/README.md +78 -0
  491. package/templates/develop/develop/accept.ts +11 -0
  492. package/templates/develop/develop/flow-tests.ts +357 -0
  493. package/templates/develop/develop/local.ts +40 -0
  494. package/templates/develop/develop/option-tests.ts +174 -0
  495. package/templates/develop/develop/partial-choice.ts +29 -0
  496. package/templates/develop/develop/partial.ts +28 -0
  497. package/templates/develop/develop/pull.ts +152 -0
  498. package/templates/develop/develop/queue-partial.ts +39 -0
  499. package/templates/develop/develop/refusal-tests.ts +174 -0
  500. package/templates/develop/develop/report.ts +156 -0
  501. package/templates/develop/develop/round.ts +40 -0
  502. package/templates/develop/develop/scenarios.ts +87 -0
  503. package/templates/develop/develop/turn.ts +67 -0
  504. package/templates/develop/develop.declaration.json +24 -0
  505. package/templates/develop/develop.test.ts +287 -0
  506. package/templates/develop/develop.ts +30 -0
  507. package/templates/develop/template.json +153 -0
  508. package/dist/src/chats/analysis-batches.d.ts +0 -24
  509. package/dist/src/chats/analysis-batches.js +0 -83
  510. package/dist/src/chats/analysis-contract.d.ts +0 -80
  511. package/dist/src/chats/analysis-contract.js +0 -16
  512. package/dist/src/chats/analysis-data.d.ts +0 -3
  513. package/dist/src/chats/analysis-data.js +0 -85
  514. package/dist/src/chats/analysis-input.d.ts +0 -12
  515. package/dist/src/chats/analysis-input.js +0 -83
  516. package/dist/src/chats/analysis-links.d.ts +0 -2
  517. package/dist/src/chats/analysis-links.js +0 -25
  518. package/dist/src/chats/analysis-prompt.d.ts +0 -10
  519. package/dist/src/chats/analysis-prompt.js +0 -16
  520. package/dist/src/chats/analysis-proposal.d.ts +0 -2
  521. package/dist/src/chats/analysis-proposal.js +0 -32
  522. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  523. package/dist/src/chats/analysis-provenance.js +0 -99
  524. package/dist/src/chats/analysis-shape.d.ts +0 -3
  525. package/dist/src/chats/analysis-shape.js +0 -228
  526. package/dist/src/chats/analysis.d.ts +0 -3
  527. package/dist/src/chats/analysis.js +0 -42
  528. package/dist/src/chats/corpus-input.d.ts +0 -5
  529. package/dist/src/chats/corpus-input.js +0 -288
  530. package/dist/src/chats/destination.d.ts +0 -4
  531. package/dist/src/chats/destination.js +0 -96
  532. package/dist/src/chats/import.d.ts +0 -15
  533. package/dist/src/chats/import.js +0 -243
  534. package/dist/src/chats/input-file.d.ts +0 -3
  535. package/dist/src/chats/input-file.js +0 -32
  536. package/dist/src/chats/normalize.d.ts +0 -29
  537. package/dist/src/chats/normalize.js +0 -155
  538. package/dist/src/chats/previous-import.d.ts +0 -5
  539. package/dist/src/chats/previous-import.js +0 -34
  540. package/dist/src/chats/reader.d.ts +0 -21
  541. package/dist/src/chats/reader.js +0 -118
  542. package/dist/src/chats/redact-import.d.ts +0 -14
  543. package/dist/src/chats/redact-import.js +0 -141
  544. package/dist/src/chats/redaction.d.ts +0 -41
  545. package/dist/src/chats/redaction.js +0 -161
  546. package/dist/src/chats/revision-input.d.ts +0 -3
  547. package/dist/src/chats/revision-input.js +0 -180
  548. package/dist/src/chats/revision.d.ts +0 -48
  549. package/dist/src/chats/revision.js +0 -94
  550. package/dist/src/chats/selection.d.ts +0 -25
  551. package/dist/src/chats/selection.js +0 -109
  552. package/dist/src/chats/source.d.ts +0 -23
  553. package/dist/src/chats/source.js +0 -135
  554. package/dist/src/chats/structure.d.ts +0 -57
  555. package/dist/src/chats/structure.js +0 -216
  556. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  557. package/dist/src/daemon/analysis-launch.js +0 -81
  558. package/dist/src/daemon/analysis-token.d.ts +0 -6
  559. package/dist/src/daemon/analysis-token.js +0 -88
  560. package/dist/src/daemon/analysis-worker.d.ts +0 -22
  561. package/dist/src/daemon/analysis-worker.js +0 -219
  562. package/dist/src/daemon/chats-files.d.ts +0 -15
  563. package/dist/src/daemon/chats-files.js +0 -113
  564. package/dist/src/daemon/chats-worker.d.ts +0 -12
  565. package/dist/src/daemon/chats-worker.js +0 -200
  566. package/dist/workflows/analyze-chats.d.ts +0 -10
  567. package/dist/workflows/analyze-chats.declaration.json +0 -9
  568. package/dist/workflows/analyze-chats.js +0 -73
@@ -0,0 +1,60 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { link, mkdir, readdir, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { readRetainedWorkflowBundle } from "./workflow-bundles.js";
5
+ export async function selectRuntimeDirectory(input) {
6
+ const { runtime, repository, legacyRuntime, adoptionRecord } = input;
7
+ if (legacyRuntime === undefined ||
8
+ adoptionRecord === undefined ||
9
+ runtime === legacyRuntime)
10
+ return { runtime, note: "" };
11
+ const directory = join(dirname(legacyRuntime), "workflow-bundles");
12
+ if (!(await belongsToRepository(directory, repository)))
13
+ return {
14
+ runtime,
15
+ note: `Legacy runtime ${legacyRuntime} was not adopted: retained bundles are absent, damaged or belong to another repository.`,
16
+ };
17
+ return { runtime: legacyRuntime, note: "", adoptionRecord };
18
+ }
19
+ export async function adoptRuntimeDirectory(input) {
20
+ const selected = await selectRuntimeDirectory(input);
21
+ const adoptionRecord = selected.adoptionRecord;
22
+ if (adoptionRecord === undefined)
23
+ return { runtime: selected.runtime, note: selected.note };
24
+ const { repository } = input;
25
+ const legacyRuntime = selected.runtime;
26
+ await mkdir(dirname(adoptionRecord), { recursive: true, mode: 0o700 });
27
+ const contents = JSON.stringify({
28
+ schemaVersion: 1,
29
+ repository,
30
+ runtimeDirectory: legacyRuntime,
31
+ });
32
+ const temporary = `${adoptionRecord}.${randomUUID()}.tmp`;
33
+ try {
34
+ await writeFile(temporary, contents, {
35
+ flag: "wx",
36
+ mode: 0o600,
37
+ flush: true,
38
+ });
39
+ await link(temporary, adoptionRecord);
40
+ }
41
+ finally {
42
+ await rm(temporary, { force: true });
43
+ }
44
+ return { runtime: legacyRuntime, note: "" };
45
+ }
46
+ async function belongsToRepository(directory, repository) {
47
+ try {
48
+ const ids = (await readdir(directory)).filter((id) => id !== ".history");
49
+ if (ids.length === 0)
50
+ return false;
51
+ for (const id of ids)
52
+ if ((await readRetainedWorkflowBundle({ directory, repository, id }))
53
+ .kind !== "available")
54
+ return false;
55
+ return true;
56
+ }
57
+ catch {
58
+ return false;
59
+ }
60
+ }
@@ -12,4 +12,5 @@ interface HostManifest {
12
12
  export declare function workflowFiles(directory: string): Promise<string[]>;
13
13
  export declare function workflowDeclarations(directory: string, manifests: Readonly<Record<string, HostManifest>>): Promise<readonly DeclaredWorkflow[]>;
14
14
  export declare function workflowManifests(compiled: WorkflowManifest, declarations?: readonly DeclaredWorkflow[]): Readonly<Record<string, HostManifest>>;
15
+ export declare function workflowBundleLoader(): string;
15
16
  export {};
@@ -6,7 +6,8 @@ export async function workflowFiles(directory) {
6
6
  return entries
7
7
  .filter((entry) => entry.isFile() &&
8
8
  /\.(?:ts|js)$/.test(entry.name) &&
9
- !entry.name.endsWith(".d.ts"))
9
+ !entry.name.endsWith(".d.ts") &&
10
+ !entry.name.endsWith(".test.ts"))
10
11
  .map((entry) => entry.name)
11
12
  .sort();
12
13
  }
@@ -76,3 +77,37 @@ export function workflowManifests(compiled, declarations = []) {
76
77
  });
77
78
  }));
78
79
  }
80
+ export function workflowBundleLoader() {
81
+ return `
82
+ import { AsyncLocalStorage } from "node:async_hooks";
83
+ import { pathToFileURL } from "node:url";
84
+ const bundleRegistries = new AsyncLocalStorage();
85
+ const registryKeys = ["@workflow/core//registeredSteps", "workflow-class-registry"].map(Symbol.for);
86
+ for (const key of registryKeys) {
87
+ let current = globalThis[key] ?? new Map();
88
+ Object.defineProperty(globalThis, key, {
89
+ configurable: true,
90
+ get: () => bundleRegistries.getStore()?.get(key) ?? current,
91
+ set: (value) => {
92
+ const scope = bundleRegistries.getStore();
93
+ if (scope === undefined) current = value;
94
+ else scope.set(key, value);
95
+ },
96
+ });
97
+ }
98
+ const loadedBundles = new Map();
99
+ const loadWorkflowBundle = (directory) => {
100
+ const known = loadedBundles.get(directory);
101
+ if (known !== undefined) return known;
102
+ const scope = new Map(registryKeys.map((key) => [key, new Map()]));
103
+ const loaded = bundleRegistries.run(scope, async () => {
104
+ const workflows = await import(pathToFileURL(directory + "/artifacts/client.mjs").href);
105
+ const { POST } = await import(pathToFileURL(directory + "/artifacts/flow.mjs").href);
106
+ if (typeof POST !== "function") throw new Error("pinned-workflow-unavailable");
107
+ return { workflows, handler: (request) => bundleRegistries.run(scope, () => POST(request)) };
108
+ });
109
+ loadedBundles.set(directory, loaded);
110
+ return loaded;
111
+ };
112
+ `;
113
+ }
@@ -1,79 +1,74 @@
1
+ import { turnHarness, harnessDefaults, nativeHarness, } from "../src/harness-defaults.js";
2
+ import { absoluteWorkflowFolder } from "../src/project-settings.js";
3
+ import { projectConfiguration, projectRoot, topLevel, } from "./project-configuration.js";
1
4
  import { isProfilesFile } from "../src/turn-profile.js";
2
- import { parseTokenPrices } from "../src/token-prices.js";
3
- import { execFileSync, spawn } from "node:child_process";
4
- import { copyFile, mkdir, readFile, rm, symlink, writeFile, } from "node:fs/promises";
5
+ import { parseCommands, parseCommandSeconds, } from "../src/command-settings.js";
6
+ import { parseFallbackModels, parseTokenPrices, } from "../src/token-prices.js";
7
+ import { readFile, writeFile } from "node:fs/promises";
8
+ import { homedir } from "node:os";
5
9
  import { dirname, extname, join, resolve } from "node:path";
6
- import packageMetadata from "#package" with { type: "json" };
7
- import { findPackageJSON } from "node:module";
8
10
  import { pathToFileURL } from "node:url";
9
- import { workflowDeclarations, workflowFiles, workflowManifests, } from "./self-host-workflows.js";
10
- import { isWorkflowManifest } from "./workflow-manifest.js";
11
+ import { preparedProject, } from "./self-host-project.js";
11
12
  import { selfUpdateMilliseconds } from "./self-update-host.js";
12
13
  import { hostedPrograms } from "./self-host-processes.js";
14
+ import { workflowBundleLoader } from "./self-host-workflows.js";
15
+ import { adoptRuntimeDirectory } from "./self-host-runtime.js";
16
+ import { parseSchedulesSetting } from "../src/workflow-schedule.js";
13
17
  const product = resolve(import.meta.dirname, "..");
14
18
  const flags = process.argv.slice(2);
15
19
  function flag(name) {
16
- const index = flags.lastIndexOf(name);
17
- return index === -1 ? undefined : flags[index + 1];
18
- }
19
- function topLevel(given) {
20
- try {
21
- return execFileSync("git", ["-C", given, "rev-parse", "--show-toplevel"], {
22
- encoding: "utf8",
23
- stdio: ["ignore", "pipe", "ignore"],
24
- }).trim();
25
- }
26
- catch {
27
- return given;
28
- }
20
+ const index = flags.findLastIndex((argument) => argument === name || argument.startsWith(`${name}=`));
21
+ const argument = flags[index];
22
+ return argument === name
23
+ ? flags[index + 1]
24
+ : argument?.slice(name.length + 1);
29
25
  }
30
26
  const runtimeArgument = flag("--runtime");
31
27
  if (runtimeArgument === undefined)
32
28
  throw new Error("The start program needs --runtime. Use: cloving start");
33
- const runtime = resolve(runtimeArgument);
29
+ const repository = await projectRoot(flag("--repository") ?? process.cwd());
30
+ const configuration = await projectConfiguration(repository, process.env);
31
+ const environment = configuration.environment;
32
+ const selectedRuntime = await adoptRuntimeDirectory({
33
+ runtime: resolve(runtimeArgument),
34
+ repository,
35
+ legacyRuntime: flag("--legacy-runtime"),
36
+ adoptionRecord: flag("--adoption-record"),
37
+ });
38
+ const runtime = selectedRuntime.runtime;
34
39
  const directory = dirname(runtime);
35
- const repository = topLevel(resolve(flag("--repository") ?? process.cwd()));
36
40
  const updateMilliseconds = await selfUpdateMilliseconds({
37
- seconds: process.env["CLOVING_SELF_UPDATE_SECONDS"],
41
+ seconds: environment["CLOVING_SELF_UPDATE_SECONDS"],
38
42
  repository,
39
43
  product: extname(import.meta.filename) === ".ts" ? topLevel(product) : product,
40
44
  });
41
45
  const client = flag("--client") ?? "cloving";
42
46
  const project = join(directory, "project");
43
- const concurrency = Number(process.env["CLOVING_HOST_BOUND"] ?? "8");
44
- const leaseText = process.env["CLOVING_OWNERSHIP_LEASE_SECONDS"];
47
+ const concurrency = Number(environment["CLOVING_HOST_BOUND"] ?? "8");
48
+ const leaseText = environment["CLOVING_OWNERSHIP_LEASE_SECONDS"];
45
49
  const leaseSeconds = leaseText === undefined ? undefined : Number(leaseText);
46
- const defaultCommand = [
47
- "claude",
48
- "-p",
49
- "--output-format",
50
- "stream-json",
51
- "--verbose",
52
- "--permission-mode",
53
- "acceptEdits",
54
- "--allowedTools",
55
- "Bash,Read,Edit,Write,Glob,Grep,WebSearch,WebFetch",
56
- "--max-budget-usd",
57
- "5",
58
- ];
59
- const defaultCodexCommand = [
60
- "codex",
61
- "exec",
62
- "--json",
63
- "--dangerously-bypass-approvals-and-sandbox",
64
- "--skip-git-repo-check",
65
- "-",
66
- ];
67
50
  function selectedWorker() {
68
- const worker = process.env["CLOVING_WORKER"] ?? "claude";
69
- if (worker === "claude" || worker === "codex")
70
- return worker;
71
- throw new Error(`The daemon did not start: invalid-worker: ${worker}`);
51
+ return checkedWorker(environment["CLOVING_WORKER"] ?? "claude");
52
+ }
53
+ function checkedWorker(name) {
54
+ try {
55
+ return turnHarness({
56
+ worker: name,
57
+ ...(configuration.harness === undefined
58
+ ? {}
59
+ : { harness: configuration.harness }),
60
+ }).worker;
61
+ }
62
+ catch (error) {
63
+ throw new Error(`The daemon did not start: harness-no-worker: ${name}`, {
64
+ cause: error,
65
+ });
66
+ }
72
67
  }
73
68
  async function profilesFile() {
74
- const path = process.env["CLOVING_PROFILES"];
69
+ const path = environment["CLOVING_PROFILES"];
75
70
  if (path === undefined)
76
- return {};
71
+ return configuration.profiles;
77
72
  try {
78
73
  const value = JSON.parse(await readFile(path, "utf8"));
79
74
  if (isProfilesFile(value))
@@ -84,8 +79,18 @@ async function profilesFile() {
84
79
  }
85
80
  throw new Error("The daemon did not start: invalid-profiles");
86
81
  }
82
+ function queueLanes() {
83
+ const value = environment["CLOVING_QUEUE_LANES"];
84
+ if (value === undefined)
85
+ return 1;
86
+ if (!/^[1-4]$/.test(value))
87
+ throw new Error("The daemon did not start: invalid-queue-lanes");
88
+ if (environment["CLOVING_QUEUE_SECONDS"] === undefined)
89
+ throw new Error("The daemon did not start: queue-lanes-needs-queue");
90
+ return Number(value);
91
+ }
87
92
  function queueInterval(commands) {
88
- const value = process.env["CLOVING_QUEUE_SECONDS"];
93
+ const value = environment["CLOVING_QUEUE_SECONDS"];
89
94
  if (value === undefined)
90
95
  return undefined;
91
96
  const seconds = Number(value);
@@ -101,7 +106,7 @@ function queueInterval(commands) {
101
106
  return seconds * 1000;
102
107
  }
103
108
  function listed(name) {
104
- const given = process.env[name];
109
+ const given = environment[name];
105
110
  if (given === undefined)
106
111
  return undefined;
107
112
  const list = JSON.parse(given);
@@ -109,61 +114,6 @@ function listed(name) {
109
114
  throw new Error(`${name} is not a JSON list of texts.`);
110
115
  return list.map(String);
111
116
  }
112
- function record(value) {
113
- return typeof value === "object" && value !== null ? { ...value } : {};
114
- }
115
- function ended(argumentsList, environment) {
116
- return new Promise((settle, reject) => {
117
- const child = spawn(process.execPath, argumentsList, {
118
- cwd: project,
119
- env: environment,
120
- stdio: "inherit",
121
- });
122
- for (const signal of ["SIGINT", "SIGTERM"])
123
- process.on(signal, () => child.kill(signal));
124
- child.once("error", reject);
125
- child.once("close", (status) => {
126
- settle(status ?? 1);
127
- });
128
- });
129
- }
130
- async function linkedPackages() {
131
- const modules = join(project, "node_modules");
132
- await mkdir(join(modules, "cloving"), { recursive: true });
133
- for (const name of Object.keys(packageMetadata.dependencies)) {
134
- const location = findPackageJSON(name, join(product, "package.json"));
135
- if (location === undefined)
136
- throw new Error(`missing-runtime-dependency: ${name}`);
137
- await mkdir(dirname(join(modules, name)), { recursive: true });
138
- await symlink(dirname(location), join(modules, name));
139
- }
140
- const manifest = record(packageMetadata);
141
- const exported = Object.keys(record(manifest["exports"])).filter((subpath) => subpath.startsWith("./workflows"));
142
- await symlink(join(product, "src"), join(modules, "cloving", "src"));
143
- await writeFile(join(modules, "cloving", "package.json"), JSON.stringify({
144
- name: manifest["name"],
145
- version: manifest["version"],
146
- type: "module",
147
- exports: Object.fromEntries(exported.map((subpath) => [
148
- subpath,
149
- `./src/${subpath.slice("./workflows/".length) || "workflows"}${extname(import.meta.filename)}`,
150
- ])),
151
- }));
152
- }
153
- async function registered() {
154
- const compiled = JSON.parse(await readFile(join(project, "artifacts/manifest.json"), "utf8"));
155
- if (!isWorkflowManifest(compiled))
156
- throw new Error("The compiled workflow manifest is invalid.");
157
- const manifests = workflowManifests(compiled);
158
- const declarations = await workflowDeclarations(join(product, "workflows"), manifests);
159
- const paths = new Map();
160
- for (const [functionName, manifest] of Object.entries(workflowManifests(compiled, declarations))) {
161
- const path = join(project, `${manifest.name}.workflow.json`);
162
- await writeFile(path, JSON.stringify(manifest));
163
- paths.set(functionName, path);
164
- }
165
- return { manifests: Object.fromEntries(paths), declarations };
166
- }
167
117
  function source(file) {
168
118
  return JSON.stringify(pathToFileURL(join(product, file.replace(/\.ts$/, extname(import.meta.filename)))).href);
169
119
  }
@@ -171,7 +121,6 @@ async function launchers(commands, workflows) {
171
121
  const settings = {
172
122
  ...commands,
173
123
  directory,
174
- repository,
175
124
  concurrency,
176
125
  runtimeDirectory: runtime,
177
126
  ...workflows,
@@ -183,22 +132,27 @@ await import("./main.mjs");
183
132
  await writeFile(join(project, "main.mjs"), `import * as workflows from "./artifacts/client.mjs";
184
133
  import { POST } from "./artifacts/flow.mjs";
185
134
  import { startDaemon } from ${source("src/daemon/daemon.ts")};
186
- const opening = await startDaemon({ ...JSON.parse(${JSON.stringify(JSON.stringify(settings))}), workflows, handler: POST });
135
+ ${workflowBundleLoader()}
136
+ const opening = await startDaemon({ ...JSON.parse(${JSON.stringify(JSON.stringify(settings))}), workflows, handler: POST, loadBundle: loadWorkflowBundle });
187
137
  if (opening.kind !== "started") {
188
138
  process.stderr.write("The daemon did not start: " + opening.reason + ": " + opening.detail + "\\n");
189
139
  process.exit(1);
190
140
  }
191
- process.stdout.write(${JSON.stringify(guide())});
141
+ process.stdout.write(${JSON.stringify(guide(workflows))});
192
142
  const stop = async () => { await opening.daemon.close(); process.exit(0); };
193
143
  process.once("SIGINT", stop);
194
144
  process.once("SIGTERM", stop);
195
145
  `);
196
146
  }
197
- function guide() {
147
+ function guide(workflows) {
198
148
  return [
199
149
  "Cloving runs. Stop it with Control-C.",
200
150
  `Repository: ${repository}`,
151
+ `Runtime directory: ${runtime}`,
201
152
  `Work trees: ${join(directory, "worktrees")}`,
153
+ ...(selectedRuntime.note === "" ? [] : [selectedRuntime.note]),
154
+ ...Object.entries(configuration.sources).map(([field, source]) => `${field}: ${source}`),
155
+ ...workflows.workflowRefusals.map((refusal) => `Refused workflow ${refusal.scope} ${refusal.label}: ${refusal.codes.join(", ")}`),
202
156
  "Commands for a second terminal:",
203
157
  ` ${client} run develop-ticket --ticket <ticket-id>`,
204
158
  ` ${client} run develop-issue --ticket <ticket-id>`,
@@ -210,43 +164,59 @@ function guide() {
210
164
  "",
211
165
  ].join("\n");
212
166
  }
213
- async function prepared() {
214
- await rm(project, { recursive: true, force: true });
215
- await mkdir(join(project, "workflows"), { recursive: true });
216
- await writeFile(join(project, "package.json"), '{"name":"cloving-self-host","private":true,"type":"module"}');
217
- for (const file of await workflowFiles(join(product, "workflows")))
218
- await copyFile(join(product, "workflows", file), join(project, "workflows", file));
219
- await linkedPackages();
220
- const compiled = await ended([
221
- join(product, `tools/compile-workflows${extname(import.meta.filename)}`),
222
- "workflows",
223
- "artifacts",
224
- ], process.env);
225
- if (compiled !== 0)
226
- throw new Error("The workflows did not compile.");
227
- return registered();
228
- }
229
- const tokenPrices = parseTokenPrices(process.env["CLOVING_TOKEN_PRICES"]);
167
+ const tokenPrices = parseTokenPrices(environment["CLOVING_TOKEN_PRICES"]);
168
+ const commands = parseCommands(environment["CLOVING_COMMANDS"]);
169
+ const commandSeconds = parseCommandSeconds(environment["CLOVING_COMMAND_SECONDS"]);
170
+ const fallbackModels = parseFallbackModels(environment["CLOVING_FALLBACK_MODELS"]);
230
171
  const profiles = await profilesFile();
172
+ const schedules = parseSchedulesSetting(environment["CLOVING_SCHEDULES"]);
231
173
  const worker = selectedWorker();
232
- const command = worker === "codex"
233
- ? (listed("CLOVING_CODEX_COMMAND") ?? defaultCodexCommand)
234
- : (listed("CLOVING_CLAUDE_COMMAND") ?? defaultCommand);
174
+ function nativeCommands() {
175
+ const names = new Set([
176
+ worker,
177
+ ...Object.values(profiles).map((profile) => checkedWorker(profile.harness ?? worker)),
178
+ ]);
179
+ return Object.fromEntries([...names].filter(nativeHarness).flatMap((name) => {
180
+ const variable = harnessDefaults(name).variable;
181
+ const command = variable === undefined ? undefined : listed(variable);
182
+ return command === undefined ? [] : [[name, command]];
183
+ }));
184
+ }
185
+ const workerCommands = nativeCommands();
186
+ const harness = configuration.harness ?? {};
187
+ const command = turnHarness({ worker, workerCommands, harness }).command;
235
188
  const nextCommand = listed("CLOVING_NEXT_COMMAND");
236
189
  const ticketCommand = listed("CLOVING_TICKET_COMMAND");
190
+ const lanes = queueLanes();
237
191
  const queueMilliseconds = queueInterval({ nextCommand, ticketCommand });
238
- const manifests = await prepared();
192
+ const manifests = await preparedProject({
193
+ product,
194
+ project,
195
+ repository,
196
+ home: homedir(),
197
+ xdgConfigHome: environment["XDG_CONFIG_HOME"],
198
+ userFolder: absoluteWorkflowFolder(environment["CLOVING_WORKFLOW_FOLDER"]),
199
+ });
239
200
  await launchers({
201
+ commands,
202
+ commandSeconds,
203
+ schedules,
240
204
  tokenPrices,
205
+ fallbackModels,
241
206
  worker,
207
+ workerCommands,
208
+ harness,
209
+ shell: environment["SHELL"] ?? "/bin/sh",
242
210
  profiles,
243
211
  command,
244
212
  ticketCommand,
245
213
  nextCommand,
246
214
  queueMilliseconds,
215
+ queueLanes: lanes,
247
216
  resetQueue: flags.includes("--reset-queue"),
248
217
  notifyCommand: listed("CLOVING_NOTIFY_COMMAND"),
249
218
  githubCommand: listed("CLOVING_GH_COMMAND"),
219
+ requiredChecks: listed("CLOVING_REQUIRED_CHECKS") ?? null,
250
220
  checkCommand: listed("CLOVING_CHECK_COMMAND"),
251
221
  privateTexts: listed("CLOVING_PRIVATE_TEXTS"),
252
222
  }, manifests);
@@ -257,5 +227,6 @@ process.exitCode = await hostedPrograms({
257
227
  directory,
258
228
  repository,
259
229
  updateMilliseconds,
260
- watchPort: process.env["CLOVING_WATCH_PORT"] ?? "3663",
230
+ watchPort: environment["CLOVING_WATCH_PORT"] ?? "3663",
231
+ phoneRelay: environment["CLOVING_PHONE_RELAY"] ?? "on",
261
232
  });
@@ -0,0 +1,5 @@
1
+ export declare function workflowPackageRoot(directory: string): Promise<string>;
2
+ export declare function workflowBundleDependencies(input: {
3
+ readonly product: string;
4
+ readonly packages: readonly string[];
5
+ }): Promise<string>;
@@ -0,0 +1,93 @@
1
+ import { createHash } from "node:crypto";
2
+ import { access, readFile, realpath } from "node:fs/promises";
3
+ import { findPackageJSON } from "node:module";
4
+ import { dirname, join, resolve } from "node:path";
5
+ import { record } from "../src/protocol.js";
6
+ export async function workflowPackageRoot(directory) {
7
+ const root = resolve(directory);
8
+ try {
9
+ await access(join(root, "package.json"));
10
+ return root;
11
+ }
12
+ catch (error) {
13
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
14
+ throw error;
15
+ }
16
+ const parent = dirname(root);
17
+ if (parent === root)
18
+ throw new Error("workflow-package-unavailable");
19
+ return workflowPackageRoot(parent);
20
+ }
21
+ function references(manifest) {
22
+ const dependencies = record(manifest["dependencies"]) ?? {};
23
+ const optional = record(manifest["optionalDependencies"]) ?? {};
24
+ const peers = record(manifest["peerDependencies"]) ?? {};
25
+ const peerMetadata = record(manifest["peerDependenciesMeta"]) ?? {};
26
+ return Object.keys({ ...dependencies, ...optional, ...peers })
27
+ .sort()
28
+ .map((name) => ({
29
+ name,
30
+ optional: Object.hasOwn(optional, name) ||
31
+ (!Object.hasOwn(dependencies, name) &&
32
+ record(peerMetadata[name])?.["optional"] === true),
33
+ }));
34
+ }
35
+ async function manifestFile(from, reference) {
36
+ try {
37
+ const file = findPackageJSON(reference.name, from);
38
+ if (file !== undefined)
39
+ return await realpath(file);
40
+ }
41
+ catch (error) {
42
+ if (!(error instanceof Error &&
43
+ "code" in error &&
44
+ error.code === "ERR_MODULE_NOT_FOUND"))
45
+ throw error;
46
+ }
47
+ if (reference.optional)
48
+ return undefined;
49
+ throw new Error("workflow-dependency-unavailable");
50
+ }
51
+ async function capturePackage(capture, input) {
52
+ const file = await manifestFile(input.from, input);
53
+ if (file === undefined)
54
+ return null;
55
+ const previous = capture.seen.get(file);
56
+ if (previous !== undefined)
57
+ return previous;
58
+ const manifest = await readFile(file, "utf8");
59
+ const parsed = JSON.parse(manifest);
60
+ const fields = record(parsed);
61
+ if (typeof fields?.["name"] !== "string" ||
62
+ typeof fields["version"] !== "string")
63
+ throw new Error("invalid-workflow-dependency");
64
+ const captured = { manifest, dependencies: {} };
65
+ const index = capture.packages.length;
66
+ capture.seen.set(file, index);
67
+ capture.packages.push(captured);
68
+ for (const reference of references(fields))
69
+ captured.dependencies[reference.name] = await capturePackage(capture, {
70
+ ...reference,
71
+ from: file,
72
+ });
73
+ return index;
74
+ }
75
+ export async function workflowBundleDependencies(input) {
76
+ const capture = { seen: new Map(), packages: [] };
77
+ const roots = {};
78
+ const manifest = join(await workflowPackageRoot(input.product), "package.json");
79
+ for (const name of [...input.packages].sort())
80
+ roots[name] = await capturePackage(capture, {
81
+ name,
82
+ from: manifest,
83
+ optional: false,
84
+ });
85
+ return JSON.stringify({
86
+ node: process.version,
87
+ product: createHash("sha256")
88
+ .update(await readFile(manifest))
89
+ .digest("hex"),
90
+ roots,
91
+ packages: capture.packages,
92
+ });
93
+ }
@@ -0,0 +1,20 @@
1
+ interface BundleInput {
2
+ readonly directory: string;
3
+ readonly repository: string;
4
+ readonly project: string;
5
+ }
6
+ interface BundleLookup {
7
+ readonly directory: string;
8
+ readonly repository: string;
9
+ readonly id: string;
10
+ }
11
+ type BundleResult = {
12
+ readonly kind: "available";
13
+ readonly directory: string;
14
+ } | {
15
+ readonly kind: "unavailable";
16
+ readonly code: "pinned-workflow-unavailable";
17
+ };
18
+ export declare function readRetainedWorkflowBundle(input: BundleLookup): Promise<BundleResult>;
19
+ export declare function retainWorkflowBundle(input: BundleInput): Promise<string>;
20
+ export {};