cloving 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/README.md +584 -144
  2. package/assets/watch-fonts/fira-code-OFL.md +93 -0
  3. package/assets/watch-fonts/fira-code-latin-400-normal.woff2 +0 -0
  4. package/assets/watch-fonts/fira-code-latin-500-normal.woff2 +0 -0
  5. package/assets/watch-fonts/heebo-OFL.md +93 -0
  6. package/assets/watch-fonts/heebo-latin-500-normal.woff2 +0 -0
  7. package/assets/watch-fonts/heebo-latin-700-normal.woff2 +0 -0
  8. package/assets/watch-fonts/heebo-latin-800-normal.woff2 +0 -0
  9. package/assets/watch-fonts/manifest.json +112 -0
  10. package/assets/watch-fonts/space-grotesk-OFL.md +93 -0
  11. package/assets/watch-fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  12. package/assets/watch-fonts/space-grotesk-latin-500-normal.woff2 +0 -0
  13. package/assets/watch-fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  14. package/assets/watch-fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  15. package/dist/src/agent-harness-shell.d.ts +12 -0
  16. package/dist/src/agent-harness-shell.js +90 -0
  17. package/dist/src/agent-harness-versions.d.ts +8 -0
  18. package/dist/src/agent-harness-versions.js +49 -0
  19. package/dist/src/agent-harnesses.d.ts +4 -0
  20. package/dist/src/agent-harnesses.js +13 -0
  21. package/dist/src/authority/commands.d.ts +2 -0
  22. package/dist/src/authority/commands.js +49 -8
  23. package/dist/src/authority/dispatch-decision.d.ts +1 -0
  24. package/dist/src/authority/dispatch-decision.js +7 -4
  25. package/dist/src/authority/events.js +2 -2
  26. package/dist/src/authority/gate-reduction.d.ts +1 -0
  27. package/dist/src/authority/gate-reduction.js +18 -3
  28. package/dist/src/authority/gates.d.ts +2 -1
  29. package/dist/src/authority/gates.js +5 -1
  30. package/dist/src/authority/handoff-chain.d.ts +24 -0
  31. package/dist/src/authority/handoff-chain.js +46 -0
  32. package/dist/src/authority/operations.js +1 -1
  33. package/dist/src/authority/reconciliation.d.ts +1 -0
  34. package/dist/src/authority/reconciliation.js +18 -11
  35. package/dist/src/authority/reduction.d.ts +1 -1
  36. package/dist/src/authority/reduction.js +6 -1
  37. package/dist/src/authority/status-input.d.ts +1 -1
  38. package/dist/src/authority/status.d.ts +1 -0
  39. package/dist/src/authority/status.js +27 -3
  40. package/dist/src/authority/transitions.d.ts +5 -5
  41. package/dist/src/authority/transitions.js +9 -0
  42. package/dist/src/broker/actor/authority-delivery.js +1 -0
  43. package/dist/src/broker/actor/authority-queries.d.ts +11 -1
  44. package/dist/src/broker/actor/authority-queries.js +67 -3
  45. package/dist/src/broker/actor/authority-receipts.js +11 -1
  46. package/dist/src/broker/actor/authority-session.js +2 -2
  47. package/dist/src/broker/actor/authority-settings.js +4 -0
  48. package/dist/src/broker/actor/delivery-intents.d.ts +3 -1
  49. package/dist/src/broker/actor/delivery-intents.js +4 -4
  50. package/dist/src/broker/actor/effect-delivery.js +13 -1
  51. package/dist/src/broker/actor/effect-queries.d.ts +1 -0
  52. package/dist/src/broker/actor/effect-queries.js +7 -0
  53. package/dist/src/broker/actor/pin-check.js +1 -1
  54. package/dist/src/broker/actor/stop-plan.js +1 -1
  55. package/dist/src/broker/actor/turn-state.js +1 -1
  56. package/dist/src/broker/authority-admission.js +26 -5
  57. package/dist/src/broker/authority-restore.js +1 -0
  58. package/dist/src/broker/decision-restore.js +4 -4
  59. package/dist/src/broker/socket-address.d.ts +3 -1
  60. package/dist/src/broker/socket-address.js +2 -2
  61. package/dist/src/cli/arguments.d.ts +11 -13
  62. package/dist/src/cli/arguments.js +37 -107
  63. package/dist/src/cli/command-effects.d.ts +7 -0
  64. package/dist/src/cli/command-effects.js +39 -0
  65. package/dist/src/cli/commands.js +11 -4
  66. package/dist/src/cli/config-arguments.d.ts +11 -0
  67. package/dist/src/cli/config-arguments.js +59 -0
  68. package/dist/src/cli/config-command.d.ts +2 -0
  69. package/dist/src/cli/config-command.js +105 -0
  70. package/dist/src/cli/config-file.d.ts +3 -0
  71. package/dist/src/cli/config-file.js +50 -0
  72. package/dist/src/cli/config-lock.d.ts +7 -0
  73. package/dist/src/cli/config-lock.js +61 -0
  74. package/dist/src/cli/config-notice.d.ts +5 -0
  75. package/dist/src/cli/config-notice.js +46 -0
  76. package/dist/src/cli/doctor-github.d.ts +9 -0
  77. package/dist/src/cli/doctor-github.js +138 -0
  78. package/dist/src/cli/doctor-harness.d.ts +13 -0
  79. package/dist/src/cli/doctor-harness.js +242 -0
  80. package/dist/src/cli/doctor-local.d.ts +18 -0
  81. package/dist/src/cli/doctor-local.js +77 -0
  82. package/dist/src/cli/doctor-runtime.d.ts +15 -0
  83. package/dist/src/cli/doctor-runtime.js +176 -0
  84. package/dist/src/cli/doctor-service.d.ts +1 -0
  85. package/dist/src/cli/doctor-service.js +11 -0
  86. package/dist/src/cli/doctor-workflows.d.ts +3 -0
  87. package/dist/src/cli/doctor-workflows.js +45 -0
  88. package/dist/src/cli/doctor.d.ts +15 -0
  89. package/dist/src/cli/doctor.js +190 -0
  90. package/dist/src/cli/github-ci-progress.d.ts +8 -0
  91. package/dist/src/cli/github-ci-progress.js +83 -0
  92. package/dist/src/cli/github-retry.d.ts +6 -0
  93. package/dist/src/cli/github-retry.js +47 -0
  94. package/dist/src/cli/harness-probes.d.ts +22 -0
  95. package/dist/src/cli/harness-probes.js +183 -0
  96. package/dist/src/cli/main.d.ts +7 -1
  97. package/dist/src/cli/main.js +39 -61
  98. package/dist/src/cli/phone-arguments.d.ts +14 -0
  99. package/dist/src/cli/phone-arguments.js +37 -0
  100. package/dist/src/cli/phone-client.d.ts +2 -0
  101. package/dist/src/cli/phone-client.js +32 -0
  102. package/dist/src/cli/phone-command.d.ts +13 -0
  103. package/dist/src/cli/phone-command.js +101 -0
  104. package/dist/src/cli/probe-command.d.ts +36 -0
  105. package/dist/src/cli/probe-command.js +59 -0
  106. package/dist/src/cli/project-settings.d.ts +4 -0
  107. package/dist/src/cli/project-settings.js +33 -0
  108. package/dist/src/cli/render.d.ts +3 -1
  109. package/dist/src/cli/render.js +102 -39
  110. package/dist/src/cli/report-github.d.ts +18 -0
  111. package/dist/src/cli/report-github.js +200 -0
  112. package/dist/src/cli/report.d.ts +17 -0
  113. package/dist/src/cli/report.js +192 -0
  114. package/dist/src/cli/repository-arguments.d.ts +5 -0
  115. package/dist/src/cli/repository-arguments.js +34 -0
  116. package/dist/src/cli/runtime-arguments.d.ts +4 -0
  117. package/dist/src/cli/runtime-arguments.js +15 -0
  118. package/dist/src/cli/runtime-directory.d.ts +6 -2
  119. package/dist/src/cli/runtime-directory.js +72 -14
  120. package/dist/src/cli/toolchain.d.ts +2 -0
  121. package/dist/src/cli/toolchain.js +22 -2
  122. package/dist/src/cli/usage-render.d.ts +5 -0
  123. package/dist/src/cli/usage-render.js +40 -1
  124. package/dist/src/cli/usage.d.ts +3 -3
  125. package/dist/src/cli/usage.js +74 -45
  126. package/dist/src/cli/watch-actions.d.ts +2 -0
  127. package/dist/src/cli/watch-actions.js +4 -4
  128. package/dist/src/cli/watch-board-view.d.ts +12 -1
  129. package/dist/src/cli/watch-board-view.js +64 -12
  130. package/dist/src/cli/watch-board.d.ts +7 -1
  131. package/dist/src/cli/watch-board.js +61 -16
  132. package/dist/src/cli/watch-card-forms.js +2 -2
  133. package/dist/src/cli/watch-client.d.ts +1 -1
  134. package/dist/src/cli/watch-client.js +12 -3
  135. package/dist/src/cli/watch-header-view.d.ts +27 -0
  136. package/dist/src/cli/watch-header-view.js +116 -0
  137. package/dist/src/cli/watch-model.d.ts +10 -4
  138. package/dist/src/cli/watch-model.js +49 -59
  139. package/dist/src/cli/watch-page.js +67 -14
  140. package/dist/src/cli/watch-phases.js +3 -3
  141. package/dist/src/cli/watch-phone-client.d.ts +1 -0
  142. package/dist/src/cli/watch-phone-client.js +84 -0
  143. package/dist/src/cli/watch-phone-view.d.ts +56 -0
  144. package/dist/src/cli/watch-phone-view.js +113 -0
  145. package/dist/src/cli/watch-phone.d.ts +5 -0
  146. package/dist/src/cli/watch-phone.js +53 -0
  147. package/dist/src/cli/watch-pr-command.d.ts +5 -2
  148. package/dist/src/cli/watch-pr-command.js +41 -4
  149. package/dist/src/cli/watch-pr-identity.d.ts +14 -2
  150. package/dist/src/cli/watch-pr-identity.js +25 -0
  151. package/dist/src/cli/watch-pr-observer.d.ts +1 -0
  152. package/dist/src/cli/watch-pr-observer.js +48 -6
  153. package/dist/src/cli/watch-pull-request.d.ts +12 -0
  154. package/dist/src/cli/watch-pull-request.js +134 -0
  155. package/dist/src/cli/watch-reads.d.ts +7 -1
  156. package/dist/src/cli/watch-reads.js +42 -20
  157. package/dist/src/cli/watch-render.d.ts +23 -2
  158. package/dist/src/cli/watch-render.js +2 -1
  159. package/dist/src/cli/watch-server.js +56 -7
  160. package/dist/src/cli/watch-turn.d.ts +4 -1
  161. package/dist/src/cli/watch-turn.js +38 -2
  162. package/dist/src/cli/watch-usage.js +5 -1
  163. package/dist/src/cli/watch-view.d.ts +10 -17
  164. package/dist/src/cli/watch-view.js +33 -77
  165. package/dist/src/cli.js +106 -23
  166. package/dist/src/command-settings.d.ts +16 -0
  167. package/dist/src/command-settings.js +42 -0
  168. package/dist/src/configuration-change.d.ts +11 -0
  169. package/dist/src/configuration-change.js +62 -0
  170. package/dist/src/configuration-display.d.ts +21 -0
  171. package/dist/src/configuration-display.js +69 -0
  172. package/dist/src/configuration-schema.d.ts +49 -0
  173. package/dist/src/configuration-schema.js +159 -0
  174. package/dist/src/daemon/claude-turn.d.ts +20 -5
  175. package/dist/src/daemon/claude-turn.js +116 -53
  176. package/dist/src/daemon/claude-worker.d.ts +3 -5
  177. package/dist/src/daemon/claude-worker.js +64 -80
  178. package/dist/src/daemon/command-journal.d.ts +5 -0
  179. package/dist/src/daemon/command-journal.js +50 -0
  180. package/dist/src/daemon/command-process.d.ts +28 -0
  181. package/dist/src/daemon/command-process.js +164 -0
  182. package/dist/src/daemon/command-worker.d.ts +19 -0
  183. package/dist/src/daemon/command-worker.js +182 -0
  184. package/dist/src/daemon/cursor-stream.d.ts +4 -0
  185. package/dist/src/daemon/cursor-stream.js +154 -0
  186. package/dist/src/daemon/daemon-adapters.d.ts +58 -0
  187. package/dist/src/daemon/daemon-adapters.js +102 -0
  188. package/dist/src/daemon/daemon-loops.d.ts +14 -0
  189. package/dist/src/daemon/daemon-loops.js +39 -0
  190. package/dist/src/daemon/daemon.d.ts +3 -30
  191. package/dist/src/daemon/daemon.js +132 -110
  192. package/dist/src/daemon/declared-input.d.ts +3 -0
  193. package/dist/src/daemon/declared-input.js +9 -0
  194. package/dist/src/daemon/delivery-router.js +7 -1
  195. package/dist/src/daemon/gemini-stream.d.ts +4 -0
  196. package/dist/src/daemon/gemini-stream.js +129 -0
  197. package/dist/src/daemon/github-calls.d.ts +4 -0
  198. package/dist/src/daemon/github-calls.js +16 -7
  199. package/dist/src/daemon/github-ci-rerun.d.ts +26 -0
  200. package/dist/src/daemon/github-ci-rerun.js +92 -0
  201. package/dist/src/daemon/github-ci.d.ts +6 -0
  202. package/dist/src/daemon/github-ci.js +251 -0
  203. package/dist/src/daemon/github-merge-call.d.ts +16 -0
  204. package/dist/src/daemon/github-merge-call.js +73 -0
  205. package/dist/src/daemon/github-merge.d.ts +3 -5
  206. package/dist/src/daemon/github-merge.js +59 -98
  207. package/dist/src/daemon/github-methods.d.ts +28 -0
  208. package/dist/src/daemon/github-methods.js +90 -16
  209. package/dist/src/daemon/github-operation.d.ts +3 -0
  210. package/dist/src/daemon/github-retry.d.ts +6 -0
  211. package/dist/src/daemon/github-retry.js +13 -0
  212. package/dist/src/daemon/github-ticket-status.js +27 -1
  213. package/dist/src/daemon/github-worker.js +2 -1
  214. package/dist/src/daemon/handoff-worker.d.ts +10 -0
  215. package/dist/src/daemon/handoff-worker.js +232 -0
  216. package/dist/src/daemon/issue-queue.d.ts +2 -0
  217. package/dist/src/daemon/issue-queue.js +92 -63
  218. package/dist/src/daemon/notify-journal.d.ts +18 -0
  219. package/dist/src/daemon/notify-journal.js +108 -0
  220. package/dist/src/daemon/notify-message.js +2 -1
  221. package/dist/src/daemon/notify.js +177 -37
  222. package/dist/src/daemon/opencode-stream.d.ts +5 -0
  223. package/dist/src/daemon/opencode-stream.js +87 -0
  224. package/dist/src/daemon/queue-status.d.ts +4 -0
  225. package/dist/src/daemon/queue-status.js +38 -0
  226. package/dist/src/daemon/retry-worktree.d.ts +18 -0
  227. package/dist/src/daemon/retry-worktree.js +139 -0
  228. package/dist/src/daemon/retrying-turn.d.ts +5 -0
  229. package/dist/src/daemon/retrying-turn.js +145 -21
  230. package/dist/src/daemon/schedule-journal.d.ts +19 -0
  231. package/dist/src/daemon/schedule-journal.js +57 -0
  232. package/dist/src/daemon/text-output.d.ts +18 -0
  233. package/dist/src/daemon/text-output.js +44 -0
  234. package/dist/src/daemon/ticket-dependency-waits.d.ts +18 -0
  235. package/dist/src/daemon/ticket-dependency-waits.js +60 -0
  236. package/dist/src/daemon/ticket-registration.d.ts +10 -8
  237. package/dist/src/daemon/ticket-registration.js +146 -47
  238. package/dist/src/daemon/ticket-source.d.ts +4 -1
  239. package/dist/src/daemon/ticket-source.js +8 -2
  240. package/dist/src/daemon/turn-command.d.ts +10 -0
  241. package/dist/src/daemon/turn-command.js +33 -0
  242. package/dist/src/daemon/turn-report.d.ts +18 -0
  243. package/dist/src/daemon/turn-report.js +79 -0
  244. package/dist/src/daemon/work-tree.d.ts +2 -1
  245. package/dist/src/daemon/work-tree.js +15 -12
  246. package/dist/src/daemon/workflow-generations.d.ts +32 -0
  247. package/dist/src/daemon/workflow-generations.js +57 -0
  248. package/dist/src/daemon/workflow-replay.d.ts +16 -0
  249. package/dist/src/daemon/workflow-replay.js +58 -0
  250. package/dist/src/daemon/workflow-schedules.d.ts +27 -0
  251. package/dist/src/daemon/workflow-schedules.js +185 -0
  252. package/dist/src/decision-visibility.d.ts +2 -0
  253. package/dist/src/decision-visibility.js +10 -0
  254. package/dist/src/decision-wait.d.ts +1 -0
  255. package/dist/src/decision-wait.js +3 -0
  256. package/dist/src/delivery-backoff.d.ts +1 -0
  257. package/dist/src/delivery-backoff.js +3 -0
  258. package/dist/src/doctor-report.d.ts +24 -0
  259. package/dist/src/doctor-report.js +70 -0
  260. package/dist/src/execution-pin.d.ts +9 -0
  261. package/dist/src/execution-pin.js +86 -2
  262. package/dist/src/grok-result.d.ts +12 -0
  263. package/dist/src/grok-result.js +61 -0
  264. package/dist/src/harness-defaults.d.ts +35 -0
  265. package/dist/src/harness-defaults.js +121 -0
  266. package/dist/src/host/decision-resume.d.ts +35 -0
  267. package/dist/src/host/decision-resume.js +86 -0
  268. package/dist/src/host/gate-bridge.d.ts +48 -0
  269. package/dist/src/host/gate-bridge.js +124 -0
  270. package/dist/src/host/run-wait.d.ts +26 -0
  271. package/dist/src/host/run-wait.js +37 -0
  272. package/dist/src/host/start-delivery.d.ts +3 -2
  273. package/dist/src/host/start-delivery.js +11 -4
  274. package/dist/src/host/step-bridge-host.d.ts +6 -19
  275. package/dist/src/host/step-bridge-host.js +57 -55
  276. package/dist/src/host/world-reconciliation.d.ts +1 -0
  277. package/dist/src/host/world-reconciliation.js +3 -0
  278. package/dist/src/host/world-runs.js +5 -0
  279. package/dist/src/issue-identity.d.ts +6 -0
  280. package/dist/src/issue-identity.js +23 -0
  281. package/dist/src/merge-request.d.ts +19 -0
  282. package/dist/src/merge-request.js +32 -0
  283. package/dist/src/phone/canonical-json.d.ts +1 -0
  284. package/dist/src/phone/canonical-json.js +16 -0
  285. package/dist/src/phone/phone-link.d.ts +7 -0
  286. package/dist/src/phone/phone-link.js +21 -0
  287. package/dist/src/phone/qr-data.d.ts +8 -0
  288. package/dist/src/phone/qr-data.js +133 -0
  289. package/dist/src/phone/qr-matrix.d.ts +6 -0
  290. package/dist/src/phone/qr-matrix.js +175 -0
  291. package/dist/src/phone/qr-penalty.d.ts +3 -0
  292. package/dist/src/phone/qr-penalty.js +67 -0
  293. package/dist/src/phone/qr-picture.d.ts +5 -0
  294. package/dist/src/phone/qr-picture.js +24 -0
  295. package/dist/src/private-config.schema.json +263 -0
  296. package/dist/src/project-config.schema.json +65 -0
  297. package/dist/src/project-settings.d.ts +19 -0
  298. package/dist/src/project-settings.js +131 -0
  299. package/dist/src/relay/answer-check.d.ts +24 -0
  300. package/dist/src/relay/answer-check.js +145 -0
  301. package/dist/src/relay/answer-inbox.d.ts +15 -0
  302. package/dist/src/relay/answer-inbox.js +173 -0
  303. package/dist/src/relay/daemon-keys.d.ts +16 -0
  304. package/dist/src/relay/daemon-keys.js +75 -0
  305. package/dist/src/relay/decision-check.d.ts +3 -0
  306. package/dist/src/relay/decision-check.js +77 -0
  307. package/dist/src/relay/decision-close.d.ts +6 -0
  308. package/dist/src/relay/decision-close.js +72 -0
  309. package/dist/src/relay/decision-envelopes.d.ts +29 -0
  310. package/dist/src/relay/decision-envelopes.js +93 -0
  311. package/dist/src/relay/decision-watch.d.ts +14 -0
  312. package/dist/src/relay/decision-watch.js +68 -0
  313. package/dist/src/relay/envelope-post.d.ts +8 -0
  314. package/dist/src/relay/envelope-post.js +71 -0
  315. package/dist/src/relay/envelope.d.ts +28 -0
  316. package/dist/src/relay/envelope.js +53 -0
  317. package/dist/src/relay/hpke.d.ts +25 -0
  318. package/dist/src/relay/hpke.js +108 -0
  319. package/dist/src/relay/pairing-checks.d.ts +42 -0
  320. package/dist/src/relay/pairing-checks.js +172 -0
  321. package/dist/src/relay/pairing-follow.d.ts +8 -0
  322. package/dist/src/relay/pairing-follow.js +95 -0
  323. package/dist/src/relay/pairing-session.d.ts +29 -0
  324. package/dist/src/relay/pairing-session.js +87 -0
  325. package/dist/src/relay/phone-delivery.d.ts +51 -0
  326. package/dist/src/relay/phone-delivery.js +139 -0
  327. package/dist/src/relay/phone-devices.d.ts +36 -0
  328. package/dist/src/relay/phone-devices.js +46 -0
  329. package/dist/src/relay/phone-inbox.d.ts +18 -0
  330. package/dist/src/relay/phone-inbox.js +17 -0
  331. package/dist/src/relay/phone-operations.d.ts +18 -0
  332. package/dist/src/relay/phone-operations.js +121 -0
  333. package/dist/src/relay/phone-outbox.d.ts +21 -0
  334. package/dist/src/relay/phone-outbox.js +25 -0
  335. package/dist/src/relay/phone-socket.d.ts +6 -0
  336. package/dist/src/relay/phone-socket.js +63 -0
  337. package/dist/src/relay/relay-control.d.ts +7 -0
  338. package/dist/src/relay/relay-control.js +24 -0
  339. package/dist/src/relay/relay-files.d.ts +2 -0
  340. package/dist/src/relay/relay-files.js +23 -0
  341. package/dist/src/relay/relay-heartbeat.d.ts +17 -0
  342. package/dist/src/relay/relay-heartbeat.js +81 -0
  343. package/dist/src/relay/relay-http.d.ts +14 -0
  344. package/dist/src/relay/relay-http.js +63 -0
  345. package/dist/src/relay/relay-registration.d.ts +15 -0
  346. package/dist/src/relay/relay-registration.js +63 -0
  347. package/dist/src/relay/relay-service.d.ts +25 -0
  348. package/dist/src/relay/relay-service.js +216 -0
  349. package/dist/src/relay/relay-store.d.ts +48 -0
  350. package/dist/src/relay/relay-store.js +131 -0
  351. package/dist/src/relay/sealed-post.d.ts +25 -0
  352. package/dist/src/relay/sealed-post.js +52 -0
  353. package/dist/src/relay.d.ts +1 -0
  354. package/dist/src/relay.js +8 -0
  355. package/dist/src/report-statistics.d.ts +50 -0
  356. package/dist/src/report-statistics.js +70 -0
  357. package/dist/src/report.d.ts +171 -0
  358. package/dist/src/report.js +119 -0
  359. package/dist/src/repository-identity.d.ts +4 -0
  360. package/dist/src/repository-identity.js +4 -0
  361. package/dist/src/review-subject.d.ts +41 -0
  362. package/dist/src/review-subject.js +91 -0
  363. package/dist/src/run-wait.d.ts +23 -0
  364. package/dist/src/run-wait.js +20 -0
  365. package/dist/src/service/active-tickets.d.ts +4 -0
  366. package/dist/src/service/active-tickets.js +49 -0
  367. package/dist/src/service/command-effects.d.ts +4 -0
  368. package/dist/src/service/command-effects.js +16 -0
  369. package/dist/src/service/decision-handler.d.ts +4 -0
  370. package/dist/src/service/decision-handler.js +39 -4
  371. package/dist/src/service/gateway.js +18 -3
  372. package/dist/src/service/queue-runs.d.ts +3 -0
  373. package/dist/src/service/queue-runs.js +39 -0
  374. package/dist/src/service/registry.d.ts +22 -3
  375. package/dist/src/service/registry.js +51 -8
  376. package/dist/src/service/replies.d.ts +10 -0
  377. package/dist/src/service/replies.js +12 -0
  378. package/dist/src/service/run-handlers.js +45 -54
  379. package/dist/src/service/run-metadata.d.ts +8 -0
  380. package/dist/src/service/run-metadata.js +53 -0
  381. package/dist/src/service/run-waits.d.ts +3 -0
  382. package/dist/src/service/run-waits.js +41 -0
  383. package/dist/src/service/service.d.ts +21 -2
  384. package/dist/src/service/service.js +23 -5
  385. package/dist/src/service/submission-handler.js +70 -19
  386. package/dist/src/service/worker-port.d.ts +1 -0
  387. package/dist/src/service/worker-totals.js +10 -1
  388. package/dist/src/step-bridge.d.ts +32 -0
  389. package/dist/src/steps/decision-gate.d.ts +2 -1
  390. package/dist/src/steps/decision-gate.js +7 -0
  391. package/dist/src/steps/handoff.d.ts +2 -0
  392. package/dist/src/steps/handoff.js +13 -0
  393. package/dist/src/steps/merge-by-person.d.ts +2 -0
  394. package/dist/src/steps/merge-by-person.js +18 -0
  395. package/dist/src/steps/merge-when-green.d.ts +2 -0
  396. package/dist/src/steps/merge-when-green.js +62 -0
  397. package/dist/src/steps/review-by-agent.d.ts +5 -0
  398. package/dist/src/steps/review-by-agent.js +124 -0
  399. package/dist/src/steps/review-by-person.d.ts +4 -0
  400. package/dist/src/steps/review-by-person.js +16 -0
  401. package/dist/src/steps/review-subject.d.ts +2 -0
  402. package/dist/src/steps/review-subject.js +11 -0
  403. package/dist/src/steps/run-command.d.ts +2 -0
  404. package/dist/src/steps/run-command.js +15 -0
  405. package/dist/src/steps/sleep.d.ts +3 -0
  406. package/dist/src/steps/sleep.js +19 -0
  407. package/dist/src/steps/wait-for-decision.d.ts +2 -0
  408. package/dist/src/steps/wait-for-decision.js +71 -0
  409. package/dist/src/steps/wait-for-run.d.ts +5 -0
  410. package/dist/src/steps/wait-for-run.js +9 -0
  411. package/dist/src/storage/decision-snapshots.d.ts +1 -0
  412. package/dist/src/storage/decision-snapshots.js +7 -1
  413. package/dist/src/submission.d.ts +4 -0
  414. package/dist/src/submission.js +6 -2
  415. package/dist/src/testing.d.ts +29 -0
  416. package/dist/src/testing.js +264 -0
  417. package/dist/src/ticket-dependencies.d.ts +1 -0
  418. package/dist/src/ticket-dependencies.js +15 -0
  419. package/dist/src/ticket-status-stream.d.ts +9 -0
  420. package/dist/src/ticket-status-stream.js +94 -0
  421. package/dist/src/ticket-status.js +7 -4
  422. package/dist/src/token-prices.d.ts +14 -4
  423. package/dist/src/token-prices.js +56 -11
  424. package/dist/src/turn-profile.d.ts +1 -0
  425. package/dist/src/turn-profile.js +8 -1
  426. package/dist/src/worker-usage.d.ts +25 -0
  427. package/dist/src/worker-usage.js +58 -1
  428. package/dist/src/workflow-admission.d.ts +6 -0
  429. package/dist/src/workflow-candidate.d.ts +7 -2
  430. package/dist/src/workflow-candidate.js +48 -5
  431. package/dist/src/workflow-contracts.d.ts +2 -0
  432. package/dist/src/workflow-contracts.js +8 -3
  433. package/dist/src/workflow-declaration.d.ts +31 -2
  434. package/dist/src/workflow-declaration.js +140 -16
  435. package/dist/src/workflow-discovery.d.ts +19 -0
  436. package/dist/src/workflow-discovery.js +36 -0
  437. package/dist/src/workflow-refusals.d.ts +6 -0
  438. package/dist/src/workflow-refusals.js +42 -0
  439. package/dist/src/workflow-schedule.d.ts +22 -0
  440. package/dist/src/workflow-schedule.js +53 -0
  441. package/dist/src/workflows.d.ts +12 -1
  442. package/dist/src/workflows.js +9 -0
  443. package/dist/tools/admit-workflow.d.ts +14 -0
  444. package/dist/tools/admit-workflow.js +107 -0
  445. package/dist/tools/doctor-adoption.d.ts +1 -0
  446. package/dist/tools/doctor-adoption.js +11 -0
  447. package/dist/tools/project-configuration.d.ts +4 -0
  448. package/dist/tools/project-configuration.js +47 -0
  449. package/dist/tools/self-host-processes.d.ts +1 -0
  450. package/dist/tools/self-host-processes.js +33 -22
  451. package/dist/tools/self-host-project.d.ts +21 -0
  452. package/dist/tools/self-host-project.js +224 -0
  453. package/dist/tools/self-host-runtime.d.ts +16 -0
  454. package/dist/tools/self-host-runtime.js +60 -0
  455. package/dist/tools/self-host-workflows.d.ts +1 -0
  456. package/dist/tools/self-host-workflows.js +36 -1
  457. package/dist/tools/self-host.js +106 -135
  458. package/dist/tools/workflow-bundle-dependencies.d.ts +5 -0
  459. package/dist/tools/workflow-bundle-dependencies.js +93 -0
  460. package/dist/tools/workflow-bundles.d.ts +20 -0
  461. package/dist/tools/workflow-bundles.js +173 -0
  462. package/dist/tools/workflow-candidate-counts.d.ts +12 -0
  463. package/dist/tools/workflow-candidate-counts.js +266 -0
  464. package/dist/tools/workflow-candidate-fields.d.ts +5 -0
  465. package/dist/tools/workflow-candidate-fields.js +24 -0
  466. package/dist/tools/workflow-candidate-helper-counts.d.ts +10 -0
  467. package/dist/tools/workflow-candidate-helper-counts.js +129 -0
  468. package/dist/tools/workflow-candidate-program.d.ts +13 -0
  469. package/dist/tools/workflow-candidate-program.js +106 -0
  470. package/dist/tools/workflow-candidate-source.d.ts +6 -0
  471. package/dist/tools/workflow-candidate-source.js +169 -0
  472. package/dist/tools/workflow-candidate-syntax.d.ts +21 -0
  473. package/dist/tools/workflow-candidate-syntax.js +263 -0
  474. package/dist/tools/workflow-command.d.ts +1 -0
  475. package/dist/tools/workflow-command.js +143 -0
  476. package/dist/tools/workflow-folder-capture.d.ts +18 -0
  477. package/dist/tools/workflow-folder-capture.js +261 -0
  478. package/dist/tools/workflow-folders.d.ts +49 -0
  479. package/dist/tools/workflow-folders.js +203 -0
  480. package/dist/tools/workflow-source-effects.d.ts +10 -0
  481. package/dist/tools/workflow-source-effects.js +213 -0
  482. package/dist/tools/workflow-test-hook.d.ts +7 -0
  483. package/dist/tools/workflow-test-hook.js +16 -0
  484. package/dist/tools/workflow-test-loader.d.ts +1 -0
  485. package/dist/tools/workflow-test-loader.js +10 -0
  486. package/dist/workflows/develop-prd.js +71 -3
  487. package/dist/workflows/develop-ticket.js +6 -1
  488. package/dist/workflows/ticket-prompts.js +17 -3
  489. package/package.json +66 -6
  490. package/templates/develop/README.md +78 -0
  491. package/templates/develop/develop/accept.ts +11 -0
  492. package/templates/develop/develop/flow-tests.ts +357 -0
  493. package/templates/develop/develop/local.ts +40 -0
  494. package/templates/develop/develop/option-tests.ts +174 -0
  495. package/templates/develop/develop/partial-choice.ts +29 -0
  496. package/templates/develop/develop/partial.ts +28 -0
  497. package/templates/develop/develop/pull.ts +152 -0
  498. package/templates/develop/develop/queue-partial.ts +39 -0
  499. package/templates/develop/develop/refusal-tests.ts +174 -0
  500. package/templates/develop/develop/report.ts +156 -0
  501. package/templates/develop/develop/round.ts +40 -0
  502. package/templates/develop/develop/scenarios.ts +87 -0
  503. package/templates/develop/develop/turn.ts +67 -0
  504. package/templates/develop/develop.declaration.json +24 -0
  505. package/templates/develop/develop.test.ts +287 -0
  506. package/templates/develop/develop.ts +30 -0
  507. package/templates/develop/template.json +153 -0
  508. package/dist/src/chats/analysis-batches.d.ts +0 -24
  509. package/dist/src/chats/analysis-batches.js +0 -83
  510. package/dist/src/chats/analysis-contract.d.ts +0 -80
  511. package/dist/src/chats/analysis-contract.js +0 -16
  512. package/dist/src/chats/analysis-data.d.ts +0 -3
  513. package/dist/src/chats/analysis-data.js +0 -85
  514. package/dist/src/chats/analysis-input.d.ts +0 -12
  515. package/dist/src/chats/analysis-input.js +0 -83
  516. package/dist/src/chats/analysis-links.d.ts +0 -2
  517. package/dist/src/chats/analysis-links.js +0 -25
  518. package/dist/src/chats/analysis-prompt.d.ts +0 -10
  519. package/dist/src/chats/analysis-prompt.js +0 -16
  520. package/dist/src/chats/analysis-proposal.d.ts +0 -2
  521. package/dist/src/chats/analysis-proposal.js +0 -32
  522. package/dist/src/chats/analysis-provenance.d.ts +0 -4
  523. package/dist/src/chats/analysis-provenance.js +0 -99
  524. package/dist/src/chats/analysis-shape.d.ts +0 -3
  525. package/dist/src/chats/analysis-shape.js +0 -228
  526. package/dist/src/chats/analysis.d.ts +0 -3
  527. package/dist/src/chats/analysis.js +0 -42
  528. package/dist/src/chats/corpus-input.d.ts +0 -5
  529. package/dist/src/chats/corpus-input.js +0 -288
  530. package/dist/src/chats/destination.d.ts +0 -4
  531. package/dist/src/chats/destination.js +0 -96
  532. package/dist/src/chats/import.d.ts +0 -15
  533. package/dist/src/chats/import.js +0 -243
  534. package/dist/src/chats/input-file.d.ts +0 -3
  535. package/dist/src/chats/input-file.js +0 -32
  536. package/dist/src/chats/normalize.d.ts +0 -29
  537. package/dist/src/chats/normalize.js +0 -155
  538. package/dist/src/chats/previous-import.d.ts +0 -5
  539. package/dist/src/chats/previous-import.js +0 -34
  540. package/dist/src/chats/reader.d.ts +0 -21
  541. package/dist/src/chats/reader.js +0 -118
  542. package/dist/src/chats/redact-import.d.ts +0 -14
  543. package/dist/src/chats/redact-import.js +0 -141
  544. package/dist/src/chats/redaction.d.ts +0 -41
  545. package/dist/src/chats/redaction.js +0 -161
  546. package/dist/src/chats/revision-input.d.ts +0 -3
  547. package/dist/src/chats/revision-input.js +0 -180
  548. package/dist/src/chats/revision.d.ts +0 -48
  549. package/dist/src/chats/revision.js +0 -94
  550. package/dist/src/chats/selection.d.ts +0 -25
  551. package/dist/src/chats/selection.js +0 -109
  552. package/dist/src/chats/source.d.ts +0 -23
  553. package/dist/src/chats/source.js +0 -135
  554. package/dist/src/chats/structure.d.ts +0 -57
  555. package/dist/src/chats/structure.js +0 -216
  556. package/dist/src/daemon/analysis-launch.d.ts +0 -5
  557. package/dist/src/daemon/analysis-launch.js +0 -81
  558. package/dist/src/daemon/analysis-token.d.ts +0 -6
  559. package/dist/src/daemon/analysis-token.js +0 -88
  560. package/dist/src/daemon/analysis-worker.d.ts +0 -22
  561. package/dist/src/daemon/analysis-worker.js +0 -219
  562. package/dist/src/daemon/chats-files.d.ts +0 -15
  563. package/dist/src/daemon/chats-files.js +0 -113
  564. package/dist/src/daemon/chats-worker.d.ts +0 -12
  565. package/dist/src/daemon/chats-worker.js +0 -200
  566. package/dist/workflows/analyze-chats.d.ts +0 -10
  567. package/dist/workflows/analyze-chats.declaration.json +0 -9
  568. package/dist/workflows/analyze-chats.js +0 -73
@@ -1,88 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- function failed(category) {
3
- return { error: "analysis-token-command-" + category };
4
- }
5
- function commandOf(setting) {
6
- try {
7
- const parsed = JSON.parse(setting);
8
- if (!Array.isArray(parsed) || parsed.length === 0)
9
- return undefined;
10
- const entries = parsed;
11
- if (entries.every((entry) => typeof entry === "string" && entry.length > 0))
12
- return entries;
13
- return undefined;
14
- }
15
- catch {
16
- return undefined;
17
- }
18
- }
19
- function tokenOf(chunks) {
20
- const token = Buffer.concat(chunks)
21
- .toString("utf8")
22
- .replace(/(?:\r\n|[\r\n])$/, "");
23
- return /^[!-~]{1,512}$/.test(token) ? { token } : failed("output-invalid");
24
- }
25
- function captured(command, request) {
26
- return new Promise((settle) => {
27
- const [program = "", ...arguments_] = command;
28
- const child = spawn(program, arguments_, {
29
- cwd: request.folder,
30
- shell: false,
31
- stdio: ["ignore", "pipe", "pipe"],
32
- signal: request.signal,
33
- killSignal: "SIGKILL",
34
- });
35
- const chunks = [];
36
- let bytes = 0;
37
- let stopped = false;
38
- const stop = (category) => {
39
- stopped = true;
40
- clearTimeout(timer);
41
- child.kill("SIGKILL");
42
- child.stdout.destroy();
43
- child.stderr.destroy();
44
- settle(failed(category));
45
- };
46
- const timer = setTimeout(() => {
47
- stop("timeout");
48
- }, 10_000);
49
- const received = (chunk, output) => {
50
- if (stopped)
51
- return;
52
- bytes += chunk.length;
53
- if (bytes > 4_096) {
54
- stop("output-too-large");
55
- return;
56
- }
57
- output?.push(chunk);
58
- };
59
- child.stdout.on("data", (chunk) => {
60
- received(chunk, chunks);
61
- });
62
- child.stderr.on("data", (chunk) => {
63
- received(chunk);
64
- });
65
- child.once("error", () => {
66
- stop("failed");
67
- });
68
- child.once("close", (code) => {
69
- clearTimeout(timer);
70
- if (!stopped)
71
- settle(code === 0 ? tokenOf(chunks) : failed("failed"));
72
- });
73
- });
74
- }
75
- export async function analysisToken(folder, signal) {
76
- const setting = process.env["CLOVING_ANALYSIS_TOKEN_COMMAND"];
77
- if (setting === undefined)
78
- return failed("unset");
79
- const command = commandOf(setting);
80
- if (command === undefined)
81
- return failed("invalid");
82
- try {
83
- return await captured(command, { folder, signal });
84
- }
85
- catch {
86
- return failed("failed");
87
- }
88
- }
@@ -1,22 +0,0 @@
1
- import type { AdapterOutcome, DeliveryIntent } from "../broker/actor/delivery-intents.ts";
2
- import { type TokenPrices } from "../token-prices.ts";
3
- import { type RetrySettings } from "./retrying-turn.ts";
4
- import { type WorkerReport } from "./operation-journal.ts";
5
- interface Settings extends RetrySettings {
6
- readonly tokenPrices?: TokenPrices;
7
- readonly journal: string;
8
- readonly document: (digest: string) => Promise<string | undefined>;
9
- readonly report: (report: WorkerReport) => Promise<unknown>;
10
- readonly stopMilliseconds?: number;
11
- }
12
- interface AnalysisWorker {
13
- readonly deliver: (intent: DeliveryIntent, signal: AbortSignal) => Promise<AdapterOutcome | {
14
- readonly receipt: string;
15
- readonly worker: string;
16
- }>;
17
- readonly reconcile: (intent: DeliveryIntent, signal: AbortSignal) => Promise<AdapterOutcome>;
18
- readonly stop: (intent: DeliveryIntent, signal: AbortSignal) => Promise<AdapterOutcome>;
19
- readonly close: () => Promise<void>;
20
- }
21
- export declare function analysisWorker(settings: Settings): AnalysisWorker;
22
- export {};
@@ -1,219 +0,0 @@
1
- import { mkdir, rm } from "node:fs/promises";
2
- import { join } from "node:path";
3
- import { analysisPrompt } from "../chats/analysis-prompt.js";
4
- import { isAnalysisSnapshot } from "../chats/analysis-input.js";
5
- import { record } from "../protocol.js";
6
- import { estimatedCostUsd, priceForModel, } from "../token-prices.js";
7
- import { startRetriedTurn } from "./retrying-turn.js";
8
- import { analysisAvailable, analysisMethod } from "./analysis-launch.js";
9
- import { analysisToken } from "./analysis-token.js";
10
- import { located, readRecord, writeRecord, replied, reportOf, interrupted, } from "./operation-journal.js";
11
- function own(intent) {
12
- return (intent.kind === "protected-effect" &&
13
- intent.capability === "claude" &&
14
- intent.method === analysisMethod &&
15
- intent.target !== undefined &&
16
- intent.payload !== undefined &&
17
- intent.leaseGeneration !== undefined);
18
- }
19
- function failed(reason) {
20
- return { kind: "failed", reason };
21
- }
22
- function snapshotOf(text) {
23
- try {
24
- return record(JSON.parse(text ?? "null"))?.["snapshot"];
25
- }
26
- catch {
27
- return undefined;
28
- }
29
- }
30
- async function cleaned(folder) {
31
- await Promise.all(["configuration", "working"].map((name) => rm(join(folder, name), { recursive: true, force: true })));
32
- }
33
- async function privateRecord(folder, entry) {
34
- await writeRecord(folder, { ...entry, permissions: "private" });
35
- }
36
- function outcome(end, prices) {
37
- const endedAt = new Date().toISOString();
38
- if (end.stopped)
39
- return { outcome: "stopped", endedAt };
40
- const result = end.result;
41
- if (result === undefined)
42
- return { ...interrupted("analysis-turn-failed"), endedAt };
43
- const fields = {
44
- costUsd: result.costUsd,
45
- usage: result.usage,
46
- model: result.model,
47
- sessionId: result.sessionId,
48
- turns: result.turns,
49
- estimatedCostUsd: estimatedCostUsd(result.usage, {
50
- worker: "claude",
51
- price: priceForModel(prices, result.model),
52
- }),
53
- };
54
- if (end.exitCode !== 0 || result.failed)
55
- return {
56
- outcome: "failed",
57
- reason: "analysis-turn-failed",
58
- endedAt,
59
- result: JSON.stringify(fields),
60
- };
61
- if (Buffer.byteLength(result.text, "utf8") > 16_000)
62
- return {
63
- outcome: "failed",
64
- reason: "analysis-reply-too-large",
65
- endedAt,
66
- result: JSON.stringify(fields),
67
- };
68
- return {
69
- outcome: "completed",
70
- endedAt,
71
- result: JSON.stringify({ ...fields, reply: result.text }),
72
- };
73
- }
74
- function running(processId) {
75
- if (typeof processId !== "number")
76
- return false;
77
- try {
78
- process.kill(processId, 0);
79
- return true;
80
- }
81
- catch {
82
- return false;
83
- }
84
- }
85
- async function reconcile(parts, intent) {
86
- if (!own(intent))
87
- return failed("unsupported-effect");
88
- const { key, folder } = located(parts.settings.journal, intent.operationId);
89
- const result = await readRecord(folder, "result.json");
90
- if (result !== undefined) {
91
- await cleaned(folder);
92
- return replied({ receipt: key, worker: "claude" }, result);
93
- }
94
- if (parts.active.has(key))
95
- return { kind: "accepted", receipt: key, worker: "claude" };
96
- const started = await readRecord(folder, "started.json");
97
- if (started === undefined)
98
- return { kind: "absent" };
99
- if (running(record(started)?.["processId"]))
100
- return { kind: "unknown", evidence: key };
101
- const ending = interrupted("analysis-turn-failed");
102
- await privateRecord(folder, { name: "result.json", value: ending });
103
- await cleaned(folder);
104
- return replied({ receipt: key, worker: "claude" }, ending);
105
- }
106
- async function begun(parts, opening) {
107
- const { intent, folder, key, directory, prompt } = opening;
108
- const started = {
109
- operationId: intent.operationId,
110
- target: intent.target,
111
- mode: "analysis",
112
- startedAt: new Date().toISOString(),
113
- };
114
- const turn = await startRetriedTurn({
115
- mode: "analysis",
116
- analysisToken: opening.token,
117
- command: [],
118
- folder,
119
- directory,
120
- prompt,
121
- }, { ...parts.settings, metadata: started });
122
- const done = turn.ended
123
- .then(async (end) => {
124
- const result = outcome(end, parts.settings.tokenPrices ?? {});
125
- await privateRecord(folder, { name: "result.json", value: result });
126
- await cleaned(folder);
127
- await parts.settings.report(reportOf({ intent, worker: "claude", commandId: `analysis-turn:${key}` }, result));
128
- })
129
- .catch(() => undefined)
130
- .finally(() => parts.active.delete(key));
131
- parts.active.set(key, { turn, done });
132
- }
133
- function cancelled(parts, signal) {
134
- return signal.aborted || parts.stopping.signal.aborted;
135
- }
136
- async function deliver(parts, call) {
137
- const { intent, signal } = call;
138
- if (!own(intent))
139
- return failed("unsupported-effect");
140
- const known = await reconcile(parts, intent);
141
- if (known.kind !== "absent")
142
- return known;
143
- const { key, folder } = located(parts.settings.journal, intent.operationId);
144
- const text = await parts.settings.document(intent.payload);
145
- const snapshot = snapshotOf(text);
146
- if (!isAnalysisSnapshot(snapshot) || snapshot.importId !== intent.target)
147
- return failed("analysis-input-refused");
148
- await mkdir(join(folder, "configuration"), { recursive: true, mode: 0o700 });
149
- if (!(await analysisAvailable(folder))) {
150
- await cleaned(folder);
151
- return failed("analysis-worker-unavailable");
152
- }
153
- if (cancelled(parts, signal)) {
154
- await cleaned(folder);
155
- return failed("analysis-turn-failed");
156
- }
157
- const credential = await analysisToken(folder, signal);
158
- if (cancelled(parts, signal)) {
159
- await cleaned(folder);
160
- return failed("analysis-turn-failed");
161
- }
162
- if ("error" in credential) {
163
- await cleaned(folder);
164
- return {
165
- ...failed("analysis-worker-unavailable"),
166
- result: JSON.stringify({ error: credential.error }),
167
- };
168
- }
169
- const directory = join(folder, "working");
170
- await mkdir(directory, { mode: 0o700 });
171
- await begun(parts, {
172
- intent,
173
- key,
174
- folder,
175
- directory,
176
- prompt: analysisPrompt(snapshot),
177
- token: credential.token,
178
- });
179
- return { receipt: key, worker: "claude" };
180
- }
181
- async function halted(parts, active) {
182
- active.turn.stop(parts.settings.stopMilliseconds ?? 2_000);
183
- await active.done;
184
- }
185
- function delivered(parts, call) {
186
- if (cancelled(parts, call.signal))
187
- return Promise.resolve(failed("analysis-turn-failed"));
188
- const key = call.intent.operationId;
189
- const known = parts.preparing.get(key);
190
- if (known !== undefined)
191
- return known;
192
- const signal = AbortSignal.any([call.signal, parts.stopping.signal]);
193
- const pending = deliver(parts, { ...call, signal }).finally(() => parts.preparing.delete(key));
194
- parts.preparing.set(key, pending);
195
- return pending;
196
- }
197
- export function analysisWorker(settings) {
198
- const parts = {
199
- settings,
200
- active: new Map(),
201
- preparing: new Map(),
202
- stopping: new AbortController(),
203
- };
204
- return {
205
- deliver: (intent, signal) => delivered(parts, { intent, signal }),
206
- reconcile: (intent) => reconcile(parts, intent),
207
- stop: async (intent) => {
208
- const active = parts.active.get(located(settings.journal, intent.operationId).key);
209
- if (active !== undefined)
210
- await halted(parts, active);
211
- return reconcile(parts, intent);
212
- },
213
- close: async () => {
214
- parts.stopping.abort();
215
- await Promise.all(parts.preparing.values());
216
- await Promise.all([...parts.active.values()].map((active) => halted(parts, active)));
217
- },
218
- };
219
- }
@@ -1,15 +0,0 @@
1
- import { type AnalysisSnapshot } from "../chats/analysis-input.ts";
2
- export declare function analysisDirectory(runtime: string, importId: string): Promise<string>;
3
- export declare function boundedAnalysisFile(path: string, options?: {
4
- readonly permissions?: number;
5
- }): Promise<string>;
6
- export declare function readAnalysisSnapshot(directory: string, importId: string): Promise<AnalysisSnapshot>;
7
- export declare function matchingPrivateFile(path: string, text: string): Promise<void>;
8
- interface AnalysisOutput {
9
- readonly cycleId: string;
10
- readonly analysis: string;
11
- readonly proposal: string;
12
- }
13
- export declare function inspectAnalysisFiles(directory: string, output: AnalysisOutput): Promise<"complete" | "absent">;
14
- export declare function saveAnalysisFiles(directory: string, output: AnalysisOutput): Promise<void>;
15
- export {};
@@ -1,113 +0,0 @@
1
- import { lstat } from "node:fs/promises";
2
- import { dirname, join, resolve } from "node:path";
3
- import { openInput } from "../chats/input-file.js";
4
- import { createPrivateFile, validateDestination, } from "../chats/destination.js";
5
- import { analysisDocumentBytes, } from "../chats/analysis-input.js";
6
- export async function analysisDirectory(runtime, importId) {
7
- if (process.platform !== "darwin")
8
- throw new Error("platform-unsupported");
9
- const directory = resolve(runtime, "chats", importId);
10
- await checkedDirectory(directory);
11
- return directory;
12
- }
13
- async function checkedDirectory(directory) {
14
- try {
15
- if (!(await lstat(directory)).isDirectory())
16
- throw new Error("analysis-input-refused");
17
- }
18
- catch (error) {
19
- if (Reflect.get(Object(error), "code") !== "ENOENT")
20
- throw error;
21
- const parent = dirname(directory);
22
- if (parent === directory)
23
- throw error;
24
- await checkedDirectory(parent);
25
- throw error;
26
- }
27
- await validateDestination(directory);
28
- }
29
- export async function boundedAnalysisFile(path, options = {}) {
30
- const handle = await openInput(path);
31
- try {
32
- if (options.permissions !== undefined &&
33
- ((await handle.stat()).mode & 0o777) !== options.permissions)
34
- throw new Error("analysis-output-failed");
35
- const buffer = Buffer.alloc(analysisDocumentBytes + 1);
36
- let size = 0;
37
- while (size < buffer.length) {
38
- const { bytesRead } = await handle.read(buffer, size, buffer.length - size, null);
39
- if (bytesRead === 0)
40
- break;
41
- size += bytesRead;
42
- }
43
- if (size > analysisDocumentBytes)
44
- throw new Error("analysis-too-large");
45
- return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(buffer.subarray(0, size));
46
- }
47
- finally {
48
- await handle.close();
49
- }
50
- }
51
- export async function readAnalysisSnapshot(directory, importId) {
52
- const required = async (name) => {
53
- try {
54
- return await boundedAnalysisFile(join(directory, name));
55
- }
56
- catch (error) {
57
- if (Reflect.get(Object(error), "code") === "ENOENT")
58
- throw new Error("redaction-required", { cause: error });
59
- throw error;
60
- }
61
- };
62
- return {
63
- importId,
64
- redaction: await required("redaction.json"),
65
- corpus: await required("redacted.jsonl"),
66
- structure: await boundedAnalysisFile(join(directory, "structure.json")),
67
- };
68
- }
69
- export async function matchingPrivateFile(path, text) {
70
- try {
71
- const existing = await boundedAnalysisFile(path, { permissions: 0o600 });
72
- if (existing !== text)
73
- throw new Error("analysis-output-failed");
74
- return;
75
- }
76
- catch (error) {
77
- if (Reflect.get(Object(error), "code") !== "ENOENT")
78
- throw error;
79
- }
80
- const handle = await createPrivateFile(path);
81
- try {
82
- await handle.writeFile(text);
83
- }
84
- finally {
85
- await handle.close();
86
- }
87
- }
88
- export async function inspectAnalysisFiles(directory, output) {
89
- const proposal = join(directory, `proposal-${output.cycleId}.txt`);
90
- const analysis = join(directory, `analysis-${output.cycleId}.json`);
91
- const marker = await boundedAnalysisFile(analysis, {
92
- permissions: 0o600,
93
- }).catch((error) => {
94
- if (Reflect.get(Object(error), "code") === "ENOENT")
95
- return undefined;
96
- throw error;
97
- });
98
- if (marker === undefined)
99
- return "absent";
100
- if (marker !== output.analysis ||
101
- (await boundedAnalysisFile(proposal, { permissions: 0o600 })) !==
102
- output.proposal)
103
- throw new Error("analysis-output-failed");
104
- return "complete";
105
- }
106
- export async function saveAnalysisFiles(directory, output) {
107
- if ((await inspectAnalysisFiles(directory, output)) === "complete")
108
- return;
109
- const proposal = join(directory, `proposal-${output.cycleId}.txt`);
110
- const analysis = join(directory, `analysis-${output.cycleId}.json`);
111
- await matchingPrivateFile(proposal, output.proposal);
112
- await matchingPrivateFile(analysis, output.analysis);
113
- }
@@ -1,12 +0,0 @@
1
- import type { AdapterOutcome, DeliveryIntent } from "../broker/actor/delivery-intents.ts";
2
- import type { EffectDelivery } from "./delivery-router.ts";
3
- export interface ChatsWorkerSettings {
4
- readonly runtimeDirectory: string;
5
- readonly document: (digest: string) => Promise<string | undefined>;
6
- readonly workflowId: (runId: string) => Promise<string | undefined>;
7
- }
8
- export interface ChatsWorker extends EffectDelivery {
9
- readonly deliver: (intent: DeliveryIntent, signal: AbortSignal) => Promise<AdapterOutcome>;
10
- readonly close: () => Promise<void>;
11
- }
12
- export declare function chatsWorker(settings: ChatsWorkerSettings): ChatsWorker;
@@ -1,200 +0,0 @@
1
- import { record } from "../protocol.js";
2
- import { validateAnalysis } from "../chats/analysis.js";
3
- import { analysisDocumentBytes, analysisEvidence, analysisModelInput, isAnalysisSnapshot, validAnalysisImportId, } from "../chats/analysis-input.js";
4
- import { analysisProposal } from "../chats/analysis-proposal.js";
5
- import { operationKey } from "./operation-journal.js";
6
- import { analysisDirectory, readAnalysisSnapshot, saveAnalysisFiles, inspectAnalysisFiles, } from "./chats-files.js";
7
- function completed(intent, result) {
8
- return {
9
- kind: "completed",
10
- worker: "chats",
11
- receipt: operationKey(intent.operationId),
12
- result: JSON.stringify(result),
13
- };
14
- }
15
- function refused(code, codes = [code]) {
16
- return {
17
- kind: "failed",
18
- reason: code,
19
- result: JSON.stringify({ kind: "blocked", codes }),
20
- };
21
- }
22
- function bounded(text) {
23
- if (Buffer.byteLength(text) > analysisDocumentBytes)
24
- throw new Error("analysis-too-large");
25
- }
26
- function ownIntent(intent) {
27
- return (intent.kind === "protected-effect" &&
28
- intent.capability === "chats" &&
29
- ["read-analysis", "save-analysis"].includes(intent.method ?? "") &&
30
- intent.payload !== undefined &&
31
- intent.leaseGeneration !== undefined);
32
- }
33
- async function payloadOf(settings, intent) {
34
- if (!ownIntent(intent) || intent.payload === undefined)
35
- throw new Error("unsupported-effect");
36
- if ((await settings.workflowId(intent.runId)) !== "analyze-chats")
37
- throw new Error("workflow-not-allowed");
38
- const text = await settings.document(intent.payload);
39
- if (text === undefined)
40
- throw new Error("payload-not-available");
41
- bounded(text);
42
- const payload = record(JSON.parse(text));
43
- if (payload === undefined)
44
- throw new Error("analysis-input-refused");
45
- const importId = payload["importId"];
46
- if (typeof importId !== "string" || importId === "")
47
- throw new Error("analysis-input-refused");
48
- if (!validAnalysisImportId(importId))
49
- throw new Error("invalid-import-id");
50
- if (intent.target !== importId)
51
- throw new Error("analysis-input-refused");
52
- return payload;
53
- }
54
- async function read(settings, call) {
55
- let directory;
56
- try {
57
- directory = await analysisDirectory(settings.runtimeDirectory, call.importId);
58
- }
59
- catch (error) {
60
- if (Reflect.get(Object(error), "code") === "ENOENT")
61
- throw new Error("redaction-required", { cause: error });
62
- throw error;
63
- }
64
- const snapshot = await readAnalysisSnapshot(directory, call.importId);
65
- bounded(JSON.stringify(snapshot));
66
- bounded(JSON.stringify({ prompt: analysisModelInput(snapshot) }));
67
- analysisEvidence(snapshot);
68
- const result = { snapshot };
69
- bounded(JSON.stringify(result));
70
- return completed(call.intent, result);
71
- }
72
- function saveInput(payload) {
73
- const snapshot = payload["snapshot"];
74
- const cycleId = payload["cycleId"];
75
- if (!isAnalysisSnapshot(snapshot) ||
76
- snapshot.importId !== payload["importId"] ||
77
- typeof cycleId !== "string" ||
78
- !/^[A-Za-z0-9_-]{1,128}$/.test(cycleId) ||
79
- typeof payload["reply"] !== "string")
80
- throw new Error("analysis-input-refused");
81
- let candidate;
82
- try {
83
- candidate = JSON.parse(payload["reply"]);
84
- }
85
- catch {
86
- throw new Error("analysis-invalid-json");
87
- }
88
- return { snapshot, cycleId, candidate };
89
- }
90
- async function save(settings, call) {
91
- const { snapshot, cycleId, candidate } = saveInput(call.payload);
92
- const validation = validateAnalysis(candidate, analysisEvidence(snapshot));
93
- if (!validation.accepted)
94
- return refused(validation.codes[0] ?? "analysis-input-refused", validation.codes);
95
- if (validation.result.openQuestion !== undefined)
96
- return refused("analysis-input-refused");
97
- try {
98
- const directory = await analysisDirectory(settings.runtimeDirectory, snapshot.importId);
99
- const output = {
100
- cycleId,
101
- analysis: JSON.stringify(validation.result) + "\n",
102
- proposal: analysisProposal(validation.result),
103
- };
104
- if (call.mode === "reconcile" &&
105
- (await inspectAnalysisFiles(directory, output)) === "absent")
106
- return { kind: "absent" };
107
- if (call.mode === "deliver")
108
- await saveAnalysisFiles(directory, output);
109
- }
110
- catch {
111
- throw new Error("analysis-output-failed");
112
- }
113
- return completed(call.intent, {
114
- kind: "handoff_requested",
115
- cycleId,
116
- promotionId: `analysis:${snapshot.importId}:${cycleId}`,
117
- });
118
- }
119
- const reasons = new Set([
120
- "analysis-too-large",
121
- "redaction-required",
122
- "invalid-import-id",
123
- "analysis-invalid-json",
124
- "analysis-input-refused",
125
- "analysis-output-failed",
126
- "unsupported-effect",
127
- "workflow-not-allowed",
128
- "payload-not-available",
129
- ]);
130
- async function delivered(settings, call) {
131
- const { intent, mode } = call;
132
- try {
133
- if (call.signal?.aborted)
134
- return { kind: "stopped" };
135
- const payload = await payloadOf(settings, intent);
136
- if (call.signal?.aborted)
137
- return { kind: "stopped" };
138
- if (intent.method === "read-analysis" && mode === "reconcile")
139
- return { kind: "absent" };
140
- if (intent.method === "read-analysis")
141
- return await read(settings, {
142
- intent,
143
- importId: String(payload["importId"]),
144
- });
145
- return await save(settings, { intent, payload, mode });
146
- }
147
- catch (error) {
148
- const message = String(Reflect.get(Object(error), "message"));
149
- return refused(reasons.has(message) ? message : "analysis-input-refused");
150
- }
151
- }
152
- export function chatsWorker(settings) {
153
- if (process.platform !== "darwin") {
154
- const unsupported = () => Promise.resolve(refused("platform-unsupported"));
155
- return {
156
- deliver: unsupported,
157
- reconcile: unsupported,
158
- stop: unsupported,
159
- close: () => Promise.resolve(),
160
- };
161
- }
162
- const active = new Map();
163
- const lifecycle = { closed: false };
164
- const deliver = (intent, signal) => {
165
- if (lifecycle.closed || signal.aborted)
166
- return Promise.resolve({ kind: "stopped" });
167
- const key = operationKey(JSON.stringify([intent.runId, intent.operationId, intent.inputDigest]));
168
- const known = active.get(key);
169
- if (known !== undefined)
170
- return known;
171
- const pending = delivered(settings, {
172
- intent,
173
- mode: "deliver",
174
- signal,
175
- }).finally(() => active.delete(key));
176
- active.set(key, pending);
177
- return pending;
178
- };
179
- const stop = async (intent) => {
180
- if (!ownIntent(intent))
181
- return refused("unsupported-effect");
182
- if ((await settings.workflowId(intent.runId)) !== "analyze-chats")
183
- return refused("workflow-not-allowed");
184
- const key = operationKey(JSON.stringify([intent.runId, intent.operationId, intent.inputDigest]));
185
- const pending = active.get(key);
186
- if (pending !== undefined)
187
- return await pending;
188
- const result = await delivered(settings, { intent, mode: "reconcile" });
189
- return result.kind === "absent" ? { kind: "stopped" } : result;
190
- };
191
- return {
192
- deliver,
193
- reconcile: (intent) => delivered(settings, { intent, mode: "reconcile" }),
194
- stop,
195
- close: async () => {
196
- lifecycle.closed = true;
197
- await Promise.all(active.values());
198
- },
199
- };
200
- }
@@ -1,10 +0,0 @@
1
- import type { CycleOutcome } from "cloving/workflows";
2
- interface AnalysisInput {
3
- readonly cycleId: string;
4
- readonly repository: string;
5
- readonly input: {
6
- readonly importId: string;
7
- };
8
- }
9
- export declare function analyzeChats(input: AnalysisInput): Promise<CycleOutcome>;
10
- export {};