cloving 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/README.md +525 -185
  2. package/dist/src/agent-harness-shell.d.ts +12 -0
  3. package/dist/src/agent-harness-shell.js +90 -0
  4. package/dist/src/agent-harness-versions.d.ts +8 -0
  5. package/dist/src/agent-harness-versions.js +49 -0
  6. package/dist/src/agent-harnesses.d.ts +4 -0
  7. package/dist/src/agent-harnesses.js +13 -0
  8. package/dist/src/authority/commands.d.ts +1 -0
  9. package/dist/src/authority/commands.js +24 -4
  10. package/dist/src/authority/gate-reduction.d.ts +1 -0
  11. package/dist/src/authority/gate-reduction.js +18 -3
  12. package/dist/src/authority/gates.d.ts +2 -1
  13. package/dist/src/authority/gates.js +5 -1
  14. package/dist/src/authority/operations.js +1 -1
  15. package/dist/src/authority/reduction.d.ts +1 -1
  16. package/dist/src/authority/reduction.js +6 -1
  17. package/dist/src/authority/status-input.d.ts +1 -1
  18. package/dist/src/authority/status.d.ts +1 -0
  19. package/dist/src/authority/status.js +27 -3
  20. package/dist/src/authority/transitions.d.ts +5 -5
  21. package/dist/src/authority/transitions.js +6 -0
  22. package/dist/src/broker/actor/authority-delivery.js +1 -0
  23. package/dist/src/broker/actor/authority-queries.d.ts +7 -1
  24. package/dist/src/broker/actor/authority-queries.js +17 -2
  25. package/dist/src/broker/actor/authority-receipts.js +11 -1
  26. package/dist/src/broker/actor/authority-session.js +2 -2
  27. package/dist/src/broker/actor/authority-settings.js +4 -0
  28. package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
  29. package/dist/src/broker/actor/delivery-intents.js +4 -4
  30. package/dist/src/broker/actor/effect-delivery.js +4 -1
  31. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  32. package/dist/src/broker/actor/effect-queries.js +7 -0
  33. package/dist/src/broker/actor/pin-check.js +1 -1
  34. package/dist/src/broker/actor/stop-plan.js +1 -1
  35. package/dist/src/broker/actor/turn-state.js +1 -1
  36. package/dist/src/broker/authority-admission.js +22 -9
  37. package/dist/src/broker/authority-restore.js +1 -0
  38. package/dist/src/broker/decision-restore.js +4 -4
  39. package/dist/src/broker/socket-address.d.ts +3 -1
  40. package/dist/src/broker/socket-address.js +2 -2
  41. package/dist/src/cli/arguments.d.ts +11 -13
  42. package/dist/src/cli/arguments.js +37 -107
  43. package/dist/src/cli/command-effects.d.ts +7 -0
  44. package/dist/src/cli/command-effects.js +39 -0
  45. package/dist/src/cli/commands.js +11 -4
  46. package/dist/src/cli/config-arguments.d.ts +11 -0
  47. package/dist/src/cli/config-arguments.js +59 -0
  48. package/dist/src/cli/config-command.d.ts +2 -0
  49. package/dist/src/cli/config-command.js +105 -0
  50. package/dist/src/cli/config-file.d.ts +3 -0
  51. package/dist/src/cli/config-file.js +50 -0
  52. package/dist/src/cli/config-lock.d.ts +7 -0
  53. package/dist/src/cli/config-lock.js +61 -0
  54. package/dist/src/cli/config-notice.d.ts +5 -0
  55. package/dist/src/cli/config-notice.js +46 -0
  56. package/dist/src/cli/doctor-github.d.ts +9 -0
  57. package/dist/src/cli/doctor-github.js +138 -0
  58. package/dist/src/cli/doctor-harness.d.ts +13 -0
  59. package/dist/src/cli/doctor-harness.js +242 -0
  60. package/dist/src/cli/doctor-local.d.ts +18 -0
  61. package/dist/src/cli/doctor-local.js +77 -0
  62. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  63. package/dist/src/cli/doctor-runtime.js +176 -0
  64. package/dist/src/cli/doctor-service.d.ts +1 -0
  65. package/dist/src/cli/doctor-service.js +11 -0
  66. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  67. package/dist/src/cli/doctor-workflows.js +45 -0
  68. package/dist/src/cli/doctor.d.ts +15 -0
  69. package/dist/src/cli/doctor.js +190 -0
  70. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  71. package/dist/src/cli/github-ci-progress.js +83 -0
  72. package/dist/src/cli/github-retry.d.ts +6 -0
  73. package/dist/src/cli/github-retry.js +47 -0
  74. package/dist/src/cli/harness-probes.d.ts +22 -0
  75. package/dist/src/cli/harness-probes.js +183 -0
  76. package/dist/src/cli/main.d.ts +7 -1
  77. package/dist/src/cli/main.js +39 -61
  78. package/dist/src/cli/phone-arguments.d.ts +14 -0
  79. package/dist/src/cli/phone-arguments.js +37 -0
  80. package/dist/src/cli/phone-client.d.ts +2 -0
  81. package/dist/src/cli/phone-client.js +32 -0
  82. package/dist/src/cli/phone-command.d.ts +13 -0
  83. package/dist/src/cli/phone-command.js +101 -0
  84. package/dist/src/cli/probe-command.d.ts +36 -0
  85. package/dist/src/cli/probe-command.js +59 -0
  86. package/dist/src/cli/project-settings.d.ts +4 -0
  87. package/dist/src/cli/project-settings.js +33 -0
  88. package/dist/src/cli/render.d.ts +2 -1
  89. package/dist/src/cli/render.js +44 -28
  90. package/dist/src/cli/report-github.d.ts +18 -0
  91. package/dist/src/cli/report-github.js +200 -0
  92. package/dist/src/cli/report.d.ts +17 -0
  93. package/dist/src/cli/report.js +192 -0
  94. package/dist/src/cli/repository-arguments.d.ts +5 -0
  95. package/dist/src/cli/repository-arguments.js +34 -0
  96. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  97. package/dist/src/cli/runtime-arguments.js +15 -0
  98. package/dist/src/cli/runtime-directory.d.ts +6 -2
  99. package/dist/src/cli/runtime-directory.js +72 -14
  100. package/dist/src/cli/toolchain.d.ts +2 -0
  101. package/dist/src/cli/toolchain.js +22 -2
  102. package/dist/src/cli/usage-render.d.ts +5 -0
  103. package/dist/src/cli/usage-render.js +40 -1
  104. package/dist/src/cli/usage.d.ts +3 -3
  105. package/dist/src/cli/usage.js +70 -44
  106. package/dist/src/cli/watch-actions.d.ts +2 -0
  107. package/dist/src/cli/watch-actions.js +4 -4
  108. package/dist/src/cli/watch-board-view.d.ts +1 -1
  109. package/dist/src/cli/watch-board-view.js +8 -2
  110. package/dist/src/cli/watch-board.js +23 -10
  111. package/dist/src/cli/watch-card-forms.js +2 -2
  112. package/dist/src/cli/watch-client.d.ts +1 -1
  113. package/dist/src/cli/watch-client.js +7 -2
  114. package/dist/src/cli/watch-header-view.d.ts +27 -0
  115. package/dist/src/cli/watch-header-view.js +116 -0
  116. package/dist/src/cli/watch-model.js +17 -4
  117. package/dist/src/cli/watch-page.js +48 -12
  118. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  119. package/dist/src/cli/watch-phone-client.js +84 -0
  120. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  121. package/dist/src/cli/watch-phone-view.js +113 -0
  122. package/dist/src/cli/watch-phone.d.ts +5 -0
  123. package/dist/src/cli/watch-phone.js +53 -0
  124. package/dist/src/cli/watch-pull-request.d.ts +3 -1
  125. package/dist/src/cli/watch-pull-request.js +4 -0
  126. package/dist/src/cli/watch-render.d.ts +9 -1
  127. package/dist/src/cli/watch-server.js +23 -5
  128. package/dist/src/cli/watch-turn.d.ts +4 -1
  129. package/dist/src/cli/watch-turn.js +37 -1
  130. package/dist/src/cli/watch-usage.js +5 -1
  131. package/dist/src/cli/watch-view.d.ts +6 -20
  132. package/dist/src/cli/watch-view.js +14 -106
  133. package/dist/src/cli.js +106 -23
  134. package/dist/src/command-settings.d.ts +16 -0
  135. package/dist/src/command-settings.js +42 -0
  136. package/dist/src/configuration-change.d.ts +11 -0
  137. package/dist/src/configuration-change.js +62 -0
  138. package/dist/src/configuration-display.d.ts +21 -0
  139. package/dist/src/configuration-display.js +69 -0
  140. package/dist/src/configuration-schema.d.ts +49 -0
  141. package/dist/src/configuration-schema.js +159 -0
  142. package/dist/src/daemon/claude-turn.d.ts +19 -5
  143. package/dist/src/daemon/claude-turn.js +116 -53
  144. package/dist/src/daemon/claude-worker.d.ts +3 -3
  145. package/dist/src/daemon/claude-worker.js +65 -76
  146. package/dist/src/daemon/command-journal.d.ts +5 -0
  147. package/dist/src/daemon/command-journal.js +50 -0
  148. package/dist/src/daemon/command-process.d.ts +28 -0
  149. package/dist/src/daemon/command-process.js +164 -0
  150. package/dist/src/daemon/command-worker.d.ts +19 -0
  151. package/dist/src/daemon/command-worker.js +182 -0
  152. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  153. package/dist/src/daemon/cursor-stream.js +154 -0
  154. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  155. package/dist/src/daemon/daemon-adapters.js +102 -0
  156. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  157. package/dist/src/daemon/daemon-loops.js +39 -0
  158. package/dist/src/daemon/daemon.d.ts +2 -33
  159. package/dist/src/daemon/daemon.js +126 -132
  160. package/dist/src/daemon/declared-input.d.ts +3 -0
  161. package/dist/src/daemon/declared-input.js +9 -0
  162. package/dist/src/daemon/delivery-router.js +1 -1
  163. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  164. package/dist/src/daemon/gemini-stream.js +129 -0
  165. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  166. package/dist/src/daemon/github-ci-rerun.js +92 -0
  167. package/dist/src/daemon/github-ci.js +89 -8
  168. package/dist/src/daemon/github-merge-call.d.ts +2 -0
  169. package/dist/src/daemon/github-merge.js +7 -3
  170. package/dist/src/daemon/github-methods.js +10 -0
  171. package/dist/src/daemon/github-operation.d.ts +1 -0
  172. package/dist/src/daemon/github-retry.js +8 -44
  173. package/dist/src/daemon/issue-queue.d.ts +1 -0
  174. package/dist/src/daemon/issue-queue.js +3 -26
  175. package/dist/src/daemon/notify.js +2 -1
  176. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  177. package/dist/src/daemon/opencode-stream.js +87 -0
  178. package/dist/src/daemon/queue-status.d.ts +4 -0
  179. package/dist/src/daemon/queue-status.js +38 -0
  180. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  181. package/dist/src/daemon/retry-worktree.js +139 -0
  182. package/dist/src/daemon/retrying-turn.d.ts +2 -0
  183. package/dist/src/daemon/retrying-turn.js +108 -30
  184. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  185. package/dist/src/daemon/schedule-journal.js +57 -0
  186. package/dist/src/daemon/text-output.d.ts +18 -0
  187. package/dist/src/daemon/text-output.js +44 -0
  188. package/dist/src/daemon/ticket-registration.d.ts +5 -7
  189. package/dist/src/daemon/ticket-registration.js +85 -40
  190. package/dist/src/daemon/turn-command.d.ts +10 -0
  191. package/dist/src/daemon/turn-command.js +33 -0
  192. package/dist/src/daemon/turn-report.d.ts +18 -0
  193. package/dist/src/daemon/turn-report.js +79 -0
  194. package/dist/src/daemon/work-tree.d.ts +2 -1
  195. package/dist/src/daemon/work-tree.js +15 -12
  196. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  197. package/dist/src/daemon/workflow-generations.js +57 -0
  198. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  199. package/dist/src/daemon/workflow-replay.js +58 -0
  200. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  201. package/dist/src/daemon/workflow-schedules.js +185 -0
  202. package/dist/src/decision-wait.d.ts +1 -0
  203. package/dist/src/decision-wait.js +3 -0
  204. package/dist/src/delivery-backoff.d.ts +1 -0
  205. package/dist/src/delivery-backoff.js +3 -0
  206. package/dist/src/doctor-report.d.ts +24 -0
  207. package/dist/src/doctor-report.js +70 -0
  208. package/dist/src/execution-pin.d.ts +5 -0
  209. package/dist/src/execution-pin.js +67 -4
  210. package/dist/src/grok-result.d.ts +12 -0
  211. package/dist/src/grok-result.js +61 -0
  212. package/dist/src/harness-defaults.d.ts +35 -0
  213. package/dist/src/harness-defaults.js +121 -0
  214. package/dist/src/host/decision-resume.d.ts +35 -0
  215. package/dist/src/host/decision-resume.js +86 -0
  216. package/dist/src/host/gate-bridge.d.ts +48 -0
  217. package/dist/src/host/gate-bridge.js +124 -0
  218. package/dist/src/host/run-wait.d.ts +26 -0
  219. package/dist/src/host/run-wait.js +37 -0
  220. package/dist/src/host/start-delivery.d.ts +1 -1
  221. package/dist/src/host/start-delivery.js +10 -3
  222. package/dist/src/host/step-bridge-host.d.ts +6 -20
  223. package/dist/src/host/step-bridge-host.js +44 -58
  224. package/dist/src/merge-request.d.ts +19 -0
  225. package/dist/src/merge-request.js +32 -0
  226. package/dist/src/phone/canonical-json.d.ts +1 -0
  227. package/dist/src/phone/canonical-json.js +16 -0
  228. package/dist/src/phone/phone-link.d.ts +7 -0
  229. package/dist/src/phone/phone-link.js +21 -0
  230. package/dist/src/phone/qr-data.d.ts +8 -0
  231. package/dist/src/phone/qr-data.js +133 -0
  232. package/dist/src/phone/qr-matrix.d.ts +6 -0
  233. package/dist/src/phone/qr-matrix.js +175 -0
  234. package/dist/src/phone/qr-penalty.d.ts +3 -0
  235. package/dist/src/phone/qr-penalty.js +67 -0
  236. package/dist/src/phone/qr-picture.d.ts +5 -0
  237. package/dist/src/phone/qr-picture.js +24 -0
  238. package/dist/src/private-config.schema.json +263 -0
  239. package/dist/src/project-config.schema.json +65 -0
  240. package/dist/src/project-settings.d.ts +19 -0
  241. package/dist/src/project-settings.js +131 -0
  242. package/dist/src/relay/answer-check.d.ts +24 -0
  243. package/dist/src/relay/answer-check.js +145 -0
  244. package/dist/src/relay/answer-inbox.d.ts +15 -0
  245. package/dist/src/relay/answer-inbox.js +173 -0
  246. package/dist/src/relay/daemon-keys.d.ts +16 -0
  247. package/dist/src/relay/daemon-keys.js +75 -0
  248. package/dist/src/relay/decision-check.d.ts +3 -0
  249. package/dist/src/relay/decision-check.js +77 -0
  250. package/dist/src/relay/decision-close.d.ts +6 -0
  251. package/dist/src/relay/decision-close.js +72 -0
  252. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  253. package/dist/src/relay/decision-envelopes.js +93 -0
  254. package/dist/src/relay/decision-watch.d.ts +14 -0
  255. package/dist/src/relay/decision-watch.js +68 -0
  256. package/dist/src/relay/envelope-post.d.ts +8 -0
  257. package/dist/src/relay/envelope-post.js +71 -0
  258. package/dist/src/relay/envelope.d.ts +28 -0
  259. package/dist/src/relay/envelope.js +53 -0
  260. package/dist/src/relay/hpke.d.ts +25 -0
  261. package/dist/src/relay/hpke.js +108 -0
  262. package/dist/src/relay/pairing-checks.d.ts +42 -0
  263. package/dist/src/relay/pairing-checks.js +172 -0
  264. package/dist/src/relay/pairing-follow.d.ts +8 -0
  265. package/dist/src/relay/pairing-follow.js +95 -0
  266. package/dist/src/relay/pairing-session.d.ts +29 -0
  267. package/dist/src/relay/pairing-session.js +87 -0
  268. package/dist/src/relay/phone-delivery.d.ts +51 -0
  269. package/dist/src/relay/phone-delivery.js +139 -0
  270. package/dist/src/relay/phone-devices.d.ts +36 -0
  271. package/dist/src/relay/phone-devices.js +46 -0
  272. package/dist/src/relay/phone-inbox.d.ts +18 -0
  273. package/dist/src/relay/phone-inbox.js +17 -0
  274. package/dist/src/relay/phone-operations.d.ts +18 -0
  275. package/dist/src/relay/phone-operations.js +121 -0
  276. package/dist/src/relay/phone-outbox.d.ts +21 -0
  277. package/dist/src/relay/phone-outbox.js +25 -0
  278. package/dist/src/relay/phone-socket.d.ts +6 -0
  279. package/dist/src/relay/phone-socket.js +63 -0
  280. package/dist/src/relay/relay-control.d.ts +7 -0
  281. package/dist/src/relay/relay-control.js +24 -0
  282. package/dist/src/relay/relay-files.d.ts +2 -0
  283. package/dist/src/relay/relay-files.js +23 -0
  284. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  285. package/dist/src/relay/relay-heartbeat.js +81 -0
  286. package/dist/src/relay/relay-http.d.ts +14 -0
  287. package/dist/src/relay/relay-http.js +63 -0
  288. package/dist/src/relay/relay-registration.d.ts +15 -0
  289. package/dist/src/relay/relay-registration.js +63 -0
  290. package/dist/src/relay/relay-service.d.ts +25 -0
  291. package/dist/src/relay/relay-service.js +216 -0
  292. package/dist/src/relay/relay-store.d.ts +48 -0
  293. package/dist/src/relay/relay-store.js +131 -0
  294. package/dist/src/relay/sealed-post.d.ts +25 -0
  295. package/dist/src/relay/sealed-post.js +52 -0
  296. package/dist/src/relay.d.ts +1 -0
  297. package/dist/src/relay.js +8 -0
  298. package/dist/src/report-statistics.d.ts +50 -0
  299. package/dist/src/report-statistics.js +70 -0
  300. package/dist/src/report.d.ts +171 -0
  301. package/dist/src/report.js +119 -0
  302. package/dist/src/repository-identity.d.ts +4 -0
  303. package/dist/src/repository-identity.js +4 -0
  304. package/dist/src/review-subject.d.ts +41 -0
  305. package/dist/src/review-subject.js +91 -0
  306. package/dist/src/run-wait.d.ts +23 -0
  307. package/dist/src/run-wait.js +20 -0
  308. package/dist/src/service/active-tickets.d.ts +4 -0
  309. package/dist/src/service/active-tickets.js +49 -0
  310. package/dist/src/service/command-effects.d.ts +4 -0
  311. package/dist/src/service/command-effects.js +16 -0
  312. package/dist/src/service/decision-handler.d.ts +4 -0
  313. package/dist/src/service/decision-handler.js +39 -4
  314. package/dist/src/service/gateway.js +18 -3
  315. package/dist/src/service/registry.d.ts +16 -3
  316. package/dist/src/service/registry.js +34 -3
  317. package/dist/src/service/replies.d.ts +9 -1
  318. package/dist/src/service/replies.js +12 -0
  319. package/dist/src/service/run-handlers.js +14 -55
  320. package/dist/src/service/run-metadata.d.ts +8 -0
  321. package/dist/src/service/run-metadata.js +53 -0
  322. package/dist/src/service/run-waits.d.ts +3 -0
  323. package/dist/src/service/run-waits.js +41 -0
  324. package/dist/src/service/service.d.ts +18 -2
  325. package/dist/src/service/service.js +23 -7
  326. package/dist/src/service/submission-handler.d.ts +0 -1
  327. package/dist/src/service/submission-handler.js +6 -34
  328. package/dist/src/service/worker-port.d.ts +1 -0
  329. package/dist/src/service/worker-totals.js +8 -23
  330. package/dist/src/step-bridge.d.ts +23 -0
  331. package/dist/src/steps/decision-gate.d.ts +2 -1
  332. package/dist/src/steps/decision-gate.js +7 -0
  333. package/dist/src/steps/merge-by-person.d.ts +2 -0
  334. package/dist/src/steps/merge-by-person.js +18 -0
  335. package/dist/src/steps/merge-when-green.d.ts +2 -0
  336. package/dist/src/steps/merge-when-green.js +62 -0
  337. package/dist/src/steps/review-by-agent.d.ts +5 -0
  338. package/dist/src/steps/review-by-agent.js +124 -0
  339. package/dist/src/steps/review-by-person.d.ts +4 -0
  340. package/dist/src/steps/review-by-person.js +16 -0
  341. package/dist/src/steps/review-subject.d.ts +2 -0
  342. package/dist/src/steps/review-subject.js +11 -0
  343. package/dist/src/steps/run-command.d.ts +2 -0
  344. package/dist/src/steps/run-command.js +15 -0
  345. package/dist/src/steps/sleep.d.ts +3 -0
  346. package/dist/src/steps/sleep.js +19 -0
  347. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  348. package/dist/src/steps/wait-for-decision.js +71 -0
  349. package/dist/src/steps/wait-for-run.d.ts +5 -0
  350. package/dist/src/steps/wait-for-run.js +9 -0
  351. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  352. package/dist/src/storage/decision-snapshots.js +7 -1
  353. package/dist/src/submission.d.ts +4 -0
  354. package/dist/src/submission.js +6 -2
  355. package/dist/src/testing.d.ts +29 -0
  356. package/dist/src/testing.js +264 -0
  357. package/dist/src/ticket-status-stream.d.ts +9 -0
  358. package/dist/src/ticket-status-stream.js +94 -0
  359. package/dist/src/token-prices.d.ts +12 -4
  360. package/dist/src/token-prices.js +15 -2
  361. package/dist/src/turn-profile.d.ts +1 -0
  362. package/dist/src/turn-profile.js +8 -1
  363. package/dist/src/worker-usage.d.ts +16 -0
  364. package/dist/src/worker-usage.js +57 -0
  365. package/dist/src/workflow-admission.d.ts +5 -0
  366. package/dist/src/workflow-candidate.d.ts +7 -2
  367. package/dist/src/workflow-candidate.js +47 -5
  368. package/dist/src/workflow-declaration.d.ts +21 -3
  369. package/dist/src/workflow-declaration.js +77 -9
  370. package/dist/src/workflow-discovery.d.ts +2 -1
  371. package/dist/src/workflow-discovery.js +4 -1
  372. package/dist/src/workflow-refusals.js +3 -0
  373. package/dist/src/workflow-schedule.d.ts +22 -0
  374. package/dist/src/workflow-schedule.js +53 -0
  375. package/dist/src/workflows.d.ts +11 -1
  376. package/dist/src/workflows.js +8 -0
  377. package/dist/tools/admit-workflow.d.ts +1 -0
  378. package/dist/tools/admit-workflow.js +18 -5
  379. package/dist/tools/doctor-adoption.d.ts +1 -0
  380. package/dist/tools/doctor-adoption.js +11 -0
  381. package/dist/tools/project-configuration.d.ts +4 -0
  382. package/dist/tools/project-configuration.js +47 -0
  383. package/dist/tools/self-host-processes.d.ts +1 -0
  384. package/dist/tools/self-host-processes.js +33 -22
  385. package/dist/tools/self-host-project.d.ts +4 -0
  386. package/dist/tools/self-host-project.js +61 -14
  387. package/dist/tools/self-host-runtime.d.ts +16 -0
  388. package/dist/tools/self-host-runtime.js +60 -0
  389. package/dist/tools/self-host-workflows.d.ts +1 -0
  390. package/dist/tools/self-host-workflows.js +36 -1
  391. package/dist/tools/self-host.js +86 -61
  392. package/dist/tools/workflow-candidate-counts.d.ts +6 -2
  393. package/dist/tools/workflow-candidate-counts.js +31 -16
  394. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  395. package/dist/tools/workflow-candidate-fields.js +24 -0
  396. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  397. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  398. package/dist/tools/workflow-candidate-program.d.ts +2 -0
  399. package/dist/tools/workflow-candidate-program.js +36 -8
  400. package/dist/tools/workflow-candidate-source.js +77 -15
  401. package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
  402. package/dist/tools/workflow-candidate-syntax.js +70 -26
  403. package/dist/tools/workflow-command.d.ts +1 -0
  404. package/dist/tools/workflow-command.js +143 -0
  405. package/dist/tools/workflow-folder-capture.d.ts +1 -0
  406. package/dist/tools/workflow-folder-capture.js +47 -2
  407. package/dist/tools/workflow-folders.d.ts +17 -1
  408. package/dist/tools/workflow-folders.js +59 -6
  409. package/dist/tools/workflow-test-hook.d.ts +7 -0
  410. package/dist/tools/workflow-test-hook.js +16 -0
  411. package/dist/tools/workflow-test-loader.d.ts +1 -0
  412. package/dist/tools/workflow-test-loader.js +10 -0
  413. package/dist/workflows/develop-ticket.js +1 -1
  414. package/dist/workflows/ticket-prompts.js +5 -1
  415. package/package.json +46 -4
  416. package/templates/develop/README.md +78 -0
  417. package/templates/develop/develop/accept.ts +11 -0
  418. package/templates/develop/develop/flow-tests.ts +357 -0
  419. package/templates/develop/develop/local.ts +40 -0
  420. package/templates/develop/develop/option-tests.ts +174 -0
  421. package/templates/develop/develop/partial-choice.ts +29 -0
  422. package/templates/develop/develop/partial.ts +28 -0
  423. package/templates/develop/develop/pull.ts +152 -0
  424. package/templates/develop/develop/queue-partial.ts +39 -0
  425. package/templates/develop/develop/refusal-tests.ts +174 -0
  426. package/templates/develop/develop/report.ts +156 -0
  427. package/templates/develop/develop/round.ts +40 -0
  428. package/templates/develop/develop/scenarios.ts +87 -0
  429. package/templates/develop/develop/turn.ts +67 -0
  430. package/templates/develop/develop.declaration.json +24 -0
  431. package/templates/develop/develop.test.ts +287 -0
  432. package/templates/develop/develop.ts +30 -0
  433. package/templates/develop/template.json +153 -0
  434. package/dist/src/chats/analysis-batches.d.ts +0 -42
  435. package/dist/src/chats/analysis-batches.js +0 -97
  436. package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
  437. package/dist/src/chats/analysis-checkpoint.js +0 -31
  438. package/dist/src/chats/analysis-contract.d.ts +0 -80
  439. package/dist/src/chats/analysis-contract.js +0 -16
  440. package/dist/src/chats/analysis-data.d.ts +0 -3
  441. package/dist/src/chats/analysis-data.js +0 -85
  442. package/dist/src/chats/analysis-input.d.ts +0 -18
  443. package/dist/src/chats/analysis-input.js +0 -97
  444. package/dist/src/chats/analysis-links.d.ts +0 -2
  445. package/dist/src/chats/analysis-links.js +0 -25
  446. package/dist/src/chats/analysis-merge.d.ts +0 -16
  447. package/dist/src/chats/analysis-merge.js +0 -134
  448. package/dist/src/chats/analysis-prompt.d.ts +0 -18
  449. package/dist/src/chats/analysis-prompt.js +0 -42
  450. package/dist/src/chats/analysis-proposal.d.ts +0 -4
  451. package/dist/src/chats/analysis-proposal.js +0 -41
  452. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  453. package/dist/src/chats/analysis-provenance.js +0 -99
  454. package/dist/src/chats/analysis-shape.d.ts +0 -4
  455. package/dist/src/chats/analysis-shape.js +0 -235
  456. package/dist/src/chats/analysis.d.ts +0 -3
  457. package/dist/src/chats/analysis.js +0 -42
  458. package/dist/src/chats/corpus-input.d.ts +0 -5
  459. package/dist/src/chats/corpus-input.js +0 -288
  460. package/dist/src/chats/destination.d.ts +0 -4
  461. package/dist/src/chats/destination.js +0 -96
  462. package/dist/src/chats/import.d.ts +0 -15
  463. package/dist/src/chats/import.js +0 -243
  464. package/dist/src/chats/input-file.d.ts +0 -3
  465. package/dist/src/chats/input-file.js +0 -32
  466. package/dist/src/chats/normalize.d.ts +0 -29
  467. package/dist/src/chats/normalize.js +0 -155
  468. package/dist/src/chats/previous-import.d.ts +0 -5
  469. package/dist/src/chats/previous-import.js +0 -34
  470. package/dist/src/chats/reader.d.ts +0 -21
  471. package/dist/src/chats/reader.js +0 -118
  472. package/dist/src/chats/redact-import.d.ts +0 -14
  473. package/dist/src/chats/redact-import.js +0 -141
  474. package/dist/src/chats/redaction.d.ts +0 -41
  475. package/dist/src/chats/redaction.js +0 -161
  476. package/dist/src/chats/reference-mapping.d.ts +0 -16
  477. package/dist/src/chats/reference-mapping.js +0 -153
  478. package/dist/src/chats/revision-input.d.ts +0 -3
  479. package/dist/src/chats/revision-input.js +0 -180
  480. package/dist/src/chats/revision.d.ts +0 -48
  481. package/dist/src/chats/revision.js +0 -94
  482. package/dist/src/chats/selection.d.ts +0 -25
  483. package/dist/src/chats/selection.js +0 -109
  484. package/dist/src/chats/source.d.ts +0 -23
  485. package/dist/src/chats/source.js +0 -135
  486. package/dist/src/chats/structure.d.ts +0 -57
  487. package/dist/src/chats/structure.js +0 -216
  488. package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
  489. package/dist/src/chats/workflow-generation-projection.js +0 -75
  490. package/dist/src/chats/workflow-generation-source.d.ts +0 -25
  491. package/dist/src/chats/workflow-generation-source.js +0 -124
  492. package/dist/src/chats/workflow-generation-text.d.ts +0 -23
  493. package/dist/src/chats/workflow-generation-text.js +0 -74
  494. package/dist/src/chats/workflow-generation.d.ts +0 -69
  495. package/dist/src/chats/workflow-generation.js +0 -142
  496. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  497. package/dist/src/daemon/analysis-launch.js +0 -81
  498. package/dist/src/daemon/analysis-token.d.ts +0 -6
  499. package/dist/src/daemon/analysis-token.js +0 -88
  500. package/dist/src/daemon/analysis-worker.d.ts +0 -20
  501. package/dist/src/daemon/analysis-worker.js +0 -271
  502. package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
  503. package/dist/src/daemon/chats-batch-binding.js +0 -99
  504. package/dist/src/daemon/chats-capture.d.ts +0 -18
  505. package/dist/src/daemon/chats-capture.js +0 -194
  506. package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
  507. package/dist/src/daemon/chats-checkpoints.js +0 -186
  508. package/dist/src/daemon/chats-files.d.ts +0 -42
  509. package/dist/src/daemon/chats-files.js +0 -252
  510. package/dist/src/daemon/chats-follow-up.d.ts +0 -38
  511. package/dist/src/daemon/chats-follow-up.js +0 -180
  512. package/dist/src/daemon/chats-question.d.ts +0 -15
  513. package/dist/src/daemon/chats-question.js +0 -93
  514. package/dist/src/daemon/chats-worker.d.ts +0 -13
  515. package/dist/src/daemon/chats-worker.js +0 -201
  516. package/dist/workflows/analyze-chats.d.ts +0 -15
  517. package/dist/workflows/analyze-chats.declaration.json +0 -22
  518. package/dist/workflows/analyze-chats.js +0 -250
@@ -121,10 +121,14 @@ export function pullOf(inputs, runId) {
121
121
  repository: inputs.repository,
122
122
  pullRequest,
123
123
  });
124
+ const ciReruns = inputs.records
125
+ .filter((item) => record(item.started)["runId"] === runId)
126
+ .flatMap((item) => item.ciReruns ?? []);
124
127
  return {
125
128
  pullRequest,
126
129
  reviews: reviewsOf(results),
127
130
  mergeCommit: mergeCommitOf(results),
131
+ ...(ciReruns.length === 0 ? {} : { ciReruns }),
128
132
  ...(mergeProof === null ? {} : { mergeProof }),
129
133
  };
130
134
  }
@@ -1,5 +1,7 @@
1
+ import type { CommandEffect } from "../command-settings.ts";
1
2
  import type { CardForm } from "./watch-run-input.ts";
2
- import type { WorkerUsage } from "../worker-usage.ts";
3
+ import type { CiRerunNotice } from "./github-ci-progress.ts";
4
+ import type { WorkerUsage, WorkerAttemptUsage } from "../worker-usage.ts";
3
5
  import type { PrIdentity, PrObservation } from "./watch-pr-identity.ts";
4
6
  import type { WorkflowRefusal } from "../workflow-refusals.ts";
5
7
  import type { Fields } from "../protocol.ts";
@@ -9,6 +11,8 @@ export interface WatchItem {
9
11
  readonly costUsd?: number;
10
12
  }
11
13
  export interface WatchTurn {
14
+ readonly attempts?: readonly WorkerAttemptUsage[];
15
+ readonly harness?: string;
12
16
  readonly estimatedCostUsd: number | null;
13
17
  readonly operationId: string;
14
18
  readonly usage: WorkerUsage;
@@ -64,6 +68,7 @@ export interface WatchStep {
64
68
  readonly startedAt: string | null;
65
69
  }
66
70
  export interface WatchCard {
71
+ readonly awaitedRunId?: string | null;
67
72
  readonly parentRunId?: string | null;
68
73
  readonly chainId?: string;
69
74
  readonly childRunIds?: readonly string[];
@@ -97,6 +102,9 @@ export interface WatchWorkflow {
97
102
  readonly columns: readonly WatchColumn[];
98
103
  }
99
104
  export interface WatchRun {
105
+ readonly awaitedRunId?: string | null;
106
+ readonly commandEffects?: readonly CommandEffect[];
107
+ readonly ciReruns?: readonly CiRerunNotice[];
100
108
  readonly parentRunId?: string | null;
101
109
  readonly chainId?: string;
102
110
  readonly childRunIds?: readonly string[];
@@ -1,5 +1,6 @@
1
1
  import { watchAction, watchActions, watchHost, } from "./watch-actions.js";
2
2
  import { observedBoard } from "./watch-pr-board.js";
3
+ import { isPhoneAction, phoneAction, phoneRead } from "./watch-phone.js";
3
4
  import { watchPrObserver } from "./watch-pr-settings.js";
4
5
  import { readdir, readFile, stat } from "node:fs/promises";
5
6
  import { createServer, } from "node:http";
@@ -7,6 +8,7 @@ import { homedir } from "node:os";
7
8
  import { dirname, join } from "node:path";
8
9
  import { fileURLToPath } from "node:url";
9
10
  import { watchReader } from "./watch-reads.js";
11
+ import { ciRerunNotices } from "./github-ci-progress.js";
10
12
  import { turnOf, watchModel } from "./watch-model.js";
11
13
  import { pageDocument } from "./watch-page.js";
12
14
  import { watchStream } from "./watch-stream.js";
@@ -82,7 +84,11 @@ async function githubRecords(watch) {
82
84
  if (started === null)
83
85
  continue;
84
86
  const result = await stored(join(journal, key, "result.json"));
85
- watch.github.set(key, { started, result });
87
+ watch.github.set(key, {
88
+ started,
89
+ result,
90
+ ciReruns: await ciRerunNotices(join(journal, key)),
91
+ });
86
92
  }
87
93
  return keys.flatMap((key) => watch.github.get(key) ?? []);
88
94
  }
@@ -121,6 +127,11 @@ async function fontReply(request) {
121
127
  cache: "public, max-age=31536000, immutable",
122
128
  };
123
129
  }
130
+ function routedAction(path) {
131
+ if (isPhoneAction(path))
132
+ return phoneAction;
133
+ return path === "/actions/run" ? watchAction : null;
134
+ }
124
135
  async function answered(watch, request) {
125
136
  if (!watchHost(request))
126
137
  return forbidden;
@@ -130,11 +141,12 @@ async function answered(watch, request) {
130
141
  const url = new URL(String(request.url), "http://localhost");
131
142
  if (request.method === "GET")
132
143
  return readReply(watch, url);
133
- if (request.method !== "POST" ||
134
- url.pathname !== "/actions/run" ||
135
- watch.actions === null)
144
+ if (request.method !== "POST" || watch.actions === null)
145
+ return notFound;
146
+ const act = routedAction(url.pathname);
147
+ if (act === null)
136
148
  return notFound;
137
- const body = await watchAction(watch.actions, request).catch(() => null);
149
+ const body = await act(watch.actions, request).catch(() => null);
138
150
  return body === null
139
151
  ? forbidden
140
152
  : { status: 200, type: "application/json", body };
@@ -153,6 +165,12 @@ async function readReply(watch, url) {
153
165
  type: "text/javascript; charset=utf-8",
154
166
  body: await readFile(libraryFile, "utf8"),
155
167
  };
168
+ if (path === "/phone.json")
169
+ return {
170
+ status: 200,
171
+ type: "application/json",
172
+ body: await phoneRead(watch.settings.runtimeDirectory),
173
+ };
156
174
  if (path !== "/data.json")
157
175
  return notFound;
158
176
  const runId = url.searchParams.get("runId");
@@ -1,5 +1,5 @@
1
1
  import { type Shown } from "./watch-element.ts";
2
- import { type Copying, type WatchDecision, type WatchEvent, type WatchItem, type WatchTurn } from "./watch-render.ts";
2
+ import { type Copying, type WatchDecision, type WatchEvent, type WatchItem, type WatchRun, type WatchTurn } from "./watch-render.ts";
3
3
  export declare function Item(props: {
4
4
  readonly item: WatchItem;
5
5
  }): Shown;
@@ -28,3 +28,6 @@ export declare function Decision(props: {
28
28
  export declare function Events(props: {
29
29
  readonly events: readonly WatchEvent[];
30
30
  }): Shown;
31
+ export declare function PullRequest(props: {
32
+ readonly run: WatchRun;
33
+ }): Shown;
@@ -1,4 +1,4 @@
1
- import { priceText, usageText } from "./usage-render.js";
1
+ import { priceText, usageText, attemptText } from "./usage-render.js";
2
2
  import { component, element } from "./watch-element.js";
3
3
  import { clockTime, counted, groupActivity, turnTime, } from "./watch-render.js";
4
4
  export function Item(props) {
@@ -43,10 +43,17 @@ export function Turn(props) {
43
43
  children: heading.filter((part) => part !== "").join(" · "),
44
44
  }),
45
45
  element("p", { class: "meta", children: place }),
46
+ turn.harness === undefined
47
+ ? null
48
+ : element("p", { class: "meta", children: `Harness: ${turn.harness}` }),
46
49
  element("p", {
47
50
  class: "turn-usage",
48
51
  children: usageText(turn.usage),
49
52
  }),
53
+ ...(turn.attempts ?? []).map((attempt) => element("p", {
54
+ class: "turn-attempt",
55
+ children: attemptText(attempt),
56
+ })),
50
57
  element("div", { class: "activity", children: activity }),
51
58
  ],
52
59
  });
@@ -133,3 +140,32 @@ export function Events(props) {
133
140
  ],
134
141
  });
135
142
  }
143
+ export function PullRequest(props) {
144
+ const { pullRequest, reviews, mergeCommit } = props.run;
145
+ if (pullRequest === null)
146
+ return null;
147
+ const link = element("a", {
148
+ href: pullRequest.url,
149
+ children: `#${String(pullRequest.number)}`,
150
+ });
151
+ const scores = reviews.map((review) => element("li", {
152
+ children: `Round ${String(review.round)} · Review ${String(review.score)}/5 · commit ${review.commit.slice(0, 7)}`,
153
+ }));
154
+ const merge = mergeCommit === null
155
+ ? null
156
+ : element("p", {
157
+ class: "meta",
158
+ children: [
159
+ "Merge commit ",
160
+ element("code", { children: mergeCommit }),
161
+ ],
162
+ });
163
+ return element("section", {
164
+ class: "pull",
165
+ children: [
166
+ element("h3", { children: ["Pull request ", link] }),
167
+ element("ul", { class: "reviews", children: scores }),
168
+ merge,
169
+ ],
170
+ });
171
+ }
@@ -1,5 +1,5 @@
1
1
  import { record } from "../protocol.js";
2
- import { priceOf, usageOf } from "../worker-usage.js";
2
+ import { priceOf, usageOf, attemptFields } from "../worker-usage.js";
3
3
  function text(value) {
4
4
  return typeof value === "string" ? value : "";
5
5
  }
@@ -41,6 +41,10 @@ export function statusTurns(turns, status) {
41
41
  emptyTurn(operationId, runId);
42
42
  return {
43
43
  ...known,
44
+ ...attemptFields(fields["attempts"]),
45
+ ...(typeof fields["harness"] === "string"
46
+ ? { harness: fields["harness"] }
47
+ : {}),
44
48
  runId,
45
49
  operationId,
46
50
  outcome: known.outcome === "in work" ? "ended" : known.outcome,
@@ -1,18 +1,16 @@
1
1
  import type { CardControls } from "./watch-card-view.ts";
2
+ import type { PhoneControls } from "./watch-phone-view.ts";
3
+ import { type StartControls } from "./watch-header-view.ts";
4
+ export { clove, Header } from "./watch-header-view.ts";
5
+ export type { StartControls } from "./watch-header-view.ts";
2
6
  import { type Shown } from "./watch-element.ts";
3
7
  import { type Copying, type WatchModel, type WatchPhase, type WatchRun } from "./watch-render.ts";
4
8
  import { type ColumnControls } from "./watch-board-view.ts";
5
- export declare function Queue(props: {
6
- readonly model: WatchModel;
7
- }): Shown;
9
+ export { PullRequest } from "./watch-turn.ts";
8
10
  interface Timed {
9
11
  readonly run: WatchRun;
10
12
  readonly now: string;
11
13
  }
12
- export declare const clove: {
13
- viewBox: string;
14
- paths: string[];
15
- };
16
14
  export declare function BannerDetail(props: Timed): Shown;
17
15
  export declare function Banner(props: Timed): Shown;
18
16
  export declare function Phases(props: {
@@ -23,21 +21,9 @@ export declare function Review(props: {
23
21
  readonly run: WatchRun;
24
22
  readonly round: number;
25
23
  }): Shown;
26
- export declare function PullRequest(props: {
27
- readonly run: WatchRun;
28
- }): Shown;
29
24
  export declare function Run(props: Timed & {
30
25
  readonly copying: Copying;
31
26
  }): Shown;
32
- export interface StartControls {
33
- readonly shown: boolean;
34
- readonly onToggle: () => void;
35
- }
36
- export declare function Header(props: {
37
- readonly model: WatchModel | null;
38
- readonly stale: boolean;
39
- readonly start?: StartControls;
40
- }): Shown;
41
27
  export interface PageProps {
42
28
  readonly cards?: CardControls;
43
29
  readonly model: WatchModel | null;
@@ -48,6 +34,7 @@ export interface PageProps {
48
34
  readonly copying: Copying;
49
35
  readonly columns?: ColumnControls;
50
36
  readonly start?: StartControls;
37
+ readonly phone?: PhoneControls | undefined;
51
38
  }
52
39
  export declare function RefusedWorkflows(props: {
53
40
  readonly model: WatchModel;
@@ -58,4 +45,3 @@ export declare function BoardPage(props: PageProps & {
58
45
  readonly workflowId: string | null;
59
46
  readonly down: Shown;
60
47
  }): Shown;
61
- export {};
@@ -1,45 +1,14 @@
1
+ import { Header, Queue } from "./watch-header-view.js";
2
+ export { clove, Header } from "./watch-header-view.js";
1
3
  import { priceText, usageText, totalsSuffix } from "./usage-render.js";
2
4
  import { component, element } from "./watch-element.js";
3
- import { clockTime, completedDetail, counted, elapsed, phaseTime, runName, runTone, waitingDetail, } from "./watch-render.js";
5
+ import { completedDetail, counted, elapsed, phaseTime, runName, runTone, waitingDetail, } from "./watch-render.js";
4
6
  import { Board, HandoffLinks, WorkflowList, } from "./watch-board-view.js";
5
7
  import { boardWorkflow, watchHash, watchLocation } from "./watch-navigation.js";
6
- import { Decision, Events, Turn } from "./watch-turn.js";
8
+ import { Decision, Events, Turn, PullRequest } from "./watch-turn.js";
9
+ import { Commands } from "./command-effects.js";
10
+ export { PullRequest } from "./watch-turn.js";
7
11
  import { StartRun } from "./watch-start-view.js";
8
- import { record } from "../protocol.js";
9
- export function Queue(props) {
10
- const queue = props.model.queue;
11
- if (queue === undefined)
12
- return null;
13
- const skipped = Array.isArray(queue["skipped"])
14
- ? queue["skipped"]
15
- : [];
16
- return [
17
- element("p", {
18
- class: "meta",
19
- children: `Queue: ${String(queue["busy"])} of ${String(queue["lanes"])} lanes busy`,
20
- }),
21
- ...skipped.map((value) => {
22
- const ticket = record(value) ?? {};
23
- const dependencies = ticket["dependencies"];
24
- const needs = Array.isArray(dependencies)
25
- ? `; needs ${dependencies.map(String).join(", ")}`
26
- : "";
27
- return element("p", {
28
- class: "meta",
29
- children: `Skipped ticket ${String(ticket["ticketId"])}: ${String(ticket["reason"])}${needs}`,
30
- });
31
- }),
32
- ];
33
- }
34
- export const clove = {
35
- viewBox: "0.6625858545303345 0.6630800366401672 46.674827575683594 46.673831939697266",
36
- paths: [
37
- "M41.47315,11.48535c-1.20117-0.12305-2.16211-1.08398-2.28418-2.28516c-0.17676-1.7334-1.01758-3.29492-2.36865-4.39648s-3.05078-1.61719-4.7832-1.43359c-3.34277,0.34082-5.86377,3.13086-5.86377,6.49121v14.13867c0,0.27637,0.22363,0.5,0.5,0.5H40.8125c3.59766,0,6.52441-2.92676,6.52441-6.52441C47.33692,14.61523,44.81592,11.82422,41.47315,11.48535z M35.56543,15.81543l-5.85791,5.85742c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648c-0.19531-0.19531-0.19531-0.51172,0-0.70703l5.85791-5.85742c0.19531-0.19531,0.51172-0.19531,0.70703,0C35.76073,15.30372,35.76074,15.62011,35.56543,15.81543z",
38
- "M15.30225,0.66308c-3.36035,0-6.15088,2.52051-6.49121,5.86328C8.68897,7.72852,7.72852,8.68945,6.52686,8.81152c-1.7334,0.17578-3.29492,1.01758-4.396,2.36816s-1.61035,3.0498-1.43408,4.7832c0.34033,3.34277,3.13086,5.86328,6.49121,5.86328h14.13867c0.27637,0,0.5-0.22363,0.5-0.5V7.18751C21.82666,3.58984,18.8999,0.66308,15.30225,0.66308z M18.99951,19.00001c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648l-5.85742-5.8584c-0.19531-0.19531-0.19531-0.51172,0-0.70703c0.19531-0.19531,0.51172-0.19531,0.70703,0l5.85742,5.8584C19.19482,18.48829,19.19482,18.80469,18.99951,19.00001z",
39
- "M24,26.17383H9.86133c-3.59766,0-6.52441,2.92676-6.52441,6.52441c0,3.35938,2.52051,6.14941,5.86377,6.49023c1.20117,0.12207,2.16211,1.08301,2.28418,2.28418c0.17676,1.7334,1.01758,3.29492,2.36865,4.39648c1.17529,0.95801,2.61377,1.46777,4.11035,1.46777c0.22314,0,0.44775-0.01074,0.67285-0.03418C21.97949,46.96189,24.5,44.17186,24.5,40.81248V26.67383C24.5,26.39746,24.27637,26.17383,24,26.17383z M21.67334,29.70704l-5.85791,5.8584c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648c-0.19531-0.19531-0.19531-0.51172,0-0.70703L20.9663,29c0.19531-0.19531,0.51172-0.19531,0.70703,0S21.86865,29.51172,21.67334,29.70704z",
40
- "M47.30322,32.03711c-0.34033-3.34277-3.13086-5.86328-6.49072-5.86328H26.67334c-0.27637,0-0.5,0.22363-0.5,0.5V40.8125c0,3.59766,2.92676,6.52441,6.52442,6.52441c3.36035,0,6.15088-2.52148,6.49121-5.86426c0.12207-1.20117,1.08301-2.16211,2.28418-2.28418c1.7334-0.17578,3.29492-1.01758,4.396-2.36816S47.47949,33.7705,47.30322,32.03711z M35.56543,35.56543c-0.09766,0.09766-0.22559,0.14648-0.35352,0.14648s-0.25586-0.04883-0.35352-0.14648l-5.85791-5.8584c-0.19531-0.19531-0.19531-0.51172,0-0.70703s0.51172-0.19531,0.70703,0l5.85791,5.8584C35.76074,35.05371,35.76074,35.37011,35.56543,35.56543z",
41
- ],
42
- };
43
12
  export function BannerDetail(props) {
44
13
  const { run, now } = props;
45
14
  const turn = run.turns.at(-1);
@@ -54,8 +23,9 @@ export function BannerDetail(props) {
54
23
  ? ""
55
24
  : ` · last output ${elapsed(turn.activeAt, now)} ago`;
56
25
  const last = turn.activity.at(-1)?.text ?? "The worker starts.";
26
+ const worker = turn.harness === undefined ? "The worker" : `The ${turn.harness} worker`;
57
27
  return [
58
- `Claude works for ${elapsed(turn.startedAt, now)} · ${counted(calls, "tool call")}${quiet}`,
28
+ `${worker} works for ${elapsed(turn.startedAt, now)} · ${counted(calls, "tool call")}${quiet}`,
59
29
  element("span", { class: "now", children: last }),
60
30
  ];
61
31
  }
@@ -115,35 +85,6 @@ export function Review(props) {
115
85
  }),
116
86
  });
117
87
  }
118
- export function PullRequest(props) {
119
- const { pullRequest, reviews, mergeCommit } = props.run;
120
- if (pullRequest === null)
121
- return null;
122
- const link = element("a", {
123
- href: pullRequest.url,
124
- children: `#${String(pullRequest.number)}`,
125
- });
126
- const scores = reviews.map((review) => element("li", {
127
- children: `Round ${String(review.round)} · Review ${String(review.score)}/5 · commit ${review.commit.slice(0, 7)}`,
128
- }));
129
- const merge = mergeCommit === null
130
- ? null
131
- : element("p", {
132
- class: "meta",
133
- children: [
134
- "Merge commit ",
135
- element("code", { children: mergeCommit }),
136
- ],
137
- });
138
- return element("section", {
139
- class: "pull",
140
- children: [
141
- element("h3", { children: ["Pull request ", link] }),
142
- element("ul", { class: "reviews", children: scores }),
143
- merge,
144
- ],
145
- });
146
- }
147
88
  export function Run(props) {
148
89
  const { run, now, copying } = props;
149
90
  const turn = run.turns.at(-1);
@@ -181,50 +122,17 @@ export function Run(props) {
181
122
  }),
182
123
  component(Phases, { phases: run.phases, now }),
183
124
  component(PullRequest, { run }),
125
+ (run.ciReruns ?? []).map((rerun) => element("p", {
126
+ class: "meta",
127
+ children: `CI rerun after a failed check: workflow ${rerun.run}, commit ${rerun.commit.slice(0, 7)}`,
128
+ })),
184
129
  run.decisions.map((decision) => component(Decision, { decision, turn, copying })),
185
130
  turns,
131
+ component(Commands, { effects: run.commandEffects ?? [] }),
186
132
  component(Events, { events: run.events }),
187
133
  element("p", { class: "meta foot", children: foot }),
188
134
  ];
189
135
  }
190
- export function Header(props) {
191
- const { model, stale } = props;
192
- const updated = model === null ? "" : `updated ${clockTime(model.updatedAt)}`;
193
- const stamp = stale
194
- ? element("span", {
195
- class: "bad",
196
- children: "The watch tool does not answer.",
197
- })
198
- : element("span", { children: updated });
199
- return element("header", {
200
- children: [
201
- element("strong", {
202
- class: "brand",
203
- children: [
204
- element("svg", {
205
- xmlns: "http://www.w3.org/2000/svg",
206
- "aria-hidden": "true",
207
- focusable: "false",
208
- viewBox: clove.viewBox,
209
- children: clove.paths.map((d) => element("path", { fill: "currentColor", d })),
210
- }),
211
- "cloving",
212
- ],
213
- }),
214
- stamp,
215
- props.start === undefined
216
- ? null
217
- : element("button", {
218
- type: "button",
219
- class: "start-toggle",
220
- "aria-controls": "start-run",
221
- "aria-expanded": String(props.start.shown),
222
- onClick: props.start.onToggle,
223
- children: "Start a run",
224
- }),
225
- ],
226
- });
227
- }
228
136
  export function RefusedWorkflows(props) {
229
137
  const refusals = props.model.workflowRefusals ?? [];
230
138
  if (refusals.length === 0)
@@ -279,7 +187,7 @@ export function BoardPage(props) {
279
187
  return element("div", {
280
188
  class: "board-page",
281
189
  children: [
282
- component(Header, { model, stale, start }),
190
+ component(Header, { model, stale, start, phone: props.phone, now }),
283
191
  component(Queue, { model }),
284
192
  down,
285
193
  component(RefusedWorkflows, { model }),
package/dist/src/cli.js CHANGED
@@ -1,11 +1,27 @@
1
1
  #!/usr/bin/env node
2
+ import { createProbeRunner } from "./cli/probe-command.js";
3
+ import { settingsEnvironment } from "./cli/project-settings.js";
2
4
  import { addAbortListener } from "node:events";
3
- import { execFile, spawn } from "node:child_process";
4
- import { delimiter, dirname, extname, join } from "node:path";
5
+ import { execFile, execFileSync, spawn } from "node:child_process";
6
+ import { existsSync, realpathSync } from "node:fs";
7
+ import { parseArgs } from "node:util";
8
+ import { delimiter, dirname, extname, join, resolve } from "node:path";
5
9
  import { main } from "./cli/main.js";
6
- import { clientCommand, runtimeDirectory } from "./cli/runtime-directory.js";
10
+ import { parseInvocation } from "./cli/arguments.js";
11
+ import { adoptionRecordPath, clientCommand, legacyRuntimeDirectory, runtimeDirectory, } from "./cli/runtime-directory.js";
7
12
  import { commandUsage } from "./cli/usage.js";
8
13
  const [command, ...options] = process.argv.slice(2);
14
+ function repositoryDirectory(directory) {
15
+ try {
16
+ return realpathSync(execFileSync("git", ["-C", resolve(directory), "rev-parse", "--show-toplevel"], {
17
+ encoding: "utf8",
18
+ stdio: ["ignore", "pipe", "ignore"],
19
+ }).trim());
20
+ }
21
+ catch {
22
+ return undefined;
23
+ }
24
+ }
9
25
  const watchCommand = async (request) => {
10
26
  const [command = "", ...argumentsList] = request.command;
11
27
  const completed = Promise.withResolvers();
@@ -42,17 +58,30 @@ const watchCommand = async (request) => {
42
58
  listener[Symbol.dispose]();
43
59
  }
44
60
  };
45
- function started(runtime, argumentsList) {
46
- const program = join(import.meta.dirname, "..", "tools", `self-host${extname(import.meta.filename)}`);
61
+ function startArguments(input) {
62
+ const { runtime, repository, argumentsList } = input;
47
63
  const located = [
48
64
  "--runtime",
49
- runtime,
65
+ runtimeDirectory(process.env, repository) ?? runtime,
50
66
  "--repository",
51
- process.cwd(),
67
+ repository ?? process.cwd(),
52
68
  "--client",
53
- clientCommand(process.env),
69
+ clientCommand(process.env, repository),
54
70
  ];
55
- const child = spawn(process.execPath, [program, ...located, ...argumentsList], {
71
+ const record = repository === undefined
72
+ ? undefined
73
+ : adoptionRecordPath(process.env, repository);
74
+ const legacy = legacyRuntimeDirectory(process.env);
75
+ if (!process.env["CLOVING_RUNTIME_DIR"] &&
76
+ record !== undefined &&
77
+ !existsSync(record) &&
78
+ legacy !== undefined)
79
+ located.push("--legacy-runtime", resolve(legacy), "--adoption-record", resolve(record));
80
+ return [...located, ...argumentsList];
81
+ }
82
+ function toolProcess(input) {
83
+ const program = join(import.meta.dirname, "..", "tools", `${input.tool}${extname(import.meta.filename)}`);
84
+ const child = spawn(process.execPath, [program, ...input.argumentsList], {
56
85
  stdio: "inherit",
57
86
  env: {
58
87
  ...process.env,
@@ -78,27 +107,81 @@ function started(runtime, argumentsList) {
78
107
  });
79
108
  });
80
109
  }
110
+ function started(input) {
111
+ return toolProcess({
112
+ tool: "self-host",
113
+ argumentsList: startArguments(input),
114
+ });
115
+ }
81
116
  async function start() {
82
117
  if (options.includes("--help")) {
83
118
  process.stdout.write(String(commandUsage["start"]));
84
119
  return 0;
85
120
  }
86
- const runtime = runtimeDirectory(process.env);
87
- if (runtime !== undefined) {
88
- let status = await started(runtime, options);
89
- const restarting = options.filter((option) => option !== "--reset-queue");
90
- while (status === 75)
91
- status = await started(runtime, restarting);
92
- return status === 0 ? 0 : 1;
121
+ const parsed = parseArgs({
122
+ args: options,
123
+ options: { repository: { type: "string" } },
124
+ strict: false,
125
+ allowPositionals: true,
126
+ });
127
+ const selected = parsed.values["repository"];
128
+ if (Object.hasOwn(parsed.values, "repository") &&
129
+ (typeof selected !== "string" || selected === "")) {
130
+ process.stderr.write("missing-value: --repository needs a directory.\n");
131
+ return 1;
93
132
  }
94
- process.stderr.write("runtime-directory-unknown: Set CLOVING_RUNTIME_DIR to the runtime directory of the service.\n");
95
- return 1;
133
+ if (parsed.positionals.length > 0) {
134
+ process.stderr.write("unexpected-argument: run cloving start --help for usage.\n");
135
+ return 1;
136
+ }
137
+ const repository = repositoryDirectory(typeof selected === "string" ? selected : process.cwd());
138
+ const runtime = runtimeDirectory(process.env, repository);
139
+ if (runtime === undefined) {
140
+ process.stderr.write("repository-unknown: Change to the service repository, use --repository <directory>, or set CLOVING_RUNTIME_DIR.\n");
141
+ return 1;
142
+ }
143
+ let status = await started({ runtime, argumentsList: options, repository });
144
+ const restarting = options.filter((option) => option !== "--reset-queue");
145
+ while (status === 75)
146
+ status = await started({
147
+ runtime,
148
+ argumentsList: restarting,
149
+ repository,
150
+ });
151
+ return status === 0 ? 0 : 1;
96
152
  }
97
- if (command === "start")
153
+ if (command === "workflows" && ["list", "test"].includes(options[0] ?? ""))
154
+ process.exitCode = await toolProcess({
155
+ tool: "workflow-command",
156
+ argumentsList: options,
157
+ });
158
+ else if (command === "templates")
159
+ process.exitCode = await toolProcess({
160
+ tool: "template-command",
161
+ argumentsList: options,
162
+ });
163
+ else if (command === "start")
98
164
  process.exitCode = await start();
99
- else
165
+ else {
166
+ const invocation = parseInvocation(process.argv.slice(2));
167
+ const repository = repositoryDirectory("repository" in invocation
168
+ ? (invocation.repository ?? process.cwd())
169
+ : process.cwd());
170
+ const settingsRepository = process.env["CLOVING_WATCH_REPOSITORY"] ?? repository;
171
+ const environment = invocation.kind === "watch" && settingsRepository !== undefined
172
+ ? settingsEnvironment(process.env, settingsRepository)
173
+ : process.env;
100
174
  await main(process.argv.slice(2), {
101
- repository: process.env["CLOVING_WATCH_REPOSITORY"],
102
- githubCommand: process.env["CLOVING_GH_COMMAND"],
103
- execute: watchCommand,
175
+ repository,
176
+ environment,
177
+ doctorProbe: createProbeRunner({
178
+ spawn: (input) => spawn(input.executable, input.arguments, input.options),
179
+ kill: (identifier, signal) => process.kill(identifier, signal),
180
+ }),
181
+ watchPr: {
182
+ repository: process.env["CLOVING_WATCH_REPOSITORY"],
183
+ githubCommand: environment["CLOVING_GH_COMMAND"],
184
+ execute: watchCommand,
185
+ },
104
186
  });
187
+ }
@@ -0,0 +1,16 @@
1
+ export type LocalCommands = Readonly<Record<string, readonly string[]>>;
2
+ export declare const commandLimits: {
3
+ stdoutBytes: number;
4
+ stderrBytes: number;
5
+ resultBytes: number;
6
+ };
7
+ export interface CommandEffect {
8
+ readonly operationId: string;
9
+ readonly name: string;
10
+ readonly state: string;
11
+ readonly exitCode: number | null;
12
+ readonly durationMilliseconds: number | null;
13
+ }
14
+ export type CommandEffects = (effects: readonly CommandEffect[]) => Promise<readonly CommandEffect[]>;
15
+ export declare function parseCommands(text: string | undefined): LocalCommands;
16
+ export declare function parseCommandSeconds(text: string | undefined): number;
@@ -0,0 +1,42 @@
1
+ import { record } from "./protocol.js";
2
+ export const commandLimits = {
3
+ stdoutBytes: 1_048_576,
4
+ stderrBytes: 65_536,
5
+ resultBytes: 3_145_728,
6
+ };
7
+ function argumentsList(value) {
8
+ return (Array.isArray(value) &&
9
+ typeof value[0] === "string" &&
10
+ value[0].startsWith("/") &&
11
+ Array.from(value).every((argument) => typeof argument === "string" && !argument.includes("\u0000")));
12
+ }
13
+ export function parseCommands(text) {
14
+ if (text === undefined)
15
+ return {};
16
+ try {
17
+ const fields = record(JSON.parse(text));
18
+ if (fields === undefined)
19
+ throw new Error("invalid-commands");
20
+ const commands = {};
21
+ for (const [name, argumentList] of Object.entries(fields)) {
22
+ if (!/^[A-Za-z0-9-]{1,64}$/.test(name) || !argumentsList(argumentList))
23
+ throw new Error("invalid-commands");
24
+ commands[name] = [...argumentList];
25
+ }
26
+ return commands;
27
+ }
28
+ catch {
29
+ throw new Error("invalid-commands");
30
+ }
31
+ }
32
+ export function parseCommandSeconds(text) {
33
+ if (text === undefined)
34
+ return 60;
35
+ const seconds = Number(text);
36
+ if (!/^\d+$/.test(text) ||
37
+ !Number.isInteger(seconds) ||
38
+ seconds < 1 ||
39
+ seconds > 3600)
40
+ throw new Error("invalid-command-seconds");
41
+ return seconds;
42
+ }
@@ -0,0 +1,11 @@
1
+ export interface SettingChange {
2
+ readonly field: string;
3
+ readonly action: "set" | "unset";
4
+ readonly value?: string;
5
+ readonly scope: "project" | "private";
6
+ }
7
+ export type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
8
+ readonly [name: string]: JsonValue;
9
+ };
10
+ export declare function settingValue(text: string): JsonValue;
11
+ export declare function changedConfiguration(contents: string | undefined, change: SettingChange): string;