cloving 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/README.md +525 -185
  2. package/dist/src/agent-harness-shell.d.ts +12 -0
  3. package/dist/src/agent-harness-shell.js +90 -0
  4. package/dist/src/agent-harness-versions.d.ts +8 -0
  5. package/dist/src/agent-harness-versions.js +49 -0
  6. package/dist/src/agent-harnesses.d.ts +4 -0
  7. package/dist/src/agent-harnesses.js +13 -0
  8. package/dist/src/authority/commands.d.ts +1 -0
  9. package/dist/src/authority/commands.js +24 -4
  10. package/dist/src/authority/gate-reduction.d.ts +1 -0
  11. package/dist/src/authority/gate-reduction.js +18 -3
  12. package/dist/src/authority/gates.d.ts +2 -1
  13. package/dist/src/authority/gates.js +5 -1
  14. package/dist/src/authority/operations.js +1 -1
  15. package/dist/src/authority/reduction.d.ts +1 -1
  16. package/dist/src/authority/reduction.js +6 -1
  17. package/dist/src/authority/status-input.d.ts +1 -1
  18. package/dist/src/authority/status.d.ts +1 -0
  19. package/dist/src/authority/status.js +27 -3
  20. package/dist/src/authority/transitions.d.ts +5 -5
  21. package/dist/src/authority/transitions.js +6 -0
  22. package/dist/src/broker/actor/authority-delivery.js +1 -0
  23. package/dist/src/broker/actor/authority-queries.d.ts +7 -1
  24. package/dist/src/broker/actor/authority-queries.js +17 -2
  25. package/dist/src/broker/actor/authority-receipts.js +11 -1
  26. package/dist/src/broker/actor/authority-session.js +2 -2
  27. package/dist/src/broker/actor/authority-settings.js +4 -0
  28. package/dist/src/broker/actor/delivery-intents.d.ts +2 -1
  29. package/dist/src/broker/actor/delivery-intents.js +4 -4
  30. package/dist/src/broker/actor/effect-delivery.js +4 -1
  31. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  32. package/dist/src/broker/actor/effect-queries.js +7 -0
  33. package/dist/src/broker/actor/pin-check.js +1 -1
  34. package/dist/src/broker/actor/stop-plan.js +1 -1
  35. package/dist/src/broker/actor/turn-state.js +1 -1
  36. package/dist/src/broker/authority-admission.js +22 -9
  37. package/dist/src/broker/authority-restore.js +1 -0
  38. package/dist/src/broker/decision-restore.js +4 -4
  39. package/dist/src/broker/socket-address.d.ts +3 -1
  40. package/dist/src/broker/socket-address.js +2 -2
  41. package/dist/src/cli/arguments.d.ts +11 -13
  42. package/dist/src/cli/arguments.js +37 -107
  43. package/dist/src/cli/command-effects.d.ts +7 -0
  44. package/dist/src/cli/command-effects.js +39 -0
  45. package/dist/src/cli/commands.js +11 -4
  46. package/dist/src/cli/config-arguments.d.ts +11 -0
  47. package/dist/src/cli/config-arguments.js +59 -0
  48. package/dist/src/cli/config-command.d.ts +2 -0
  49. package/dist/src/cli/config-command.js +105 -0
  50. package/dist/src/cli/config-file.d.ts +3 -0
  51. package/dist/src/cli/config-file.js +50 -0
  52. package/dist/src/cli/config-lock.d.ts +7 -0
  53. package/dist/src/cli/config-lock.js +61 -0
  54. package/dist/src/cli/config-notice.d.ts +5 -0
  55. package/dist/src/cli/config-notice.js +46 -0
  56. package/dist/src/cli/doctor-github.d.ts +9 -0
  57. package/dist/src/cli/doctor-github.js +138 -0
  58. package/dist/src/cli/doctor-harness.d.ts +13 -0
  59. package/dist/src/cli/doctor-harness.js +242 -0
  60. package/dist/src/cli/doctor-local.d.ts +18 -0
  61. package/dist/src/cli/doctor-local.js +77 -0
  62. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  63. package/dist/src/cli/doctor-runtime.js +176 -0
  64. package/dist/src/cli/doctor-service.d.ts +1 -0
  65. package/dist/src/cli/doctor-service.js +11 -0
  66. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  67. package/dist/src/cli/doctor-workflows.js +45 -0
  68. package/dist/src/cli/doctor.d.ts +15 -0
  69. package/dist/src/cli/doctor.js +190 -0
  70. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  71. package/dist/src/cli/github-ci-progress.js +83 -0
  72. package/dist/src/cli/github-retry.d.ts +6 -0
  73. package/dist/src/cli/github-retry.js +47 -0
  74. package/dist/src/cli/harness-probes.d.ts +22 -0
  75. package/dist/src/cli/harness-probes.js +183 -0
  76. package/dist/src/cli/main.d.ts +7 -1
  77. package/dist/src/cli/main.js +39 -61
  78. package/dist/src/cli/phone-arguments.d.ts +14 -0
  79. package/dist/src/cli/phone-arguments.js +37 -0
  80. package/dist/src/cli/phone-client.d.ts +2 -0
  81. package/dist/src/cli/phone-client.js +32 -0
  82. package/dist/src/cli/phone-command.d.ts +13 -0
  83. package/dist/src/cli/phone-command.js +101 -0
  84. package/dist/src/cli/probe-command.d.ts +36 -0
  85. package/dist/src/cli/probe-command.js +59 -0
  86. package/dist/src/cli/project-settings.d.ts +4 -0
  87. package/dist/src/cli/project-settings.js +33 -0
  88. package/dist/src/cli/render.d.ts +2 -1
  89. package/dist/src/cli/render.js +44 -28
  90. package/dist/src/cli/report-github.d.ts +18 -0
  91. package/dist/src/cli/report-github.js +200 -0
  92. package/dist/src/cli/report.d.ts +17 -0
  93. package/dist/src/cli/report.js +192 -0
  94. package/dist/src/cli/repository-arguments.d.ts +5 -0
  95. package/dist/src/cli/repository-arguments.js +34 -0
  96. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  97. package/dist/src/cli/runtime-arguments.js +15 -0
  98. package/dist/src/cli/runtime-directory.d.ts +6 -2
  99. package/dist/src/cli/runtime-directory.js +72 -14
  100. package/dist/src/cli/toolchain.d.ts +2 -0
  101. package/dist/src/cli/toolchain.js +22 -2
  102. package/dist/src/cli/usage-render.d.ts +5 -0
  103. package/dist/src/cli/usage-render.js +40 -1
  104. package/dist/src/cli/usage.d.ts +3 -3
  105. package/dist/src/cli/usage.js +70 -44
  106. package/dist/src/cli/watch-actions.d.ts +2 -0
  107. package/dist/src/cli/watch-actions.js +4 -4
  108. package/dist/src/cli/watch-board-view.d.ts +1 -1
  109. package/dist/src/cli/watch-board-view.js +8 -2
  110. package/dist/src/cli/watch-board.js +23 -10
  111. package/dist/src/cli/watch-card-forms.js +2 -2
  112. package/dist/src/cli/watch-client.d.ts +1 -1
  113. package/dist/src/cli/watch-client.js +7 -2
  114. package/dist/src/cli/watch-header-view.d.ts +27 -0
  115. package/dist/src/cli/watch-header-view.js +116 -0
  116. package/dist/src/cli/watch-model.js +17 -4
  117. package/dist/src/cli/watch-page.js +48 -12
  118. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  119. package/dist/src/cli/watch-phone-client.js +84 -0
  120. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  121. package/dist/src/cli/watch-phone-view.js +113 -0
  122. package/dist/src/cli/watch-phone.d.ts +5 -0
  123. package/dist/src/cli/watch-phone.js +53 -0
  124. package/dist/src/cli/watch-pull-request.d.ts +3 -1
  125. package/dist/src/cli/watch-pull-request.js +4 -0
  126. package/dist/src/cli/watch-render.d.ts +9 -1
  127. package/dist/src/cli/watch-server.js +23 -5
  128. package/dist/src/cli/watch-turn.d.ts +4 -1
  129. package/dist/src/cli/watch-turn.js +37 -1
  130. package/dist/src/cli/watch-usage.js +5 -1
  131. package/dist/src/cli/watch-view.d.ts +6 -20
  132. package/dist/src/cli/watch-view.js +14 -106
  133. package/dist/src/cli.js +106 -23
  134. package/dist/src/command-settings.d.ts +16 -0
  135. package/dist/src/command-settings.js +42 -0
  136. package/dist/src/configuration-change.d.ts +11 -0
  137. package/dist/src/configuration-change.js +62 -0
  138. package/dist/src/configuration-display.d.ts +21 -0
  139. package/dist/src/configuration-display.js +69 -0
  140. package/dist/src/configuration-schema.d.ts +49 -0
  141. package/dist/src/configuration-schema.js +159 -0
  142. package/dist/src/daemon/claude-turn.d.ts +19 -5
  143. package/dist/src/daemon/claude-turn.js +116 -53
  144. package/dist/src/daemon/claude-worker.d.ts +3 -3
  145. package/dist/src/daemon/claude-worker.js +65 -76
  146. package/dist/src/daemon/command-journal.d.ts +5 -0
  147. package/dist/src/daemon/command-journal.js +50 -0
  148. package/dist/src/daemon/command-process.d.ts +28 -0
  149. package/dist/src/daemon/command-process.js +164 -0
  150. package/dist/src/daemon/command-worker.d.ts +19 -0
  151. package/dist/src/daemon/command-worker.js +182 -0
  152. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  153. package/dist/src/daemon/cursor-stream.js +154 -0
  154. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  155. package/dist/src/daemon/daemon-adapters.js +102 -0
  156. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  157. package/dist/src/daemon/daemon-loops.js +39 -0
  158. package/dist/src/daemon/daemon.d.ts +2 -33
  159. package/dist/src/daemon/daemon.js +126 -132
  160. package/dist/src/daemon/declared-input.d.ts +3 -0
  161. package/dist/src/daemon/declared-input.js +9 -0
  162. package/dist/src/daemon/delivery-router.js +1 -1
  163. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  164. package/dist/src/daemon/gemini-stream.js +129 -0
  165. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  166. package/dist/src/daemon/github-ci-rerun.js +92 -0
  167. package/dist/src/daemon/github-ci.js +89 -8
  168. package/dist/src/daemon/github-merge-call.d.ts +2 -0
  169. package/dist/src/daemon/github-merge.js +7 -3
  170. package/dist/src/daemon/github-methods.js +10 -0
  171. package/dist/src/daemon/github-operation.d.ts +1 -0
  172. package/dist/src/daemon/github-retry.js +8 -44
  173. package/dist/src/daemon/issue-queue.d.ts +1 -0
  174. package/dist/src/daemon/issue-queue.js +3 -26
  175. package/dist/src/daemon/notify.js +2 -1
  176. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  177. package/dist/src/daemon/opencode-stream.js +87 -0
  178. package/dist/src/daemon/queue-status.d.ts +4 -0
  179. package/dist/src/daemon/queue-status.js +38 -0
  180. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  181. package/dist/src/daemon/retry-worktree.js +139 -0
  182. package/dist/src/daemon/retrying-turn.d.ts +2 -0
  183. package/dist/src/daemon/retrying-turn.js +108 -30
  184. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  185. package/dist/src/daemon/schedule-journal.js +57 -0
  186. package/dist/src/daemon/text-output.d.ts +18 -0
  187. package/dist/src/daemon/text-output.js +44 -0
  188. package/dist/src/daemon/ticket-registration.d.ts +5 -7
  189. package/dist/src/daemon/ticket-registration.js +85 -40
  190. package/dist/src/daemon/turn-command.d.ts +10 -0
  191. package/dist/src/daemon/turn-command.js +33 -0
  192. package/dist/src/daemon/turn-report.d.ts +18 -0
  193. package/dist/src/daemon/turn-report.js +79 -0
  194. package/dist/src/daemon/work-tree.d.ts +2 -1
  195. package/dist/src/daemon/work-tree.js +15 -12
  196. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  197. package/dist/src/daemon/workflow-generations.js +57 -0
  198. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  199. package/dist/src/daemon/workflow-replay.js +58 -0
  200. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  201. package/dist/src/daemon/workflow-schedules.js +185 -0
  202. package/dist/src/decision-wait.d.ts +1 -0
  203. package/dist/src/decision-wait.js +3 -0
  204. package/dist/src/delivery-backoff.d.ts +1 -0
  205. package/dist/src/delivery-backoff.js +3 -0
  206. package/dist/src/doctor-report.d.ts +24 -0
  207. package/dist/src/doctor-report.js +70 -0
  208. package/dist/src/execution-pin.d.ts +5 -0
  209. package/dist/src/execution-pin.js +67 -4
  210. package/dist/src/grok-result.d.ts +12 -0
  211. package/dist/src/grok-result.js +61 -0
  212. package/dist/src/harness-defaults.d.ts +35 -0
  213. package/dist/src/harness-defaults.js +121 -0
  214. package/dist/src/host/decision-resume.d.ts +35 -0
  215. package/dist/src/host/decision-resume.js +86 -0
  216. package/dist/src/host/gate-bridge.d.ts +48 -0
  217. package/dist/src/host/gate-bridge.js +124 -0
  218. package/dist/src/host/run-wait.d.ts +26 -0
  219. package/dist/src/host/run-wait.js +37 -0
  220. package/dist/src/host/start-delivery.d.ts +1 -1
  221. package/dist/src/host/start-delivery.js +10 -3
  222. package/dist/src/host/step-bridge-host.d.ts +6 -20
  223. package/dist/src/host/step-bridge-host.js +44 -58
  224. package/dist/src/merge-request.d.ts +19 -0
  225. package/dist/src/merge-request.js +32 -0
  226. package/dist/src/phone/canonical-json.d.ts +1 -0
  227. package/dist/src/phone/canonical-json.js +16 -0
  228. package/dist/src/phone/phone-link.d.ts +7 -0
  229. package/dist/src/phone/phone-link.js +21 -0
  230. package/dist/src/phone/qr-data.d.ts +8 -0
  231. package/dist/src/phone/qr-data.js +133 -0
  232. package/dist/src/phone/qr-matrix.d.ts +6 -0
  233. package/dist/src/phone/qr-matrix.js +175 -0
  234. package/dist/src/phone/qr-penalty.d.ts +3 -0
  235. package/dist/src/phone/qr-penalty.js +67 -0
  236. package/dist/src/phone/qr-picture.d.ts +5 -0
  237. package/dist/src/phone/qr-picture.js +24 -0
  238. package/dist/src/private-config.schema.json +263 -0
  239. package/dist/src/project-config.schema.json +65 -0
  240. package/dist/src/project-settings.d.ts +19 -0
  241. package/dist/src/project-settings.js +131 -0
  242. package/dist/src/relay/answer-check.d.ts +24 -0
  243. package/dist/src/relay/answer-check.js +145 -0
  244. package/dist/src/relay/answer-inbox.d.ts +15 -0
  245. package/dist/src/relay/answer-inbox.js +173 -0
  246. package/dist/src/relay/daemon-keys.d.ts +16 -0
  247. package/dist/src/relay/daemon-keys.js +75 -0
  248. package/dist/src/relay/decision-check.d.ts +3 -0
  249. package/dist/src/relay/decision-check.js +77 -0
  250. package/dist/src/relay/decision-close.d.ts +6 -0
  251. package/dist/src/relay/decision-close.js +72 -0
  252. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  253. package/dist/src/relay/decision-envelopes.js +93 -0
  254. package/dist/src/relay/decision-watch.d.ts +14 -0
  255. package/dist/src/relay/decision-watch.js +68 -0
  256. package/dist/src/relay/envelope-post.d.ts +8 -0
  257. package/dist/src/relay/envelope-post.js +71 -0
  258. package/dist/src/relay/envelope.d.ts +28 -0
  259. package/dist/src/relay/envelope.js +53 -0
  260. package/dist/src/relay/hpke.d.ts +25 -0
  261. package/dist/src/relay/hpke.js +108 -0
  262. package/dist/src/relay/pairing-checks.d.ts +42 -0
  263. package/dist/src/relay/pairing-checks.js +172 -0
  264. package/dist/src/relay/pairing-follow.d.ts +8 -0
  265. package/dist/src/relay/pairing-follow.js +95 -0
  266. package/dist/src/relay/pairing-session.d.ts +29 -0
  267. package/dist/src/relay/pairing-session.js +87 -0
  268. package/dist/src/relay/phone-delivery.d.ts +51 -0
  269. package/dist/src/relay/phone-delivery.js +139 -0
  270. package/dist/src/relay/phone-devices.d.ts +36 -0
  271. package/dist/src/relay/phone-devices.js +46 -0
  272. package/dist/src/relay/phone-inbox.d.ts +18 -0
  273. package/dist/src/relay/phone-inbox.js +17 -0
  274. package/dist/src/relay/phone-operations.d.ts +18 -0
  275. package/dist/src/relay/phone-operations.js +121 -0
  276. package/dist/src/relay/phone-outbox.d.ts +21 -0
  277. package/dist/src/relay/phone-outbox.js +25 -0
  278. package/dist/src/relay/phone-socket.d.ts +6 -0
  279. package/dist/src/relay/phone-socket.js +63 -0
  280. package/dist/src/relay/relay-control.d.ts +7 -0
  281. package/dist/src/relay/relay-control.js +24 -0
  282. package/dist/src/relay/relay-files.d.ts +2 -0
  283. package/dist/src/relay/relay-files.js +23 -0
  284. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  285. package/dist/src/relay/relay-heartbeat.js +81 -0
  286. package/dist/src/relay/relay-http.d.ts +14 -0
  287. package/dist/src/relay/relay-http.js +63 -0
  288. package/dist/src/relay/relay-registration.d.ts +15 -0
  289. package/dist/src/relay/relay-registration.js +63 -0
  290. package/dist/src/relay/relay-service.d.ts +25 -0
  291. package/dist/src/relay/relay-service.js +216 -0
  292. package/dist/src/relay/relay-store.d.ts +48 -0
  293. package/dist/src/relay/relay-store.js +131 -0
  294. package/dist/src/relay/sealed-post.d.ts +25 -0
  295. package/dist/src/relay/sealed-post.js +52 -0
  296. package/dist/src/relay.d.ts +1 -0
  297. package/dist/src/relay.js +8 -0
  298. package/dist/src/report-statistics.d.ts +50 -0
  299. package/dist/src/report-statistics.js +70 -0
  300. package/dist/src/report.d.ts +171 -0
  301. package/dist/src/report.js +119 -0
  302. package/dist/src/repository-identity.d.ts +4 -0
  303. package/dist/src/repository-identity.js +4 -0
  304. package/dist/src/review-subject.d.ts +41 -0
  305. package/dist/src/review-subject.js +91 -0
  306. package/dist/src/run-wait.d.ts +23 -0
  307. package/dist/src/run-wait.js +20 -0
  308. package/dist/src/service/active-tickets.d.ts +4 -0
  309. package/dist/src/service/active-tickets.js +49 -0
  310. package/dist/src/service/command-effects.d.ts +4 -0
  311. package/dist/src/service/command-effects.js +16 -0
  312. package/dist/src/service/decision-handler.d.ts +4 -0
  313. package/dist/src/service/decision-handler.js +39 -4
  314. package/dist/src/service/gateway.js +18 -3
  315. package/dist/src/service/registry.d.ts +16 -3
  316. package/dist/src/service/registry.js +34 -3
  317. package/dist/src/service/replies.d.ts +9 -1
  318. package/dist/src/service/replies.js +12 -0
  319. package/dist/src/service/run-handlers.js +14 -55
  320. package/dist/src/service/run-metadata.d.ts +8 -0
  321. package/dist/src/service/run-metadata.js +53 -0
  322. package/dist/src/service/run-waits.d.ts +3 -0
  323. package/dist/src/service/run-waits.js +41 -0
  324. package/dist/src/service/service.d.ts +18 -2
  325. package/dist/src/service/service.js +23 -7
  326. package/dist/src/service/submission-handler.d.ts +0 -1
  327. package/dist/src/service/submission-handler.js +6 -34
  328. package/dist/src/service/worker-port.d.ts +1 -0
  329. package/dist/src/service/worker-totals.js +8 -23
  330. package/dist/src/step-bridge.d.ts +23 -0
  331. package/dist/src/steps/decision-gate.d.ts +2 -1
  332. package/dist/src/steps/decision-gate.js +7 -0
  333. package/dist/src/steps/merge-by-person.d.ts +2 -0
  334. package/dist/src/steps/merge-by-person.js +18 -0
  335. package/dist/src/steps/merge-when-green.d.ts +2 -0
  336. package/dist/src/steps/merge-when-green.js +62 -0
  337. package/dist/src/steps/review-by-agent.d.ts +5 -0
  338. package/dist/src/steps/review-by-agent.js +124 -0
  339. package/dist/src/steps/review-by-person.d.ts +4 -0
  340. package/dist/src/steps/review-by-person.js +16 -0
  341. package/dist/src/steps/review-subject.d.ts +2 -0
  342. package/dist/src/steps/review-subject.js +11 -0
  343. package/dist/src/steps/run-command.d.ts +2 -0
  344. package/dist/src/steps/run-command.js +15 -0
  345. package/dist/src/steps/sleep.d.ts +3 -0
  346. package/dist/src/steps/sleep.js +19 -0
  347. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  348. package/dist/src/steps/wait-for-decision.js +71 -0
  349. package/dist/src/steps/wait-for-run.d.ts +5 -0
  350. package/dist/src/steps/wait-for-run.js +9 -0
  351. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  352. package/dist/src/storage/decision-snapshots.js +7 -1
  353. package/dist/src/submission.d.ts +4 -0
  354. package/dist/src/submission.js +6 -2
  355. package/dist/src/testing.d.ts +29 -0
  356. package/dist/src/testing.js +264 -0
  357. package/dist/src/ticket-status-stream.d.ts +9 -0
  358. package/dist/src/ticket-status-stream.js +94 -0
  359. package/dist/src/token-prices.d.ts +12 -4
  360. package/dist/src/token-prices.js +15 -2
  361. package/dist/src/turn-profile.d.ts +1 -0
  362. package/dist/src/turn-profile.js +8 -1
  363. package/dist/src/worker-usage.d.ts +16 -0
  364. package/dist/src/worker-usage.js +57 -0
  365. package/dist/src/workflow-admission.d.ts +5 -0
  366. package/dist/src/workflow-candidate.d.ts +7 -2
  367. package/dist/src/workflow-candidate.js +47 -5
  368. package/dist/src/workflow-declaration.d.ts +21 -3
  369. package/dist/src/workflow-declaration.js +77 -9
  370. package/dist/src/workflow-discovery.d.ts +2 -1
  371. package/dist/src/workflow-discovery.js +4 -1
  372. package/dist/src/workflow-refusals.js +3 -0
  373. package/dist/src/workflow-schedule.d.ts +22 -0
  374. package/dist/src/workflow-schedule.js +53 -0
  375. package/dist/src/workflows.d.ts +11 -1
  376. package/dist/src/workflows.js +8 -0
  377. package/dist/tools/admit-workflow.d.ts +1 -0
  378. package/dist/tools/admit-workflow.js +18 -5
  379. package/dist/tools/doctor-adoption.d.ts +1 -0
  380. package/dist/tools/doctor-adoption.js +11 -0
  381. package/dist/tools/project-configuration.d.ts +4 -0
  382. package/dist/tools/project-configuration.js +47 -0
  383. package/dist/tools/self-host-processes.d.ts +1 -0
  384. package/dist/tools/self-host-processes.js +33 -22
  385. package/dist/tools/self-host-project.d.ts +4 -0
  386. package/dist/tools/self-host-project.js +61 -14
  387. package/dist/tools/self-host-runtime.d.ts +16 -0
  388. package/dist/tools/self-host-runtime.js +60 -0
  389. package/dist/tools/self-host-workflows.d.ts +1 -0
  390. package/dist/tools/self-host-workflows.js +36 -1
  391. package/dist/tools/self-host.js +86 -61
  392. package/dist/tools/workflow-candidate-counts.d.ts +6 -2
  393. package/dist/tools/workflow-candidate-counts.js +31 -16
  394. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  395. package/dist/tools/workflow-candidate-fields.js +24 -0
  396. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  397. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  398. package/dist/tools/workflow-candidate-program.d.ts +2 -0
  399. package/dist/tools/workflow-candidate-program.js +36 -8
  400. package/dist/tools/workflow-candidate-source.js +77 -15
  401. package/dist/tools/workflow-candidate-syntax.d.ts +8 -2
  402. package/dist/tools/workflow-candidate-syntax.js +70 -26
  403. package/dist/tools/workflow-command.d.ts +1 -0
  404. package/dist/tools/workflow-command.js +143 -0
  405. package/dist/tools/workflow-folder-capture.d.ts +1 -0
  406. package/dist/tools/workflow-folder-capture.js +47 -2
  407. package/dist/tools/workflow-folders.d.ts +17 -1
  408. package/dist/tools/workflow-folders.js +59 -6
  409. package/dist/tools/workflow-test-hook.d.ts +7 -0
  410. package/dist/tools/workflow-test-hook.js +16 -0
  411. package/dist/tools/workflow-test-loader.d.ts +1 -0
  412. package/dist/tools/workflow-test-loader.js +10 -0
  413. package/dist/workflows/develop-ticket.js +1 -1
  414. package/dist/workflows/ticket-prompts.js +5 -1
  415. package/package.json +46 -4
  416. package/templates/develop/README.md +78 -0
  417. package/templates/develop/develop/accept.ts +11 -0
  418. package/templates/develop/develop/flow-tests.ts +357 -0
  419. package/templates/develop/develop/local.ts +40 -0
  420. package/templates/develop/develop/option-tests.ts +174 -0
  421. package/templates/develop/develop/partial-choice.ts +29 -0
  422. package/templates/develop/develop/partial.ts +28 -0
  423. package/templates/develop/develop/pull.ts +152 -0
  424. package/templates/develop/develop/queue-partial.ts +39 -0
  425. package/templates/develop/develop/refusal-tests.ts +174 -0
  426. package/templates/develop/develop/report.ts +156 -0
  427. package/templates/develop/develop/round.ts +40 -0
  428. package/templates/develop/develop/scenarios.ts +87 -0
  429. package/templates/develop/develop/turn.ts +67 -0
  430. package/templates/develop/develop.declaration.json +24 -0
  431. package/templates/develop/develop.test.ts +287 -0
  432. package/templates/develop/develop.ts +30 -0
  433. package/templates/develop/template.json +153 -0
  434. package/dist/src/chats/analysis-batches.d.ts +0 -42
  435. package/dist/src/chats/analysis-batches.js +0 -97
  436. package/dist/src/chats/analysis-checkpoint.d.ts +0 -29
  437. package/dist/src/chats/analysis-checkpoint.js +0 -31
  438. package/dist/src/chats/analysis-contract.d.ts +0 -80
  439. package/dist/src/chats/analysis-contract.js +0 -16
  440. package/dist/src/chats/analysis-data.d.ts +0 -3
  441. package/dist/src/chats/analysis-data.js +0 -85
  442. package/dist/src/chats/analysis-input.d.ts +0 -18
  443. package/dist/src/chats/analysis-input.js +0 -97
  444. package/dist/src/chats/analysis-links.d.ts +0 -2
  445. package/dist/src/chats/analysis-links.js +0 -25
  446. package/dist/src/chats/analysis-merge.d.ts +0 -16
  447. package/dist/src/chats/analysis-merge.js +0 -134
  448. package/dist/src/chats/analysis-prompt.d.ts +0 -18
  449. package/dist/src/chats/analysis-prompt.js +0 -42
  450. package/dist/src/chats/analysis-proposal.d.ts +0 -4
  451. package/dist/src/chats/analysis-proposal.js +0 -41
  452. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  453. package/dist/src/chats/analysis-provenance.js +0 -99
  454. package/dist/src/chats/analysis-shape.d.ts +0 -4
  455. package/dist/src/chats/analysis-shape.js +0 -235
  456. package/dist/src/chats/analysis.d.ts +0 -3
  457. package/dist/src/chats/analysis.js +0 -42
  458. package/dist/src/chats/corpus-input.d.ts +0 -5
  459. package/dist/src/chats/corpus-input.js +0 -288
  460. package/dist/src/chats/destination.d.ts +0 -4
  461. package/dist/src/chats/destination.js +0 -96
  462. package/dist/src/chats/import.d.ts +0 -15
  463. package/dist/src/chats/import.js +0 -243
  464. package/dist/src/chats/input-file.d.ts +0 -3
  465. package/dist/src/chats/input-file.js +0 -32
  466. package/dist/src/chats/normalize.d.ts +0 -29
  467. package/dist/src/chats/normalize.js +0 -155
  468. package/dist/src/chats/previous-import.d.ts +0 -5
  469. package/dist/src/chats/previous-import.js +0 -34
  470. package/dist/src/chats/reader.d.ts +0 -21
  471. package/dist/src/chats/reader.js +0 -118
  472. package/dist/src/chats/redact-import.d.ts +0 -14
  473. package/dist/src/chats/redact-import.js +0 -141
  474. package/dist/src/chats/redaction.d.ts +0 -41
  475. package/dist/src/chats/redaction.js +0 -161
  476. package/dist/src/chats/reference-mapping.d.ts +0 -16
  477. package/dist/src/chats/reference-mapping.js +0 -153
  478. package/dist/src/chats/revision-input.d.ts +0 -3
  479. package/dist/src/chats/revision-input.js +0 -180
  480. package/dist/src/chats/revision.d.ts +0 -48
  481. package/dist/src/chats/revision.js +0 -94
  482. package/dist/src/chats/selection.d.ts +0 -25
  483. package/dist/src/chats/selection.js +0 -109
  484. package/dist/src/chats/source.d.ts +0 -23
  485. package/dist/src/chats/source.js +0 -135
  486. package/dist/src/chats/structure.d.ts +0 -57
  487. package/dist/src/chats/structure.js +0 -216
  488. package/dist/src/chats/workflow-generation-projection.d.ts +0 -8
  489. package/dist/src/chats/workflow-generation-projection.js +0 -75
  490. package/dist/src/chats/workflow-generation-source.d.ts +0 -25
  491. package/dist/src/chats/workflow-generation-source.js +0 -124
  492. package/dist/src/chats/workflow-generation-text.d.ts +0 -23
  493. package/dist/src/chats/workflow-generation-text.js +0 -74
  494. package/dist/src/chats/workflow-generation.d.ts +0 -69
  495. package/dist/src/chats/workflow-generation.js +0 -142
  496. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  497. package/dist/src/daemon/analysis-launch.js +0 -81
  498. package/dist/src/daemon/analysis-token.d.ts +0 -6
  499. package/dist/src/daemon/analysis-token.js +0 -88
  500. package/dist/src/daemon/analysis-worker.d.ts +0 -20
  501. package/dist/src/daemon/analysis-worker.js +0 -271
  502. package/dist/src/daemon/chats-batch-binding.d.ts +0 -23
  503. package/dist/src/daemon/chats-batch-binding.js +0 -99
  504. package/dist/src/daemon/chats-capture.d.ts +0 -18
  505. package/dist/src/daemon/chats-capture.js +0 -194
  506. package/dist/src/daemon/chats-checkpoints.d.ts +0 -41
  507. package/dist/src/daemon/chats-checkpoints.js +0 -186
  508. package/dist/src/daemon/chats-files.d.ts +0 -42
  509. package/dist/src/daemon/chats-files.js +0 -252
  510. package/dist/src/daemon/chats-follow-up.d.ts +0 -38
  511. package/dist/src/daemon/chats-follow-up.js +0 -180
  512. package/dist/src/daemon/chats-question.d.ts +0 -15
  513. package/dist/src/daemon/chats-question.js +0 -93
  514. package/dist/src/daemon/chats-worker.d.ts +0 -13
  515. package/dist/src/daemon/chats-worker.js +0 -201
  516. package/dist/workflows/analyze-chats.d.ts +0 -15
  517. package/dist/workflows/analyze-chats.declaration.json +0 -22
  518. package/dist/workflows/analyze-chats.js +0 -250
@@ -1,27 +1,27 @@
1
+ import { configCommand } from "./config-command.js";
2
+ import { doctorCommand } from "./doctor.js";
1
3
  import { randomUUID } from "node:crypto";
2
4
  import packageMetadata from "#package" with { type: "json" };
3
- import { redactImport } from "../chats/redact-import.js";
4
- import { emptyCounts } from "../chats/redaction.js";
5
- import { importChats } from "../chats/import.js";
6
5
  import { parseInvocation } from "./arguments.js";
6
+ import { phoneCommand } from "./phone-command.js";
7
7
  import { runtimeCommand } from "./commands.js";
8
8
  import { clientCommand, runtimeDirectory } from "./runtime-directory.js";
9
- import { chatsRedactUsage, chatsImportUsage, usage, validateUsage, } from "./usage.js";
9
+ import { commandUsage, configUsage, phoneUsage, usage, validateUsage, } from "./usage.js";
10
10
  import { validateWorkflow } from "./validate.js";
11
11
  const helpTexts = {
12
12
  help: usage,
13
13
  version: `${packageMetadata.version}\n`,
14
14
  "validate-help": validateUsage,
15
- "chats-import-help": chatsImportUsage,
16
- "chats-redact-help": chatsRedactUsage,
15
+ "phone-help": phoneUsage,
16
+ "doctor-help": String(commandUsage["doctor"]),
17
+ "config-help": configUsage,
17
18
  };
18
19
  function helpInvocation(invocation) {
19
20
  return Object.hasOwn(helpTexts, invocation.kind);
20
21
  }
21
- export async function main(argumentsList, watchPr) {
22
+ export async function main(argumentsList, context = { repository: undefined }) {
23
+ const { repository, environment = process.env } = context;
22
24
  const invocation = parseInvocation(argumentsList);
23
- if (refuseChatPlatform(invocation))
24
- return;
25
25
  if (helpInvocation(invocation)) {
26
26
  process.stdout.write(helpTexts[invocation.kind]);
27
27
  return;
@@ -32,31 +32,32 @@ export async function main(argumentsList, watchPr) {
32
32
  else if (invocation.kind === "validate") {
33
33
  await validationCommand(invocation);
34
34
  }
35
- else if (invocation.kind === "chats-redact") {
36
- await redactionCommand(invocation.importId);
35
+ else if (invocation.kind === "doctor") {
36
+ if (context.doctorProbe === undefined)
37
+ throw new Error("doctor-probe-unavailable");
38
+ process.exitCode = await doctorCommand({
39
+ probe: context.doctorProbe,
40
+ repository,
41
+ environment,
42
+ json: invocation.json,
43
+ });
37
44
  }
38
- else if (invocation.kind === "chats-import") {
39
- const result = await importChats({
40
- ...invocation,
41
- workingDirectory: process.cwd(),
42
- runtimeDirectory: runtimeDirectory(process.env),
45
+ else if (invocation.kind === "config") {
46
+ process.exitCode = await configCommand(invocation, repository);
47
+ }
48
+ else if (invocation.kind === "phone") {
49
+ process.exitCode = await phoneCommand(invocation, {
50
+ runtimeDirectory: runtimeDirectory(process.env, repository),
51
+ terminal,
43
52
  });
44
- process.stdout.write(`${JSON.stringify(result)}\n`);
45
- process.exitCode = result.code === "import-complete" ? 0 : 1;
46
53
  }
47
54
  else {
48
55
  process.exitCode = await runtimeCommand(invocation, {
49
- runtimeDirectory: runtimeDirectory(process.env),
50
- ...(process.env["CLOVING_WATCH_ACTIONS"] === undefined
51
- ? {}
52
- : { watchActions: process.env["CLOVING_WATCH_ACTIONS"] }),
53
- ...(watchPr === undefined ? {} : { watchPr }),
54
- client: clientCommand(process.env),
56
+ runtimeDirectory: runtimeDirectory(process.env, repository),
57
+ ...watchSettings(context.watchPr, environment),
58
+ client: clientCommand(process.env, repository),
55
59
  workingDirectory: process.cwd(),
56
- terminal: {
57
- out: (text) => process.stdout.write(text),
58
- error: (text) => process.stderr.write(text),
59
- },
60
+ terminal,
60
61
  identifier: randomUUID,
61
62
  interrupted: () => new Promise((settle) => {
62
63
  for (const signal of ["SIGINT", "SIGTERM"])
@@ -67,15 +68,16 @@ export async function main(argumentsList, watchPr) {
67
68
  });
68
69
  }
69
70
  }
70
- function refuseChatPlatform(invocation) {
71
- if (process.platform === "darwin")
72
- return false;
73
- if (invocation.kind !== "chats-import" && invocation.kind !== "chats-redact")
74
- return false;
75
- process.stdout.write(`${JSON.stringify({ code: "platform-unsupported" })}\n`);
76
- process.stderr.write("platform-unsupported: Chat commands require macOS.\n");
77
- process.exitCode = 1;
78
- return true;
71
+ const terminal = {
72
+ out: (text) => process.stdout.write(text),
73
+ error: (text) => process.stderr.write(text),
74
+ };
75
+ function watchSettings(watchPr, environment) {
76
+ const watchActions = environment["CLOVING_WATCH_ACTIONS"];
77
+ return {
78
+ ...(watchActions === undefined ? {} : { watchActions }),
79
+ ...(watchPr === undefined ? {} : { watchPr }),
80
+ };
79
81
  }
80
82
  function presentUsageError(invocation) {
81
83
  if (invocation.json)
@@ -101,27 +103,3 @@ function present(report, format) {
101
103
  for (const error of report.errors)
102
104
  process.stderr.write(`${error.code}: ${error.file}: ${error.detail}\n`);
103
105
  }
104
- async function redactionCommand(importId) {
105
- let privateTexts = [];
106
- try {
107
- const setting = process.env["CLOVING_PRIVATE_TEXTS"];
108
- if (setting !== undefined)
109
- privateTexts = JSON.parse(setting);
110
- if (!Array.isArray(privateTexts) ||
111
- !privateTexts.every((item) => typeof item === "string" && item.trim() !== ""))
112
- throw new Error("invalid-settings");
113
- }
114
- catch {
115
- process.stdout.write(`${JSON.stringify({ code: "invalid-settings", importId, recordCount: 0, counts: emptyCounts(), totalCount: 0 })}\n`);
116
- process.exitCode = 1;
117
- return;
118
- }
119
- const result = await redactImport({
120
- importId,
121
- workingDirectory: process.cwd(),
122
- runtimeDirectory: runtimeDirectory(process.env),
123
- settings: { home: process.env["HOME"] || null, privateTexts },
124
- });
125
- process.stdout.write(`${JSON.stringify(result)}\n`);
126
- process.exitCode = result.code === "redaction-complete" ? 0 : 1;
127
- }
@@ -0,0 +1,14 @@
1
+ export type PhoneCommandName = "status" | "list" | "remove" | "reset";
2
+ export type PhoneInvocation = {
3
+ readonly kind: "phone-help";
4
+ } | {
5
+ readonly kind: "phone";
6
+ readonly command: PhoneCommandName;
7
+ readonly deviceId: string | null;
8
+ readonly json: boolean;
9
+ } | {
10
+ readonly kind: "usage-error";
11
+ readonly code: string;
12
+ readonly json: boolean;
13
+ };
14
+ export declare function phoneInvocation(argumentsList: readonly string[]): PhoneInvocation;
@@ -0,0 +1,37 @@
1
+ const commands = [
2
+ "status",
3
+ "list",
4
+ "remove",
5
+ "reset",
6
+ ];
7
+ function phoneCommandName(name) {
8
+ return commands.find((command) => command === name);
9
+ }
10
+ function unexpected(tokens, command) {
11
+ const allowed = command === "remove" ? 1 : 0;
12
+ const options = tokens.filter((token) => token.startsWith("-"));
13
+ const subjects = tokens.filter((token) => !token.startsWith("-"));
14
+ if (options.some((option) => option !== "--json"))
15
+ return "unexpected-option";
16
+ if (subjects.length > allowed)
17
+ return "unexpected-argument";
18
+ return subjects.length < allowed ? "missing-argument" : undefined;
19
+ }
20
+ export function phoneInvocation(argumentsList) {
21
+ const json = argumentsList.includes("--json");
22
+ if (argumentsList.includes("--help") || argumentsList.includes("-h"))
23
+ return { kind: "phone-help" };
24
+ const [name, ...rest] = argumentsList;
25
+ const command = phoneCommandName(name);
26
+ if (command === undefined)
27
+ return {
28
+ kind: "usage-error",
29
+ code: name === undefined ? "missing-argument" : "unknown-command",
30
+ json,
31
+ };
32
+ const code = unexpected(rest, command);
33
+ if (code !== undefined)
34
+ return { kind: "usage-error", code, json };
35
+ const deviceId = rest.find((token) => !token.startsWith("-")) ?? null;
36
+ return { kind: "phone", command, deviceId, json };
37
+ }
@@ -0,0 +1,2 @@
1
+ import { type Reply, type ServiceRequest } from "../protocol.ts";
2
+ export declare function phoneRequest(runtimeDirectory: string, request: ServiceRequest): Promise<Reply | undefined>;
@@ -0,0 +1,32 @@
1
+ import net from "node:net";
2
+ import { join } from "node:path";
3
+ import { socketAddress } from "../broker/socket-address.js";
4
+ import { parseReplyLine, requestLine, } from "../protocol.js";
5
+ const absent = ["ENOENT", "ECONNREFUSED"];
6
+ export function phoneRequest(runtimeDirectory, request) {
7
+ const address = socketAddress(join(runtimeDirectory, "phone.sock"));
8
+ if (address.kind === "refused")
9
+ return Promise.resolve({
10
+ kind: "error",
11
+ error: { code: address.reason, detail: address.detail },
12
+ });
13
+ return new Promise((settle, reject) => {
14
+ const socket = net.connect(address.path);
15
+ let buffered = "";
16
+ socket.setEncoding("utf8");
17
+ socket.once("connect", () => socket.write(requestLine(request)));
18
+ socket.on("data", (data) => {
19
+ buffered += data;
20
+ });
21
+ socket.once("end", () => {
22
+ const parsed = parseReplyLine(buffered.trim());
23
+ settle(parsed?.kind === "event" ? undefined : parsed);
24
+ });
25
+ socket.once("error", (error) => {
26
+ if (absent.includes(error.code ?? ""))
27
+ settle(undefined);
28
+ else
29
+ reject(error);
30
+ });
31
+ });
32
+ }
@@ -0,0 +1,13 @@
1
+ import type { PhoneInvocation } from "./phone-arguments.ts";
2
+ type Invocation = Extract<PhoneInvocation, {
3
+ readonly kind: "phone";
4
+ }>;
5
+ export interface PhoneContext {
6
+ readonly runtimeDirectory: string | undefined;
7
+ readonly terminal: {
8
+ readonly out: (text: string) => void;
9
+ readonly error: (text: string) => void;
10
+ };
11
+ }
12
+ export declare function phoneCommand(invocation: Invocation, context: PhoneContext): Promise<number>;
13
+ export {};
@@ -0,0 +1,101 @@
1
+ import { record } from "../protocol.js";
2
+ import { phoneRequest } from "./phone-client.js";
3
+ import { oneLine } from "./render.js";
4
+ function counted(count) {
5
+ return count === 1 ? "1 phone" : `${String(count)} phones`;
6
+ }
7
+ function listed(state) {
8
+ const devices = state["devices"];
9
+ if (!Array.isArray(devices))
10
+ return [];
11
+ return devices.flatMap((device) => {
12
+ const fields = record(device);
13
+ return fields === undefined ? [] : [fields];
14
+ });
15
+ }
16
+ function stateText(state) {
17
+ const registration = state["registered"] === true
18
+ ? `Registered as ${oneLine(state["daemonId"])} with ${oneLine(state["origin"])}.`
19
+ : "Not registered.";
20
+ return `${registration} ${counted(listed(state).length)}.\n`;
21
+ }
22
+ function deviceLine(device) {
23
+ const removedAt = device["removedAt"];
24
+ const condition = typeof removedAt === "string" ? `removed ${removedAt}` : device["state"];
25
+ return `${oneLine(device["deviceId"])} ${oneLine(device["name"])} (${oneLine(device["platform"])}) ${oneLine(condition)} paired ${oneLine(device["pairedAt"])}\n`;
26
+ }
27
+ function listText(state) {
28
+ const devices = listed(state);
29
+ return devices.length === 0
30
+ ? "No phones.\n"
31
+ : devices.map(deviceLine).join("");
32
+ }
33
+ function failed(context, reply) {
34
+ if (reply.kind === "result")
35
+ return 0;
36
+ context.terminal.error(`${oneLine(reply.error.code)}: ${oneLine(reply.error.detail)}\n`);
37
+ return 1;
38
+ }
39
+ function warned(context, result) {
40
+ const warning = result["warning"];
41
+ if (typeof warning === "string")
42
+ context.terminal.error(`warning: ${oneLine(warning)}\n`);
43
+ }
44
+ const operations = {
45
+ status: "phone-state",
46
+ list: "phone-state",
47
+ remove: "phone-remove",
48
+ reset: "phone-reset",
49
+ };
50
+ function jsonShown(command, result) {
51
+ if (command === "list")
52
+ return { devices: listed(result) };
53
+ if (command === "status")
54
+ return { relay: "on", ...result };
55
+ return result;
56
+ }
57
+ function shown(exchange, result) {
58
+ const { invocation } = exchange;
59
+ if (invocation.json)
60
+ return `${JSON.stringify(jsonShown(invocation.command, result))}\n`;
61
+ if (invocation.command === "status")
62
+ return stateText(result);
63
+ if (invocation.command === "list")
64
+ return listText(result);
65
+ if (invocation.command === "remove")
66
+ return `Removed the phone ${String(invocation.deviceId)}.\n`;
67
+ return `Removed the registration and ${counted(Number(result["removed"]))}.\n`;
68
+ }
69
+ function relayOff(exchange) {
70
+ const { invocation, context } = exchange;
71
+ if (invocation.command !== "status") {
72
+ context.terminal.error("phone-relay-off: The phone relay is off or not started.\n");
73
+ return 1;
74
+ }
75
+ context.terminal.out(invocation.json
76
+ ? `${JSON.stringify({ relay: "off" })}\n`
77
+ : "The phone relay is off or not started.\n");
78
+ return 0;
79
+ }
80
+ async function exchanged(exchange) {
81
+ const { invocation, context, runtimeDirectory } = exchange;
82
+ const reply = await phoneRequest(runtimeDirectory, {
83
+ operation: operations[invocation.command],
84
+ parameters: invocation.deviceId === null ? {} : { deviceId: invocation.deviceId },
85
+ });
86
+ if (reply === undefined)
87
+ return relayOff(exchange);
88
+ if (reply.kind === "error")
89
+ return failed(context, reply);
90
+ warned(context, reply.result);
91
+ context.terminal.out(shown(exchange, reply.result));
92
+ return 0;
93
+ }
94
+ export async function phoneCommand(invocation, context) {
95
+ const { runtimeDirectory } = context;
96
+ if (runtimeDirectory === undefined) {
97
+ context.terminal.error("repository-unknown: Change to the service repository, use --repository <directory>, or set CLOVING_RUNTIME_DIR.\n");
98
+ return 1;
99
+ }
100
+ return exchanged({ invocation, context, runtimeDirectory });
101
+ }
@@ -0,0 +1,36 @@
1
+ import type { Readable } from "node:stream";
2
+ interface ProbeChild {
3
+ readonly pid?: number | undefined;
4
+ readonly stdout: Readable;
5
+ kill(signal: NodeJS.Signals): boolean;
6
+ once(event: "error", listener: (error: Error) => void): this;
7
+ once(event: "close", listener: (code: number | null) => void): this;
8
+ }
9
+ interface ProbeEffects {
10
+ readonly spawn: (input: {
11
+ readonly executable: string;
12
+ readonly arguments: string[];
13
+ readonly options: {
14
+ readonly env: Readonly<NodeJS.ProcessEnv>;
15
+ readonly cwd?: string;
16
+ readonly stdio: ["ignore", "pipe", "ignore"];
17
+ readonly detached: true;
18
+ };
19
+ }) => ProbeChild;
20
+ readonly kill: (identifier: number, signal: NodeJS.Signals) => boolean;
21
+ }
22
+ export interface ProbeOptions {
23
+ readonly arguments: readonly string[];
24
+ readonly env: Readonly<NodeJS.ProcessEnv>;
25
+ readonly directory?: string;
26
+ readonly milliseconds?: number;
27
+ readonly bytes?: number;
28
+ }
29
+ export type ProbeRunner = (executable: string, options: ProbeOptions) => Promise<ProbeOutput>;
30
+ export interface ProbeOutput {
31
+ readonly exitCode?: number | null;
32
+ readonly stdout: string;
33
+ readonly reason: string | null;
34
+ }
35
+ export declare function createProbeRunner(effects: ProbeEffects): ProbeRunner;
36
+ export {};
@@ -0,0 +1,59 @@
1
+ function killProbe(child, effects) {
2
+ if (child.pid === undefined)
3
+ return;
4
+ try {
5
+ effects.kill(-child.pid, "SIGKILL");
6
+ }
7
+ catch {
8
+ child.kill("SIGKILL");
9
+ }
10
+ }
11
+ export function createProbeRunner(effects) {
12
+ return (executable, options) => executeProbe({ executable, options, effects });
13
+ }
14
+ function executeProbe(input) {
15
+ const { executable, options, effects } = input;
16
+ return new Promise((complete) => {
17
+ const child = effects.spawn({
18
+ executable,
19
+ arguments: [...options.arguments],
20
+ options: {
21
+ env: options.env,
22
+ ...(options.directory === undefined ? {} : { cwd: options.directory }),
23
+ stdio: ["ignore", "pipe", "ignore"],
24
+ detached: true,
25
+ },
26
+ });
27
+ const chunks = [];
28
+ let bytes = 0;
29
+ let reason = null;
30
+ const stop = (failure) => {
31
+ if (reason !== null)
32
+ return;
33
+ reason = failure;
34
+ killProbe(child, effects);
35
+ child.stdout.destroy();
36
+ };
37
+ child.stdout.on("data", (chunk) => {
38
+ bytes += chunk.length;
39
+ if (bytes > (options.bytes ?? 65536))
40
+ stop("probe-output-limit");
41
+ else
42
+ chunks.push(chunk);
43
+ });
44
+ const timer = setTimeout(() => {
45
+ stop("probe-timeout");
46
+ }, options.milliseconds ?? 10000);
47
+ child.once("error", () => {
48
+ reason ??= "probe-start";
49
+ });
50
+ child.once("close", (code) => {
51
+ clearTimeout(timer);
52
+ complete({
53
+ exitCode: code,
54
+ stdout: Buffer.concat(chunks).toString("utf8"),
55
+ reason: reason ?? (code === 0 ? null : "probe-exit"),
56
+ });
57
+ });
58
+ });
59
+ }
@@ -0,0 +1,4 @@
1
+ import { resolveSettings } from "../project-settings.ts";
2
+ export declare function privateSettingsPath(environment: Readonly<NodeJS.ProcessEnv>, repository: string): string;
3
+ export declare function projectSettings(environment: Readonly<NodeJS.ProcessEnv>, repository: string): ReturnType<typeof resolveSettings>;
4
+ export declare function settingsEnvironment(environment: Readonly<NodeJS.ProcessEnv>, repository: string): Readonly<NodeJS.ProcessEnv>;
@@ -0,0 +1,33 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { configurationRoot, resolveSettings } from "../project-settings.js";
5
+ import { repositoryRuntimeName } from "./runtime-directory.js";
6
+ export function privateSettingsPath(environment, repository) {
7
+ return join(configurationRoot(environment, homedir()), "cloving/projects", `${repositoryRuntimeName(repository)}.json`);
8
+ }
9
+ function read(file) {
10
+ try {
11
+ return readFileSync(file.path, "utf8");
12
+ }
13
+ catch (error) {
14
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
15
+ return undefined;
16
+ throw new Error(`unreadable-config-file: ${file.scope}`, { cause: error });
17
+ }
18
+ }
19
+ export function projectSettings(environment, repository) {
20
+ return resolveSettings(environment, {
21
+ project: read({
22
+ path: join(repository, ".cloving/config.json"),
23
+ scope: "project",
24
+ }),
25
+ private: read({
26
+ path: privateSettingsPath(environment, repository),
27
+ scope: "private",
28
+ }),
29
+ });
30
+ }
31
+ export function settingsEnvironment(environment, repository) {
32
+ return projectSettings(environment, repository).environment;
33
+ }
@@ -1,8 +1,9 @@
1
1
  import { type Fields } from "../protocol.ts";
2
+ export declare function oneLine(value: unknown): string;
2
3
  export declare function errorText(error: Fields): string;
3
4
  export declare function runOverview(result: Fields): Fields;
4
5
  export declare function queueLines(value: unknown): readonly string[];
5
- export declare function statusJson(result: Fields): Fields;
6
+ export { statusJson } from "./usage-render.ts";
6
7
  export declare function runStatus(result: Fields): readonly string[];
7
8
  export declare function decisionLines(decision: unknown): readonly string[];
8
9
  export declare function decisionList(result: Fields): readonly string[];
@@ -1,6 +1,7 @@
1
- import { priceText, usageText, totalsSuffix } from "./usage-render.js";
1
+ import { priceText, usageText, totalsSuffix, attemptTexts, } from "./usage-render.js";
2
2
  import { record } from "../protocol.js";
3
3
  import { workflowRefusals } from "../workflow-refusals.js";
4
+ import { commandText, shownCommands } from "./command-effects.js";
4
5
  function show(value) {
5
6
  return typeof value === "string" ? value : JSON.stringify(value);
6
7
  }
@@ -20,6 +21,9 @@ function hidden(character) {
20
21
  const code = character.codePointAt(0) ?? 0;
21
22
  return hiddenRanges.some(([first, last]) => code >= first && code <= last);
22
23
  }
24
+ export function oneLine(value) {
25
+ return Array.from(show(value), (character) => hidden(character) ? escaped(character) : character).join("");
26
+ }
23
27
  function visible(value) {
24
28
  return show(value)
25
29
  .split("\n")
@@ -59,15 +63,26 @@ function admitted(result) {
59
63
  }
60
64
  function runLine(run) {
61
65
  const line = ` ${show(part(run, "runId"))} ${show(part(run, "workflowId"))} ${show(part(run, "condition"))} revision ${show(part(run, "revision"))} latest at ${show(part(run, "latestAt") ?? "none")}`;
62
- return [line, ...chainLines(run).map((link) => ` ${link}`)].join("\n");
66
+ return [
67
+ line,
68
+ ...ciLines(run).map((notice) => ` ${notice}`),
69
+ ...chainLines(run).map((link) => ` ${link}`),
70
+ ].join("\n");
63
71
  }
64
72
  function chainLines(run) {
65
73
  return [
74
+ ...(typeof part(run, "awaitedRunId") === "string"
75
+ ? [`Awaited run: ${visible(part(run, "awaitedRunId"))}`]
76
+ : []),
66
77
  `Parent run: ${visible(part(run, "parentRunId") ?? "none")}`,
67
78
  `Chain: ${visible(part(run, "chainId") ?? part(run, "runId") ?? "none")}`,
68
79
  `Child runs: ${visible(listing(part(run, "childRunIds")))}`,
69
80
  ];
70
81
  }
82
+ function ciLines(run) {
83
+ const reruns = part(run, "ciReruns");
84
+ return (Array.isArray(reruns) ? reruns : []).map((rerun) => `CI rerun after a failed check: workflow ${visible(part(rerun, "run"))}, commit ${visible(part(rerun, "commit"))}`);
85
+ }
71
86
  function ended(run) {
72
87
  return ["completed", "failed", "cancelled"].includes(show(run["state"]));
73
88
  }
@@ -154,38 +169,31 @@ function outcomeLines(value) {
154
169
  : []),
155
170
  ];
156
171
  }
172
+ function labelled(label, value) {
173
+ return typeof value === "string" ? [` ${label}: ${visible(value)}`] : [];
174
+ }
157
175
  function workerLines(value) {
158
176
  return (Array.isArray(value) ? value : []).flatMap((turn) => [
159
177
  `Worker turn ${visible(part(turn, "operationId"))}: ${priceText(part(turn, "costUsd"), part(turn, "estimatedCostUsd"))}`,
178
+ ...labelled("Harness", part(turn, "harness")),
179
+ ...labelled("Model", part(turn, "model")),
160
180
  ` ${usageText(part(turn, "usage"))}`,
181
+ ...attemptTexts(part(turn, "attempts")).map((text) => ` ${oneLine(text)}`),
182
+ ...modelLines(part(turn, "attempts")),
183
+ ...labelled("Report", part(turn, "summary")),
161
184
  ]);
162
185
  }
163
- export function statusJson(result) {
164
- const run = record(result["run"]);
165
- if (result["kind"] !== "run-status" || run === undefined)
166
- return result;
167
- const turns = run["workerTurns"];
168
- return {
169
- ...result,
170
- run: {
171
- ...run,
172
- costDisplay: priceText(run["claudeCostUsd"], run["estimatedCostUsd"]),
173
- ...(Array.isArray(turns)
174
- ? {
175
- workerTurns: turns.map((turn) => {
176
- const fields = record(turn);
177
- if (fields === undefined)
178
- return turn;
179
- return {
180
- ...fields,
181
- costDisplay: priceText(fields["costUsd"], fields["estimatedCostUsd"]),
182
- };
183
- }),
184
- }
185
- : {}),
186
- },
187
- };
188
- }
186
+ function modelLines(attempts) {
187
+ if (!Array.isArray(attempts))
188
+ return [];
189
+ return attempts.flatMap((attempt) => {
190
+ const models = part(attempt, "models");
191
+ if (!Array.isArray(models))
192
+ return [];
193
+ return models.map((model) => ` ${visible(part(model, "model"))}: ${usageText(part(model, "usage"))}`);
194
+ });
195
+ }
196
+ export { statusJson } from "./usage-render.js";
189
197
  function inputText(value) {
190
198
  const text = visible(record(value) ?? null);
191
199
  const characters = Array.from(text);
@@ -204,6 +212,7 @@ export function runStatus(result) {
204
212
  `Title: ${visible(part(run, "title") ?? "none")}`,
205
213
  `State: ${show(part(run, "state"))}`,
206
214
  ...outcomeLines(part(run, "outcome")),
215
+ ...ciLines(run),
207
216
  `Condition: ${show(part(run, "condition"))}`,
208
217
  `Reason: ${show(part(reason, "code"))}: ${show(part(reason, "detail"))}`,
209
218
  `Input: ${inputText(part(run, "input"))}`,
@@ -216,12 +225,19 @@ export function runStatus(result) {
216
225
  `Cost${suffix}: ${priceText(part(run, "claudeCostUsd"), part(run, "estimatedCostUsd"))}`,
217
226
  `Token usage${suffix}: ${usageText(part(run, "usage"))}`,
218
227
  ...workerLines(part(run, "workerTurns")),
228
+ ...shownCommands(part(run, "commandEffects")).map((effect) => visible(commandText(effect))),
219
229
  `Next action: ${show(part(run, "nextAction") ?? "none")}${at === null ? "" : ` at ${show(at)}`}`,
220
230
  `Human input can help: ${part(run, "humanInputCanHelp") === true ? "yes" : "no"}`,
221
231
  ...feedbackLines(part(run, "feedback")),
232
+ ...decidedLines(part(run, "decisions")),
222
233
  ...chainLines(run),
223
234
  ];
224
235
  }
236
+ function decidedLines(value) {
237
+ if (!Array.isArray(value))
238
+ return [];
239
+ return value.map((decision) => `Decision ${visible(part(decision, "decisionId"))}: ${visible(part(decision, "decision"))} by ${visible(part(decision, "actor"))}`);
240
+ }
225
241
  function binding(decision) {
226
242
  return `--expected-revision ${show(part(decision, "revision"))} --generation ${show(part(decision, "generation"))} --subject-digest ${show(part(decision, "subjectDigest"))}`;
227
243
  }
@@ -0,0 +1,18 @@
1
+ import type { ReportDatum } from "../report-statistics.ts";
2
+ import type { WatchPrSettings } from "./watch-pr-settings.ts";
3
+ export interface ReportGithub {
4
+ readonly observedSince: number | null;
5
+ readonly issues: readonly ReportDatum[] | null;
6
+ readonly pulls: readonly ReportDatum[] | null;
7
+ readonly sources: Readonly<Record<"issues" | "pulls" | "history", {
8
+ readonly status: string;
9
+ readonly reason?: string;
10
+ }>>;
11
+ }
12
+ interface GithubReportInput {
13
+ readonly since: string;
14
+ readonly settings?: WatchPrSettings;
15
+ readonly retryMilliseconds?: number;
16
+ }
17
+ export declare function readReportGithub(input: GithubReportInput): Promise<ReportGithub>;
18
+ export {};