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
@@ -0,0 +1,164 @@
1
+ import { spawn } from "node:child_process";
2
+ import { closeSync, mkdtempSync, openSync, rmSync, writeSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { turnEnvironment } from "./claude-turn.js";
5
+ import { commandLimits } from "../command-settings.js";
6
+ import { isInstant } from "../authority/instants.js";
7
+ const commandClock = {
8
+ now: () => Date.now(),
9
+ timer: (wait) => {
10
+ const timer = setTimeout(wait.expired, wait.milliseconds);
11
+ return () => {
12
+ clearTimeout(timer);
13
+ };
14
+ },
15
+ };
16
+ function boundedOutput(stream, options) {
17
+ let received = 0;
18
+ stream.on("data", (chunk) => {
19
+ const kept = chunk.subarray(0, Math.max(0, options.bytes - received));
20
+ received += chunk.length;
21
+ if (kept.length > 0)
22
+ options.receive(kept);
23
+ if (received > options.bytes)
24
+ options.fail("command-output-limit");
25
+ });
26
+ }
27
+ function stopChild(child) {
28
+ try {
29
+ if (child.pid !== undefined)
30
+ process.kill(-child.pid, "SIGKILL");
31
+ }
32
+ catch (error) {
33
+ const code = Reflect.get(Object(error), "code");
34
+ if (code !== "ESRCH" && code !== "EPERM")
35
+ throw error;
36
+ child.kill("SIGKILL");
37
+ }
38
+ child.stdin.destroy();
39
+ child.stdout.destroy();
40
+ child.stderr.destroy();
41
+ }
42
+ function spawnCommand(start, configuration) {
43
+ const [executable = "", ...argumentsList] = start.command;
44
+ return spawn(executable, argumentsList, {
45
+ cwd: start.directory,
46
+ env: {
47
+ ...turnEnvironment(configuration, { ...start, prompt: start.payload }),
48
+ CLOVING_RUN_ID: start.runId,
49
+ CLOVING_OPERATION_ID: start.operationId,
50
+ },
51
+ stdio: ["pipe", "pipe", "pipe"],
52
+ detached: true,
53
+ });
54
+ }
55
+ function writeStderr(descriptor, chunk) {
56
+ try {
57
+ writeSync(descriptor, chunk);
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ function releaseCommand(resources) {
65
+ try {
66
+ if (resources.stderr !== undefined)
67
+ closeSync(resources.stderr);
68
+ }
69
+ finally {
70
+ rmSync(resources.configuration, { recursive: true, force: true });
71
+ }
72
+ }
73
+ function prepareCommand(start, clock) {
74
+ const configuration = mkdtempSync(join(start.folder, "gh-config-"));
75
+ let stderr;
76
+ let child;
77
+ try {
78
+ stderr = openSync(join(start.folder, "command.stderr.log"), "w", 0o600);
79
+ const reason = deadlineRefusal(start, clock);
80
+ if (reason !== undefined)
81
+ return { reason };
82
+ child = spawnCommand(start, configuration);
83
+ return { child, stderr, configuration };
84
+ }
85
+ finally {
86
+ if (child === undefined)
87
+ releaseCommand({ stderr, configuration });
88
+ }
89
+ }
90
+ function refusedCommand(reason) {
91
+ return {
92
+ ended: Promise.resolve({
93
+ stdout: "",
94
+ exitCode: null,
95
+ durationMilliseconds: 0,
96
+ reason,
97
+ }),
98
+ stop: () => undefined,
99
+ };
100
+ }
101
+ function deadlineRefusal(start, clock) {
102
+ if (start.deadline !== undefined && !isInstant(start.deadline))
103
+ return "invalid-command-deadline";
104
+ if (start.deadline !== undefined && Date.parse(start.deadline) <= clock.now())
105
+ return "command-wait-timeout";
106
+ return undefined;
107
+ }
108
+ export function startCommand(start, clock = commandClock) {
109
+ let reason = deadlineRefusal(start, clock);
110
+ if (reason !== undefined)
111
+ return refusedCommand(reason);
112
+ const began = performance.now();
113
+ const prepared = prepareCommand(start, clock);
114
+ if ("reason" in prepared)
115
+ return refusedCommand(prepared.reason);
116
+ const { child, stderr, configuration } = prepared;
117
+ const stdout = [];
118
+ const closed = Promise.withResolvers();
119
+ const fail = (failure = "command-exit") => {
120
+ reason ??= failure;
121
+ stopChild(child);
122
+ closed.resolve(child.exitCode);
123
+ };
124
+ boundedOutput(child.stdout, {
125
+ bytes: commandLimits.stdoutBytes,
126
+ receive: (chunk) => stdout.push(chunk),
127
+ fail,
128
+ });
129
+ boundedOutput(child.stderr, {
130
+ bytes: commandLimits.stderrBytes,
131
+ receive: (chunk) => {
132
+ if (!writeStderr(stderr, chunk))
133
+ fail("command-exit");
134
+ },
135
+ fail,
136
+ });
137
+ const remaining = start.deadline === undefined
138
+ ? Infinity
139
+ : Date.parse(start.deadline) - clock.now();
140
+ const execution = start.seconds * 1000;
141
+ const cancelTimer = clock.timer({
142
+ expired: () => {
143
+ fail(remaining <= execution ? "command-wait-timeout" : "command-timeout");
144
+ },
145
+ milliseconds: Math.min(execution, remaining),
146
+ });
147
+ child.stdin.on("error", () => undefined).end(start.payload);
148
+ child.once("error", () => undefined).once("close", closed.resolve);
149
+ return {
150
+ ended: closed.promise.then((exitCode) => {
151
+ cancelTimer();
152
+ releaseCommand({ stderr, configuration });
153
+ reason ??= deadlineRefusal(start, clock);
154
+ reason ??= exitCode === 0 ? undefined : "command-exit";
155
+ return {
156
+ stdout: Buffer.concat(stdout).toString("utf8"),
157
+ exitCode,
158
+ durationMilliseconds: Math.round(performance.now() - began),
159
+ ...(reason === undefined ? {} : { reason }),
160
+ };
161
+ }),
162
+ stop: fail,
163
+ };
164
+ }
@@ -0,0 +1,19 @@
1
+ import type { LocalCommands } from "../command-settings.ts";
2
+ import type { Delivery, DeliveryIntent } from "../broker/actor/delivery-intents.ts";
3
+ import { type WorkerReport } from "./operation-journal.ts";
4
+ import { type CommandClock } from "./command-process.ts";
5
+ export interface CommandWorkerSettings {
6
+ readonly repository: string;
7
+ readonly journal: string;
8
+ readonly commands: LocalCommands;
9
+ readonly seconds?: number;
10
+ readonly commandClock?: CommandClock;
11
+ readonly document: (digest: string) => Promise<string | undefined>;
12
+ readonly report: (report: WorkerReport) => Promise<unknown>;
13
+ }
14
+ export interface CommandWorker extends Delivery {
15
+ readonly recover: (intents: readonly DeliveryIntent[]) => Promise<void>;
16
+ readonly stop: NonNullable<Delivery["stop"]>;
17
+ readonly close: () => Promise<void>;
18
+ }
19
+ export declare function commandWorker(settings: CommandWorkerSettings): CommandWorker;
@@ -0,0 +1,182 @@
1
+ import { located, readRecord, writeRecord, replied, reportOf, } from "./operation-journal.js";
2
+ import { startCommand, } from "./command-process.js";
3
+ import { claimCommand, commandStarted, recordCommandResult, } from "./command-journal.js";
4
+ function commandIntent(intent) {
5
+ return (intent.capability === "command" &&
6
+ /^run:[A-Za-z0-9-]{1,64}$/.test(intent.method ?? "") &&
7
+ intent.payload !== undefined &&
8
+ intent.target !== undefined &&
9
+ intent.leaseGeneration !== undefined);
10
+ }
11
+ async function reconciled(parts, call) {
12
+ const { intent, origin } = call;
13
+ const { key, folder } = located(parts.settings.journal, intent.operationId);
14
+ const result = await readRecord(folder, "result.json");
15
+ if (result !== undefined)
16
+ return replied({ receipt: key, worker: "command" }, result);
17
+ const inFlight = () => parts.active.has(key) || (origin !== "dispatch" && parts.pending.has(key));
18
+ if (inFlight())
19
+ return { kind: "accepted", receipt: key, worker: "command" };
20
+ if (!(await commandStarted(folder)))
21
+ return { kind: "absent" };
22
+ const started = await readRecord(folder, "started.json");
23
+ if (inFlight())
24
+ return { kind: "accepted", receipt: key, worker: "command" };
25
+ const duration = Date.now() - Date.parse(String(Reflect.get(Object(started), "startedAt")));
26
+ await recordCommandResult(folder, {
27
+ outcome: "failed",
28
+ reason: "command-interrupted",
29
+ exitCode: null,
30
+ durationMilliseconds: Number.isFinite(duration) ? Math.max(0, duration) : 0,
31
+ endedAt: new Date().toISOString(),
32
+ });
33
+ return replied({ receipt: key, worker: "command" }, await readRecord(folder, "result.json"));
34
+ }
35
+ function ending(end, stopping) {
36
+ const endedAt = new Date().toISOString();
37
+ if (stopping.requested)
38
+ return { outcome: "stopped", endedAt };
39
+ if (end.reason !== undefined)
40
+ return { outcome: "failed", reason: end.reason, endedAt };
41
+ return { outcome: "completed", result: end.stdout, endedAt };
42
+ }
43
+ function begun(parts, start) {
44
+ const { settings } = parts;
45
+ const { intent, key, folder, payload, command } = start;
46
+ const running = startCommand({
47
+ command,
48
+ directory: settings.repository,
49
+ folder,
50
+ payload,
51
+ runId: intent.runId,
52
+ operationId: intent.operationId,
53
+ seconds: settings.seconds ?? 60,
54
+ ...(intent.commandDeadline === undefined
55
+ ? {}
56
+ : { deadline: intent.commandDeadline }),
57
+ }, settings.commandClock);
58
+ const stopping = { requested: false };
59
+ const concluded = running.ended
60
+ .then(async (end) => {
61
+ const recorded = {
62
+ ...ending(end, stopping),
63
+ exitCode: end.exitCode,
64
+ durationMilliseconds: end.durationMilliseconds,
65
+ };
66
+ if (!(await recordCommandResult(folder, recorded)))
67
+ return;
68
+ await settings.report(reportOf({ intent, commandId: `command:${key}`, worker: "command" }, recorded));
69
+ })
70
+ .catch(() => undefined)
71
+ .finally(() => parts.active.delete(key));
72
+ parts.active.set(key, { command: running, concluded, stopping });
73
+ }
74
+ async function delivered(parts, call) {
75
+ const { intent, signal } = call;
76
+ const aborted = () => signal.aborted;
77
+ if (!commandIntent(intent))
78
+ return { kind: "failed", reason: "unsupported-effect" };
79
+ if (aborted())
80
+ return { kind: "failed", reason: "command-start-aborted" };
81
+ const known = await reconciled(parts, { intent, origin: "dispatch" });
82
+ if (known.kind !== "absent")
83
+ return known;
84
+ const { settings } = parts;
85
+ const name = intent.method.slice(4);
86
+ const command = Object.hasOwn(settings.commands, name)
87
+ ? settings.commands[name]
88
+ : undefined;
89
+ if (command === undefined)
90
+ return { kind: "failed", reason: "command-unknown" };
91
+ const payload = await settings.document(intent.payload);
92
+ if (payload === undefined)
93
+ return { kind: "failed", reason: "payload-not-available" };
94
+ if (aborted())
95
+ return { kind: "failed", reason: "command-start-aborted" };
96
+ const place = located(settings.journal, intent.operationId);
97
+ if (!(await claimCommand(place.folder)))
98
+ return reconciled(parts, { intent, origin: "dispatch" });
99
+ await writeRecord(place.folder, {
100
+ name: "started.json",
101
+ value: {
102
+ runId: intent.runId,
103
+ operationId: intent.operationId,
104
+ name,
105
+ startedAt: new Date().toISOString(),
106
+ deadline: intent.commandDeadline,
107
+ },
108
+ });
109
+ if (aborted())
110
+ return reconciled(parts, { intent, origin: "dispatch" });
111
+ begun(parts, { ...place, intent, payload, command });
112
+ return { receipt: place.key, worker: "command" };
113
+ }
114
+ async function recovered(parts, intents) {
115
+ for (const intent of intents) {
116
+ if (!commandIntent(intent))
117
+ continue;
118
+ await parts.pending.get(located(parts.settings.journal, intent.operationId).key)?.opening;
119
+ const result = await reconciled(parts, { intent });
120
+ if (result.kind === "completed" ||
121
+ result.kind === "failed" ||
122
+ result.kind === "stopped")
123
+ await parts.settings.report(reportOf({
124
+ intent,
125
+ commandId: `command:${located(parts.settings.journal, intent.operationId).key}`,
126
+ worker: "command",
127
+ }, {
128
+ ...result,
129
+ outcome: result.kind,
130
+ endedAt: new Date().toISOString(),
131
+ }));
132
+ }
133
+ }
134
+ export function commandWorker(settings) {
135
+ const parts = { settings, active: new Map(), pending: new Map() };
136
+ const closing = new AbortController();
137
+ const { pending } = parts;
138
+ return {
139
+ recover: (intents) => recovered(parts, intents),
140
+ deliver: (intent, signal) => {
141
+ const { key } = located(settings.journal, intent.operationId);
142
+ const known = pending.get(key);
143
+ if (known !== undefined)
144
+ return known.opening;
145
+ const stopping = new AbortController();
146
+ const opening = delivered(parts, {
147
+ intent,
148
+ signal: AbortSignal.any([signal, closing.signal, stopping.signal]),
149
+ }).finally(() => pending.delete(key));
150
+ pending.set(key, { opening, stopping });
151
+ return opening;
152
+ },
153
+ reconcile: (intent) => {
154
+ const { key } = located(settings.journal, intent.operationId);
155
+ return pending.has(key)
156
+ ? Promise.resolve({ kind: "accepted", receipt: key, worker: "command" })
157
+ : reconciled(parts, { intent });
158
+ },
159
+ stop: async (intent) => {
160
+ const { key } = located(settings.journal, intent.operationId);
161
+ const opening = pending.get(key);
162
+ opening?.stopping.abort();
163
+ await opening?.opening;
164
+ const active = parts.active.get(key);
165
+ if (active !== undefined)
166
+ active.stopping.requested = true;
167
+ active?.command.stop();
168
+ await active?.concluded;
169
+ return reconciled(parts, { intent });
170
+ },
171
+ close: async () => {
172
+ closing.abort();
173
+ await Promise.all([...pending.values()].map((entry) => entry.opening));
174
+ const active = [...parts.active.values()];
175
+ for (const running of active) {
176
+ running.stopping.requested = true;
177
+ running.command.stop();
178
+ }
179
+ await Promise.all(active.map((running) => running.concluded));
180
+ },
181
+ };
182
+ }
@@ -0,0 +1,4 @@
1
+ export declare function cursorStream(): {
2
+ readonly line: (line: string) => readonly string[];
3
+ readonly result: (exitCode: number | null) => string;
4
+ };
@@ -0,0 +1,154 @@
1
+ import { record } from "../protocol.js";
2
+ import { tokenCount, usageOf } from "../worker-usage.js";
3
+ function text(value) {
4
+ return typeof value === "string" ? value : null;
5
+ }
6
+ function cursorUsage(value) {
7
+ const fields = record(value);
8
+ const counts = {
9
+ input_tokens: tokenCount(fields?.["inputTokens"]),
10
+ cache_read_input_tokens: tokenCount(fields?.["cacheReadTokens"]),
11
+ cache_creation_input_tokens: tokenCount(fields?.["cacheWriteTokens"]),
12
+ output_tokens: tokenCount(fields?.["outputTokens"]),
13
+ };
14
+ return Object.values(counts).includes(null) ? usageOf(null) : counts;
15
+ }
16
+ function received(event, state) {
17
+ const type = event["type"];
18
+ if (type === "system" || type === "result") {
19
+ state.model = text(event["model"]) ?? state.model;
20
+ state.sessionId = text(event["session_id"]) ?? state.sessionId;
21
+ }
22
+ if (type === "assistant")
23
+ state.report = assistantText(event) ?? state.report;
24
+ if (type === "error")
25
+ state.error = text(event["message"]) ?? "cursor-agent stream error";
26
+ if (type === "result")
27
+ state.terminal = event;
28
+ }
29
+ function assistantText(event) {
30
+ const content = record(event["message"])?.["content"];
31
+ if (!Array.isArray(content))
32
+ return null;
33
+ const blocks = content
34
+ .map((block) => record(block))
35
+ .filter((block) => block?.["type"] === "text");
36
+ if (blocks.length === 0)
37
+ return null;
38
+ return blocks.map((block) => text(block?.["text"]) ?? "").join("");
39
+ }
40
+ function functionToolCall(fields) {
41
+ const name = text(fields["name"]);
42
+ if (!name)
43
+ return undefined;
44
+ try {
45
+ const input = record(JSON.parse(String(fields["arguments"])));
46
+ return input === undefined ? undefined : { name, input };
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ }
52
+ function nativeToolCall(key, fields) {
53
+ if (!key.endsWith("ToolCall"))
54
+ return undefined;
55
+ const args = record(fields["args"]);
56
+ if (args === undefined)
57
+ return undefined;
58
+ return {
59
+ name: key === "shellToolCall"
60
+ ? "Bash"
61
+ : key.slice(0, 1).toUpperCase() + key.slice(1, -8),
62
+ input: { ...args, file_path: args["path"] },
63
+ };
64
+ }
65
+ function toolCall(key, value) {
66
+ const fields = record(value);
67
+ if (fields === undefined)
68
+ return undefined;
69
+ return key === "function"
70
+ ? functionToolCall(fields)
71
+ : nativeToolCall(key, fields);
72
+ }
73
+ function toolActivity(event, state) {
74
+ if (!["started", "completed"].includes(String(event["subtype"])))
75
+ return [];
76
+ const callId = text(event["call_id"]);
77
+ if (callId !== null && state.toolCalls.has(callId))
78
+ return [];
79
+ const tools = record(event["tool_call"]) ?? {};
80
+ const messages = Object.entries(tools).flatMap(([key, value]) => {
81
+ const tool = toolCall(key, value);
82
+ if (tool === undefined)
83
+ return [];
84
+ return [
85
+ JSON.stringify({
86
+ type: "assistant",
87
+ message: {
88
+ content: [
89
+ {
90
+ type: "tool_use",
91
+ id: callId,
92
+ ...tool,
93
+ },
94
+ ],
95
+ },
96
+ }),
97
+ ];
98
+ });
99
+ if (callId !== null && messages.length > 0)
100
+ state.toolCalls.add(callId);
101
+ return messages;
102
+ }
103
+ function failure(state, exitCode) {
104
+ if (state.error !== null)
105
+ return state.error;
106
+ if (exitCode !== 0)
107
+ return `cursor-agent ended with the code ${String(exitCode)}`;
108
+ const terminal = state.terminal;
109
+ if (terminal === undefined)
110
+ return "cursor-agent stream ended before its result";
111
+ if (terminal["subtype"] === "success" && terminal["is_error"] === false)
112
+ return null;
113
+ return text(terminal["result"]) ?? "cursor-agent result did not succeed";
114
+ }
115
+ function result(state, exitCode) {
116
+ const error = failure(state, exitCode);
117
+ const success = error === null;
118
+ return JSON.stringify({
119
+ type: "result",
120
+ subtype: success ? "success" : "error_during_execution",
121
+ is_error: !success,
122
+ result: error ?? state.report,
123
+ model: state.model,
124
+ session_id: state.sessionId,
125
+ usage: cursorUsage(state.terminal?.["usage"]),
126
+ });
127
+ }
128
+ export function cursorStream() {
129
+ const state = {
130
+ model: null,
131
+ sessionId: null,
132
+ report: "",
133
+ error: null,
134
+ terminal: undefined,
135
+ toolCalls: new Set(),
136
+ };
137
+ return {
138
+ line: (line) => {
139
+ let value;
140
+ try {
141
+ value = JSON.parse(line);
142
+ }
143
+ catch {
144
+ return [];
145
+ }
146
+ const event = record(value) ?? {};
147
+ received(event, state);
148
+ if (event["type"] === "tool_call")
149
+ return toolActivity(event, state);
150
+ return event["type"] === "result" ? [] : [line];
151
+ },
152
+ result: (exitCode) => result(state, exitCode),
153
+ };
154
+ }
@@ -0,0 +1,58 @@
1
+ import { type StartDelivery, type WorkflowFunction } from "../host/start-delivery.ts";
2
+ import type { WorkflowHandler } from "../host/world-host.ts";
3
+ import type { HostPorts } from "../service/service.ts";
4
+ import { workflowGenerations, type WorkflowBundleLoader } from "./workflow-generations.ts";
5
+ import { type ClaudeWorker } from "./claude-worker.ts";
6
+ import { type GithubWorker } from "./github-worker.ts";
7
+ import { type CommandWorker } from "./command-worker.ts";
8
+ import type { EffectDelivery } from "./delivery-router.ts";
9
+ import type { TurnProfiles } from "../turn-profile.ts";
10
+ import type { TokenPrices } from "../token-prices.ts";
11
+ import type { LocalCommands } from "../command-settings.ts";
12
+ import type { DeclaredWorkflow } from "../workflow-declaration.ts";
13
+ import type { WorkflowRefusal } from "../workflow-refusals.ts";
14
+ import type { HarnessSettings } from "../harness-defaults.ts";
15
+ export interface DaemonSettings extends HarnessSettings {
16
+ readonly commands?: LocalCommands;
17
+ readonly commandSeconds?: number;
18
+ readonly fallbackModels?: readonly string[];
19
+ readonly tokenPrices?: TokenPrices;
20
+ readonly profiles?: TurnProfiles;
21
+ readonly directory: string;
22
+ readonly runtimeDirectory: string;
23
+ readonly repository: string;
24
+ readonly bundleDigest?: string;
25
+ readonly manifests: Readonly<Record<string, string | undefined>>;
26
+ readonly declarations?: readonly DeclaredWorkflow[];
27
+ readonly workflowRefusals?: readonly WorkflowRefusal[];
28
+ readonly workflows: Readonly<Record<string, WorkflowFunction | undefined>>;
29
+ readonly handler: WorkflowHandler;
30
+ readonly loadBundle?: WorkflowBundleLoader;
31
+ readonly command: readonly string[];
32
+ readonly ticketCommand?: readonly string[];
33
+ readonly nextCommand?: readonly string[];
34
+ readonly notifyCommand?: readonly string[];
35
+ readonly notifyMilliseconds?: number;
36
+ readonly queueMilliseconds?: number;
37
+ readonly scheduleClock?: () => number;
38
+ readonly schedules?: unknown;
39
+ readonly queueLanes?: number;
40
+ readonly resetQueue?: boolean;
41
+ readonly githubCommand?: readonly string[];
42
+ readonly requiredChecks?: readonly string[] | null;
43
+ readonly checkCommand?: readonly string[];
44
+ readonly privateTexts?: readonly string[];
45
+ readonly concurrency: number;
46
+ }
47
+ export interface Adapters {
48
+ readonly worker: ClaudeWorker;
49
+ readonly github: GithubWorker;
50
+ readonly runs: StartDelivery;
51
+ readonly handoff: EffectDelivery;
52
+ readonly commands: CommandWorker;
53
+ }
54
+ export declare function adapters(settings: DaemonSettings, options: {
55
+ readonly given: Promise<HostPorts>;
56
+ readonly generations: ReturnType<typeof workflowGenerations>;
57
+ }): Adapters;
58
+ export declare function recoverCommands(commands: CommandWorker, ports: HostPorts): Promise<void>;
@@ -0,0 +1,102 @@
1
+ import { join } from "node:path";
2
+ import { startDelivery, } from "../host/start-delivery.js";
3
+ import { cancelled, taggedRuns } from "../host/world-runs.js";
4
+ import { workflowGenerations, } from "./workflow-generations.js";
5
+ import { claudeWorker } from "./claude-worker.js";
6
+ import { githubWorker } from "./github-worker.js";
7
+ import { commandWorker } from "./command-worker.js";
8
+ import { handoffWorker } from "./handoff-worker.js";
9
+ function githubOf(settings, given) {
10
+ const { directory, repository, checkCommand } = settings;
11
+ return githubWorker({
12
+ document: async (digest) => (await given).document(digest),
13
+ report: async (effect) => (await given).reportEffect(effect),
14
+ operationStatus: async (operationId) => (await (await given).operation(operationId))?.status,
15
+ runStatus: async (runId) => (await (await given).state()).runs[runId]?.status,
16
+ repository,
17
+ gh: settings.githubCommand ?? ["gh"],
18
+ ...(settings.requiredChecks === undefined
19
+ ? {}
20
+ : { requiredChecks: settings.requiredChecks }),
21
+ worktrees: join(directory, "worktrees"),
22
+ journal: join(directory, "github"),
23
+ ...(settings.privateTexts === undefined
24
+ ? {}
25
+ : { privateTexts: settings.privateTexts }),
26
+ ...(checkCommand === undefined ? {} : { check: checkCommand }),
27
+ });
28
+ }
29
+ function workerHarness(settings) {
30
+ return {
31
+ worker: settings.worker ?? settings.harness?.name ?? "claude",
32
+ workerCommands: settings.workerCommands ?? {},
33
+ harness: settings.harness ?? {},
34
+ shell: settings.shell ?? process.env["SHELL"] ?? "/bin/sh",
35
+ command: settings.command,
36
+ };
37
+ }
38
+ export function adapters(settings, options) {
39
+ const { directory, repository } = settings;
40
+ const { given, generations } = options;
41
+ const document = async (digest) => (await given).document(digest);
42
+ const report = async (effect) => (await given).reportEffect(effect);
43
+ const worker = claudeWorker({
44
+ fallbackModels: settings.fallbackModels ?? [],
45
+ tokenPrices: settings.tokenPrices ?? {},
46
+ ...workerHarness(settings),
47
+ profiles: settings.profiles ?? {},
48
+ workflowId: async (runId) => (await given).workflow.id(runId),
49
+ repository,
50
+ document,
51
+ report,
52
+ worktrees: join(directory, "worktrees"),
53
+ journal: join(directory, "journal"),
54
+ });
55
+ const github = githubOf(settings, given);
56
+ const runs = startDelivery({
57
+ document,
58
+ runs: taggedRuns,
59
+ cancel: cancelled,
60
+ input: async (runId) => (await given).input(runId),
61
+ workflow: async ({ runId }) => (await generations.resolve(await (await given).workflow.manifest(runId)))
62
+ ?.workflow,
63
+ });
64
+ const handoff = handoffOf(settings, given);
65
+ const commands = commandWorker({
66
+ repository,
67
+ journal: join(directory, "commands"),
68
+ commands: settings.commands ?? {},
69
+ seconds: settings.commandSeconds ?? 60,
70
+ document,
71
+ report,
72
+ });
73
+ return { worker, github, runs, handoff, commands };
74
+ }
75
+ function handoffOf(settings, given) {
76
+ return handoffWorker({
77
+ runtimeDirectory: settings.runtimeDirectory,
78
+ journal: join(settings.directory, "handoffs"),
79
+ document: async (digest) => (await given).document(digest),
80
+ runStatus: async (runId) => (await (await given).state()).runs[runId]?.status,
81
+ });
82
+ }
83
+ export async function recoverCommands(commands, ports) {
84
+ const state = await ports.state();
85
+ const calls = [];
86
+ for (const run of Object.values(state.runs)) {
87
+ for (const operation of await ports.operations(run.runId)) {
88
+ if (operation.capability !== "command" ||
89
+ operation.leaseGeneration === null ||
90
+ !["running", "recovering", "dispatch-pending"].includes(operation.status))
91
+ continue;
92
+ calls.push({
93
+ ...operation,
94
+ kind: "protected-effect",
95
+ purpose: "reconcile",
96
+ workflow: run.workflow,
97
+ leaseGeneration: operation.leaseGeneration,
98
+ });
99
+ }
100
+ }
101
+ await commands.recover(calls);
102
+ }