cloving 0.3.20 → 1.1.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 (515) hide show
  1. package/{LICENSE.md → LICENSE} +1 -1
  2. package/README.md +606 -182
  3. package/dist/src/authority/budgets.d.ts +12 -0
  4. package/dist/src/authority/budgets.js +42 -0
  5. package/dist/src/authority/commands.d.ts +7 -0
  6. package/dist/src/authority/commands.js +271 -0
  7. package/dist/src/authority/details.d.ts +28 -0
  8. package/dist/src/authority/details.js +33 -0
  9. package/dist/src/authority/dispatch-decision.d.ts +40 -0
  10. package/dist/src/authority/dispatch-decision.js +47 -0
  11. package/dist/src/authority/effect-requests.d.ts +2 -0
  12. package/dist/src/authority/effect-requests.js +139 -0
  13. package/dist/src/authority/effect-results.d.ts +4 -0
  14. package/dist/src/authority/effect-results.js +236 -0
  15. package/dist/src/authority/events.d.ts +2 -0
  16. package/dist/src/authority/events.js +45 -0
  17. package/dist/src/authority/gate-reduction.d.ts +8 -0
  18. package/dist/src/authority/gate-reduction.js +109 -0
  19. package/dist/src/authority/gates.d.ts +48 -0
  20. package/dist/src/authority/gates.js +77 -0
  21. package/dist/src/authority/history-state.d.ts +15 -0
  22. package/dist/src/authority/history-state.js +61 -0
  23. package/dist/src/authority/history.d.ts +13 -0
  24. package/dist/src/authority/history.js +37 -0
  25. package/dist/src/authority/instants.d.ts +3 -0
  26. package/dist/src/authority/instants.js +38 -0
  27. package/dist/src/authority/leases.d.ts +15 -0
  28. package/dist/src/authority/leases.js +113 -0
  29. package/dist/src/authority/operations.d.ts +101 -0
  30. package/dist/src/authority/operations.js +75 -0
  31. package/dist/src/authority/reconciliation.d.ts +29 -0
  32. package/dist/src/authority/reconciliation.js +156 -0
  33. package/dist/src/authority/reducer.d.ts +41 -0
  34. package/dist/src/authority/reducer.js +139 -0
  35. package/dist/src/authority/reduction-state.d.ts +36 -0
  36. package/dist/src/authority/reduction-state.js +68 -0
  37. package/dist/src/authority/reduction.d.ts +6 -0
  38. package/dist/src/authority/reduction.js +160 -0
  39. package/dist/src/authority/status-closure.d.ts +4 -0
  40. package/dist/src/authority/status-closure.js +57 -0
  41. package/dist/src/authority/status-effects.d.ts +17 -0
  42. package/dist/src/authority/status-effects.js +43 -0
  43. package/dist/src/authority/status-input.d.ts +45 -0
  44. package/dist/src/authority/status-input.js +9 -0
  45. package/dist/src/authority/status.d.ts +32 -0
  46. package/dist/src/authority/status.js +256 -0
  47. package/dist/src/authority/stop-sequence.d.ts +37 -0
  48. package/dist/src/authority/stop-sequence.js +91 -0
  49. package/dist/src/authority/transitions.d.ts +63 -0
  50. package/dist/src/authority/transitions.js +124 -0
  51. package/dist/src/broker/actor/adapter-calls.d.ts +13 -0
  52. package/dist/src/broker/actor/adapter-calls.js +34 -0
  53. package/dist/src/broker/actor/adapter-outcomes.d.ts +28 -0
  54. package/dist/src/broker/actor/adapter-outcomes.js +80 -0
  55. package/dist/src/broker/actor/authority-actor.d.ts +25 -0
  56. package/dist/src/broker/actor/authority-actor.js +169 -0
  57. package/dist/src/broker/actor/authority-changes.d.ts +31 -0
  58. package/dist/src/broker/actor/authority-changes.js +46 -0
  59. package/dist/src/broker/actor/authority-connection.d.ts +15 -0
  60. package/dist/src/broker/actor/authority-connection.js +44 -0
  61. package/dist/src/broker/actor/authority-conversion.d.ts +10 -0
  62. package/dist/src/broker/actor/authority-conversion.js +72 -0
  63. package/dist/src/broker/actor/authority-delivery.d.ts +13 -0
  64. package/dist/src/broker/actor/authority-delivery.js +162 -0
  65. package/dist/src/broker/actor/authority-logger.d.ts +2 -0
  66. package/dist/src/broker/actor/authority-logger.js +19 -0
  67. package/dist/src/broker/actor/authority-policy.d.ts +9 -0
  68. package/dist/src/broker/actor/authority-policy.js +11 -0
  69. package/dist/src/broker/actor/authority-queries.d.ts +45 -0
  70. package/dist/src/broker/actor/authority-queries.js +85 -0
  71. package/dist/src/broker/actor/authority-receipts.d.ts +28 -0
  72. package/dist/src/broker/actor/authority-receipts.js +84 -0
  73. package/dist/src/broker/actor/authority-release.d.ts +13 -0
  74. package/dist/src/broker/actor/authority-release.js +69 -0
  75. package/dist/src/broker/actor/authority-runtime.d.ts +60 -0
  76. package/dist/src/broker/actor/authority-runtime.js +204 -0
  77. package/dist/src/broker/actor/authority-session.d.ts +67 -0
  78. package/dist/src/broker/actor/authority-session.js +251 -0
  79. package/dist/src/broker/actor/authority-settings.d.ts +33 -0
  80. package/dist/src/broker/actor/authority-settings.js +63 -0
  81. package/dist/src/broker/actor/authority-upgrades.d.ts +16 -0
  82. package/dist/src/broker/actor/authority-upgrades.js +12 -0
  83. package/dist/src/broker/actor/authority-watchdog.d.ts +14 -0
  84. package/dist/src/broker/actor/authority-watchdog.js +41 -0
  85. package/dist/src/broker/actor/authority.d.ts +14 -0
  86. package/dist/src/broker/actor/authority.js +115 -0
  87. package/dist/src/broker/actor/delivery-intents.d.ts +68 -0
  88. package/dist/src/broker/actor/delivery-intents.js +77 -0
  89. package/dist/src/broker/actor/delivery-plan.d.ts +2 -0
  90. package/dist/src/broker/actor/delivery-plan.js +109 -0
  91. package/dist/src/broker/actor/delivery-results.d.ts +11 -0
  92. package/dist/src/broker/actor/delivery-results.js +63 -0
  93. package/dist/src/broker/actor/effect-delivery.d.ts +19 -0
  94. package/dist/src/broker/actor/effect-delivery.js +118 -0
  95. package/dist/src/broker/actor/effect-plan.d.ts +41 -0
  96. package/dist/src/broker/actor/effect-plan.js +173 -0
  97. package/dist/src/broker/actor/effect-queries.d.ts +27 -0
  98. package/dist/src/broker/actor/effect-queries.js +80 -0
  99. package/dist/src/broker/actor/effect-turn.d.ts +25 -0
  100. package/dist/src/broker/actor/effect-turn.js +84 -0
  101. package/dist/src/broker/actor/pin-check.d.ts +6 -0
  102. package/dist/src/broker/actor/pin-check.js +12 -0
  103. package/dist/src/broker/actor/runtime-parts.d.ts +23 -0
  104. package/dist/src/broker/actor/runtime-parts.js +34 -0
  105. package/dist/src/broker/actor/stop-plan.d.ts +20 -0
  106. package/dist/src/broker/actor/stop-plan.js +46 -0
  107. package/dist/src/broker/actor/stop-turn.d.ts +17 -0
  108. package/dist/src/broker/actor/stop-turn.js +42 -0
  109. package/dist/src/broker/actor/turn-draft.d.ts +31 -0
  110. package/dist/src/broker/actor/turn-draft.js +138 -0
  111. package/dist/src/broker/actor/turn-plan.d.ts +17 -0
  112. package/dist/src/broker/actor/turn-plan.js +136 -0
  113. package/dist/src/broker/actor/turn-refusals.d.ts +8 -0
  114. package/dist/src/broker/actor/turn-refusals.js +35 -0
  115. package/dist/src/broker/actor/turn-staging.d.ts +78 -0
  116. package/dist/src/broker/actor/turn-staging.js +34 -0
  117. package/dist/src/broker/actor/turn-state.d.ts +34 -0
  118. package/dist/src/broker/actor/turn-state.js +208 -0
  119. package/dist/src/broker/authority-admission.d.ts +21 -0
  120. package/dist/src/broker/authority-admission.js +70 -0
  121. package/dist/src/broker/authority-restore.d.ts +30 -0
  122. package/dist/src/broker/authority-restore.js +165 -0
  123. package/dist/src/broker/decision-restore.d.ts +16 -0
  124. package/dist/src/broker/decision-restore.js +158 -0
  125. package/dist/src/broker/decision-upgrade.d.ts +3 -0
  126. package/dist/src/broker/decision-upgrade.js +12 -0
  127. package/dist/src/broker/effect-restore.d.ts +20 -0
  128. package/dist/src/broker/effect-restore.js +111 -0
  129. package/dist/src/broker/effect-upgrade.d.ts +3 -0
  130. package/dist/src/broker/effect-upgrade.js +9 -0
  131. package/dist/src/broker/operation-digest.d.ts +1 -0
  132. package/dist/src/broker/operation-digest.js +4 -0
  133. package/dist/src/broker/socket-address.d.ts +9 -0
  134. package/dist/src/broker/socket-address.js +14 -0
  135. package/dist/src/broker/workflow-pin.d.ts +2 -0
  136. package/dist/src/broker/workflow-pin.js +5 -0
  137. package/dist/src/chats/analysis-batches.d.ts +24 -0
  138. package/dist/src/chats/analysis-batches.js +83 -0
  139. package/dist/src/chats/analysis-contract.d.ts +80 -0
  140. package/dist/src/chats/analysis-contract.js +16 -0
  141. package/dist/src/chats/analysis-data.d.ts +3 -0
  142. package/dist/src/chats/analysis-data.js +85 -0
  143. package/dist/src/chats/analysis-input.d.ts +12 -0
  144. package/dist/src/chats/analysis-input.js +83 -0
  145. package/dist/src/chats/analysis-links.d.ts +2 -0
  146. package/dist/src/chats/analysis-links.js +25 -0
  147. package/dist/src/chats/analysis-prompt.d.ts +10 -0
  148. package/dist/src/chats/analysis-prompt.js +16 -0
  149. package/dist/src/chats/analysis-proposal.d.ts +2 -0
  150. package/dist/src/chats/analysis-proposal.js +32 -0
  151. package/dist/src/chats/analysis-provenance.d.ts +4 -0
  152. package/dist/src/chats/analysis-provenance.js +99 -0
  153. package/dist/src/chats/analysis-shape.d.ts +3 -0
  154. package/dist/src/chats/analysis-shape.js +228 -0
  155. package/dist/src/chats/analysis.d.ts +3 -0
  156. package/dist/src/chats/analysis.js +42 -0
  157. package/dist/src/chats/corpus-input.d.ts +5 -0
  158. package/dist/src/chats/corpus-input.js +288 -0
  159. package/dist/src/chats/destination.d.ts +4 -0
  160. package/dist/src/chats/destination.js +96 -0
  161. package/dist/src/chats/import.d.ts +15 -0
  162. package/dist/src/chats/import.js +243 -0
  163. package/dist/src/chats/input-file.d.ts +3 -0
  164. package/dist/src/chats/input-file.js +32 -0
  165. package/dist/src/chats/normalize.d.ts +29 -0
  166. package/dist/src/chats/normalize.js +155 -0
  167. package/dist/src/chats/previous-import.d.ts +5 -0
  168. package/dist/src/chats/previous-import.js +34 -0
  169. package/dist/src/chats/reader.d.ts +21 -0
  170. package/dist/src/chats/reader.js +118 -0
  171. package/dist/src/chats/redact-import.d.ts +14 -0
  172. package/dist/src/chats/redact-import.js +141 -0
  173. package/dist/src/chats/redaction.d.ts +41 -0
  174. package/dist/src/chats/redaction.js +161 -0
  175. package/dist/src/chats/revision-input.d.ts +3 -0
  176. package/dist/src/chats/revision-input.js +180 -0
  177. package/dist/src/chats/revision.d.ts +48 -0
  178. package/dist/src/chats/revision.js +94 -0
  179. package/dist/src/chats/selection.d.ts +25 -0
  180. package/dist/src/chats/selection.js +109 -0
  181. package/dist/src/chats/source.d.ts +23 -0
  182. package/dist/src/chats/source.js +135 -0
  183. package/dist/src/chats/structure.d.ts +57 -0
  184. package/dist/src/chats/structure.js +216 -0
  185. package/dist/src/cli/arguments.d.ts +31 -0
  186. package/dist/src/cli/arguments.js +235 -0
  187. package/dist/src/cli/client.d.ts +16 -0
  188. package/dist/src/cli/client.js +159 -0
  189. package/dist/src/cli/commands.d.ts +17 -0
  190. package/dist/src/cli/commands.js +271 -0
  191. package/dist/src/cli/main.d.ts +2 -0
  192. package/dist/src/cli/main.js +127 -0
  193. package/dist/src/cli/render.d.ts +10 -0
  194. package/dist/src/cli/render.js +254 -0
  195. package/dist/src/cli/runtime-arguments.d.ts +73 -0
  196. package/dist/src/cli/runtime-arguments.js +248 -0
  197. package/dist/src/cli/runtime-directory.d.ts +4 -0
  198. package/dist/src/cli/runtime-directory.js +25 -0
  199. package/dist/src/cli/toolchain.d.ts +3 -0
  200. package/dist/src/cli/toolchain.js +74 -0
  201. package/dist/src/cli/usage-render.d.ts +3 -0
  202. package/dist/src/cli/usage-render.js +28 -0
  203. package/dist/src/cli/usage.d.ts +5 -0
  204. package/dist/src/cli/usage.js +156 -0
  205. package/dist/src/cli/validate.d.ts +38 -0
  206. package/dist/src/cli/validate.js +116 -0
  207. package/dist/src/cli/watch-actions.d.ts +10 -0
  208. package/dist/src/cli/watch-actions.js +58 -0
  209. package/dist/src/cli/watch-board-view.d.ts +54 -0
  210. package/dist/src/cli/watch-board-view.js +201 -0
  211. package/dist/src/cli/watch-board.d.ts +15 -0
  212. package/dist/src/cli/watch-board.js +179 -0
  213. package/dist/src/cli/watch-card-client.d.ts +1 -0
  214. package/dist/src/cli/watch-card-client.js +44 -0
  215. package/dist/src/cli/watch-card-forms.d.ts +2 -0
  216. package/dist/src/cli/watch-card-forms.js +33 -0
  217. package/dist/src/cli/watch-card-reply.d.ts +5 -0
  218. package/dist/src/cli/watch-card-reply.js +34 -0
  219. package/dist/src/cli/watch-card-view.d.ts +40 -0
  220. package/dist/src/cli/watch-card-view.js +86 -0
  221. package/dist/src/cli/watch-client.d.ts +1 -0
  222. package/dist/src/cli/watch-client.js +118 -0
  223. package/dist/src/cli/watch-element.d.ts +11 -0
  224. package/dist/src/cli/watch-element.js +6 -0
  225. package/dist/src/cli/watch-model.d.ts +29 -0
  226. package/dist/src/cli/watch-model.js +278 -0
  227. package/dist/src/cli/watch-navigation.d.ts +9 -0
  228. package/dist/src/cli/watch-navigation.js +40 -0
  229. package/dist/src/cli/watch-page.d.ts +1 -0
  230. package/dist/src/cli/watch-page.js +258 -0
  231. package/dist/src/cli/watch-paths.d.ts +2 -0
  232. package/dist/src/cli/watch-paths.js +52 -0
  233. package/dist/src/cli/watch-phases.d.ts +7 -0
  234. package/dist/src/cli/watch-phases.js +148 -0
  235. package/dist/src/cli/watch-pr-board.d.ts +3 -0
  236. package/dist/src/cli/watch-pr-board.js +26 -0
  237. package/dist/src/cli/watch-pr-command.d.ts +15 -0
  238. package/dist/src/cli/watch-pr-command.js +37 -0
  239. package/dist/src/cli/watch-pr-identity.d.ts +20 -0
  240. package/dist/src/cli/watch-pr-identity.js +62 -0
  241. package/dist/src/cli/watch-pr-observer.d.ts +19 -0
  242. package/dist/src/cli/watch-pr-observer.js +108 -0
  243. package/dist/src/cli/watch-pr-settings.d.ts +8 -0
  244. package/dist/src/cli/watch-pr-settings.js +47 -0
  245. package/dist/src/cli/watch-reads.d.ts +28 -0
  246. package/dist/src/cli/watch-reads.js +248 -0
  247. package/dist/src/cli/watch-render.d.ts +153 -0
  248. package/dist/src/cli/watch-render.js +102 -0
  249. package/dist/src/cli/watch-run-input.d.ts +14 -0
  250. package/dist/src/cli/watch-run-input.js +49 -0
  251. package/dist/src/cli/watch-server.d.ts +13 -0
  252. package/dist/src/cli/watch-server.js +214 -0
  253. package/dist/src/cli/watch-start-view.d.ts +18 -0
  254. package/dist/src/cli/watch-start-view.js +77 -0
  255. package/dist/src/cli/watch-stream.d.ts +11 -0
  256. package/dist/src/cli/watch-stream.js +128 -0
  257. package/dist/src/cli/watch-turn.d.ts +30 -0
  258. package/dist/src/cli/watch-turn.js +135 -0
  259. package/dist/src/cli/watch-usage.d.ts +6 -0
  260. package/dist/src/cli/watch-usage.js +65 -0
  261. package/dist/src/cli/watch-view.d.ts +54 -0
  262. package/dist/src/cli/watch-view.js +267 -0
  263. package/dist/src/cli.d.ts +2 -0
  264. package/dist/src/cli.js +104 -0
  265. package/dist/src/daemon/analysis-launch.d.ts +5 -0
  266. package/dist/src/daemon/analysis-launch.js +81 -0
  267. package/dist/src/daemon/analysis-token.d.ts +6 -0
  268. package/dist/src/daemon/analysis-token.js +88 -0
  269. package/dist/src/daemon/analysis-worker.d.ts +22 -0
  270. package/dist/src/daemon/analysis-worker.js +219 -0
  271. package/dist/src/daemon/chats-files.d.ts +15 -0
  272. package/dist/src/daemon/chats-files.js +113 -0
  273. package/dist/src/daemon/chats-worker.d.ts +12 -0
  274. package/dist/src/daemon/chats-worker.js +200 -0
  275. package/dist/src/daemon/claude-turn.d.ts +38 -0
  276. package/dist/src/daemon/claude-turn.js +216 -0
  277. package/dist/src/daemon/claude-worker.d.ts +29 -0
  278. package/dist/src/daemon/claude-worker.js +276 -0
  279. package/dist/src/daemon/codex-stream.d.ts +4 -0
  280. package/dist/src/daemon/codex-stream.js +129 -0
  281. package/dist/src/daemon/daemon.d.ts +49 -0
  282. package/dist/src/daemon/daemon.js +195 -0
  283. package/dist/src/daemon/delivery-router.d.ts +10 -0
  284. package/dist/src/daemon/delivery-router.js +34 -0
  285. package/dist/src/daemon/github-calls.d.ts +29 -0
  286. package/dist/src/daemon/github-calls.js +127 -0
  287. package/dist/src/daemon/github-issue-methods.d.ts +3 -0
  288. package/dist/src/daemon/github-issue-methods.js +99 -0
  289. package/dist/src/daemon/github-issue-privacy.d.ts +6 -0
  290. package/dist/src/daemon/github-issue-privacy.js +131 -0
  291. package/dist/src/daemon/github-merge.d.ts +18 -0
  292. package/dist/src/daemon/github-merge.js +259 -0
  293. package/dist/src/daemon/github-methods.d.ts +5 -0
  294. package/dist/src/daemon/github-methods.js +202 -0
  295. package/dist/src/daemon/github-operation.d.ts +38 -0
  296. package/dist/src/daemon/github-operation.js +57 -0
  297. package/dist/src/daemon/github-ticket-status.d.ts +3 -0
  298. package/dist/src/daemon/github-ticket-status.js +268 -0
  299. package/dist/src/daemon/github-worker.d.ts +17 -0
  300. package/dist/src/daemon/github-worker.js +281 -0
  301. package/dist/src/daemon/host-environment.d.ts +8 -0
  302. package/dist/src/daemon/host-environment.js +14 -0
  303. package/dist/src/daemon/issue-queue.d.ts +10 -0
  304. package/dist/src/daemon/issue-queue.js +254 -0
  305. package/dist/src/daemon/notify-message.d.ts +14 -0
  306. package/dist/src/daemon/notify-message.js +48 -0
  307. package/dist/src/daemon/notify.d.ts +12 -0
  308. package/dist/src/daemon/notify.js +161 -0
  309. package/dist/src/daemon/operation-journal.d.ts +43 -0
  310. package/dist/src/daemon/operation-journal.js +55 -0
  311. package/dist/src/daemon/retrying-turn.d.ts +9 -0
  312. package/dist/src/daemon/retrying-turn.js +185 -0
  313. package/dist/src/daemon/ticket-registration.d.ts +33 -0
  314. package/dist/src/daemon/ticket-registration.js +177 -0
  315. package/dist/src/daemon/ticket-source.d.ts +17 -0
  316. package/dist/src/daemon/ticket-source.js +36 -0
  317. package/dist/src/daemon/work-tree.d.ts +26 -0
  318. package/dist/src/daemon/work-tree.js +206 -0
  319. package/dist/src/effect-authorization.d.ts +21 -0
  320. package/dist/src/effect-authorization.js +14 -0
  321. package/dist/src/execution-pin.d.ts +4 -0
  322. package/dist/src/execution-pin.js +68 -0
  323. package/dist/src/host/start-delivery.d.ts +41 -0
  324. package/dist/src/host/start-delivery.js +68 -0
  325. package/dist/src/host/step-bridge-host.d.ts +79 -0
  326. package/dist/src/host/step-bridge-host.js +205 -0
  327. package/dist/src/host/step-claims.d.ts +31 -0
  328. package/dist/src/host/step-claims.js +85 -0
  329. package/dist/src/host/world-host.d.ts +21 -0
  330. package/dist/src/host/world-host.js +51 -0
  331. package/dist/src/host/world-reconciliation.d.ts +39 -0
  332. package/dist/src/host/world-reconciliation.js +81 -0
  333. package/dist/src/host/world-runs.d.ts +14 -0
  334. package/dist/src/host/world-runs.js +69 -0
  335. package/dist/src/operation-identity.d.ts +7 -0
  336. package/dist/src/operation-identity.js +59 -0
  337. package/dist/src/protocol.d.ts +35 -0
  338. package/dist/src/protocol.js +64 -0
  339. package/dist/src/resource-files.d.ts +1 -0
  340. package/dist/src/resource-files.js +29 -0
  341. package/dist/src/service/changes.d.ts +11 -0
  342. package/dist/src/service/changes.js +32 -0
  343. package/dist/src/service/decision-handler.d.ts +9 -0
  344. package/dist/src/service/decision-handler.js +233 -0
  345. package/dist/src/service/event-handler.d.ts +10 -0
  346. package/dist/src/service/event-handler.js +70 -0
  347. package/dist/src/service/expiry.d.ts +13 -0
  348. package/dist/src/service/expiry.js +53 -0
  349. package/dist/src/service/gateway.d.ts +21 -0
  350. package/dist/src/service/gateway.js +120 -0
  351. package/dist/src/service/registry.d.ts +40 -0
  352. package/dist/src/service/registry.js +13 -0
  353. package/dist/src/service/replies.d.ts +26 -0
  354. package/dist/src/service/replies.js +56 -0
  355. package/dist/src/service/run-handlers.d.ts +4 -0
  356. package/dist/src/service/run-handlers.js +263 -0
  357. package/dist/src/service/service.d.ts +58 -0
  358. package/dist/src/service/service.js +212 -0
  359. package/dist/src/service/submission-handler.d.ts +4 -0
  360. package/dist/src/service/submission-handler.js +206 -0
  361. package/dist/src/service/transport.d.ts +16 -0
  362. package/dist/src/service/transport.js +141 -0
  363. package/dist/src/service/worker-port.d.ts +85 -0
  364. package/dist/src/service/worker-port.js +126 -0
  365. package/dist/src/service/worker-totals.d.ts +3 -0
  366. package/dist/src/service/worker-totals.js +28 -0
  367. package/dist/src/step-bridge.d.ts +57 -0
  368. package/dist/src/step-bridge.js +4 -0
  369. package/dist/src/steps/decision-gate.d.ts +2 -0
  370. package/dist/src/steps/decision-gate.js +8 -0
  371. package/dist/src/steps/load-cycle.d.ts +10 -0
  372. package/dist/src/steps/load-cycle.js +11 -0
  373. package/dist/src/steps/protected-effect.d.ts +2 -0
  374. package/dist/src/steps/protected-effect.js +8 -0
  375. package/dist/src/storage/decision-rows.d.ts +54 -0
  376. package/dist/src/storage/decision-rows.js +72 -0
  377. package/dist/src/storage/decision-snapshots.d.ts +17 -0
  378. package/dist/src/storage/decision-snapshots.js +25 -0
  379. package/dist/src/storage/domain-changes.d.ts +48 -0
  380. package/dist/src/storage/domain-changes.js +213 -0
  381. package/dist/src/storage/domain-rows.d.ts +85 -0
  382. package/dist/src/storage/domain-rows.js +129 -0
  383. package/dist/src/storage/domain-schema.d.ts +32 -0
  384. package/dist/src/storage/domain-schema.js +193 -0
  385. package/dist/src/storage/effect-changes.d.ts +5 -0
  386. package/dist/src/storage/effect-changes.js +105 -0
  387. package/dist/src/storage/effect-rows.d.ts +67 -0
  388. package/dist/src/storage/effect-rows.js +74 -0
  389. package/dist/src/storage/effect-schema.d.ts +1 -0
  390. package/dist/src/storage/effect-schema.js +59 -0
  391. package/dist/src/storage/statements.d.ts +9 -0
  392. package/dist/src/storage/statements.js +8 -0
  393. package/dist/src/submission.d.ts +42 -0
  394. package/dist/src/submission.js +71 -0
  395. package/dist/src/ticket-status.d.ts +8 -0
  396. package/dist/src/ticket-status.js +45 -0
  397. package/dist/src/token-prices.d.ts +19 -0
  398. package/dist/src/token-prices.js +76 -0
  399. package/dist/src/turn-profile.d.ts +13 -0
  400. package/dist/src/turn-profile.js +100 -0
  401. package/dist/src/worker-usage.d.ts +22 -0
  402. package/dist/src/worker-usage.js +44 -0
  403. package/dist/src/workflow-admission.d.ts +45 -0
  404. package/dist/src/workflow-admission.js +151 -0
  405. package/dist/src/workflow-candidate.d.ts +29 -0
  406. package/dist/src/workflow-candidate.js +59 -0
  407. package/dist/src/workflow-contracts.d.ts +29 -0
  408. package/dist/src/workflow-contracts.js +110 -0
  409. package/dist/src/workflow-declaration.d.ts +11 -0
  410. package/dist/src/workflow-declaration.js +59 -0
  411. package/dist/src/workflow-resources.d.ts +8 -0
  412. package/dist/src/workflow-resources.js +14 -0
  413. package/dist/src/workflows.d.ts +6 -0
  414. package/dist/src/workflows.js +4 -0
  415. package/dist/tools/compile-workflows.d.ts +1 -0
  416. package/dist/tools/compile-workflows.js +33 -0
  417. package/dist/tools/self-host-processes.d.ts +10 -0
  418. package/dist/tools/self-host-processes.js +156 -0
  419. package/dist/tools/self-host-workflows.d.ts +15 -0
  420. package/dist/tools/self-host-workflows.js +78 -0
  421. package/dist/tools/self-host.d.ts +1 -0
  422. package/dist/tools/self-host.js +261 -0
  423. package/dist/tools/self-update-host.d.ts +13 -0
  424. package/dist/tools/self-update-host.js +88 -0
  425. package/dist/tools/self-update.d.ts +11 -0
  426. package/dist/tools/self-update.js +177 -0
  427. package/dist/tools/workflow-manifest.d.ts +3 -0
  428. package/dist/tools/workflow-manifest.js +34 -0
  429. package/dist/workflows/analyze-chats.d.ts +10 -0
  430. package/dist/workflows/analyze-chats.declaration.json +9 -0
  431. package/dist/workflows/analyze-chats.js +73 -0
  432. package/dist/workflows/develop-prd.d.ts +7 -0
  433. package/dist/workflows/develop-prd.js +97 -0
  434. package/dist/workflows/develop-ticket.d.ts +9 -0
  435. package/dist/workflows/develop-ticket.js +202 -0
  436. package/dist/workflows/issue-labels.d.ts +16 -0
  437. package/dist/workflows/issue-labels.js +70 -0
  438. package/dist/workflows/ticket-prompts.d.ts +35 -0
  439. package/dist/workflows/ticket-prompts.js +133 -0
  440. package/package.json +84 -75
  441. package/dist/abstract_gpt/index.js +0 -55
  442. package/dist/cloving_gpt/adapters/Adapter.js +0 -2
  443. package/dist/cloving_gpt/adapters/azureopenai.js +0 -69
  444. package/dist/cloving_gpt/adapters/claude.js +0 -128
  445. package/dist/cloving_gpt/adapters/gemini.js +0 -135
  446. package/dist/cloving_gpt/adapters/gpt4all.js +0 -29
  447. package/dist/cloving_gpt/adapters/index.js +0 -2
  448. package/dist/cloving_gpt/adapters/mistral.js +0 -128
  449. package/dist/cloving_gpt/adapters/ollama.js +0 -128
  450. package/dist/cloving_gpt/adapters/openai.js +0 -100
  451. package/dist/cloving_gpt/index.js +0 -192
  452. package/dist/commands/analyze.js +0 -47
  453. package/dist/commands/chat.js +0 -14
  454. package/dist/commands/check.js +0 -7
  455. package/dist/commands/commit.js +0 -44
  456. package/dist/commands/config.js +0 -167
  457. package/dist/commands/describe.js +0 -235
  458. package/dist/commands/generate/code.js +0 -21
  459. package/dist/commands/generate/commit.js +0 -11
  460. package/dist/commands/generate/context.js +0 -82
  461. package/dist/commands/generate/docs.js +0 -11
  462. package/dist/commands/generate/documentation.js +0 -11
  463. package/dist/commands/generate/fizzbuzz.js +0 -35
  464. package/dist/commands/generate/init.js +0 -15
  465. package/dist/commands/generate/review.js +0 -11
  466. package/dist/commands/generate/sh.js +0 -95
  467. package/dist/commands/generate/shell.js +0 -11
  468. package/dist/commands/generate/unit_tests.js +0 -11
  469. package/dist/commands/init.js +0 -13
  470. package/dist/commands/models.js +0 -22
  471. package/dist/commands/project/build.js +0 -88
  472. package/dist/commands/project/complete.js +0 -12
  473. package/dist/commands/project/init.js +0 -82
  474. package/dist/commands/project/plan.js +0 -108
  475. package/dist/commands/proxy.js +0 -11
  476. package/dist/commands/review.js +0 -50
  477. package/dist/commands/tokens.js +0 -75
  478. package/dist/commands/unit_tests.js +0 -150
  479. package/dist/commands/update.js +0 -7
  480. package/dist/file2.js +0 -4
  481. package/dist/index.js +0 -136
  482. package/dist/managers/BlockManager.js +0 -120
  483. package/dist/managers/ChatManager.js +0 -653
  484. package/dist/managers/ChunkManager.js +0 -32
  485. package/dist/managers/CodeManager.js +0 -185
  486. package/dist/managers/CommitManager.js +0 -78
  487. package/dist/managers/DocsManager.js +0 -88
  488. package/dist/managers/DocumentationManager.js +0 -114
  489. package/dist/managers/InitManager.js +0 -230
  490. package/dist/managers/ProxyManager.js +0 -210
  491. package/dist/managers/ReviewManager.js +0 -131
  492. package/dist/managers/ShellManager.js +0 -163
  493. package/dist/managers/StreamManager.js +0 -308
  494. package/dist/managers/UnitTestManager.js +0 -243
  495. package/dist/managers/src/managers/ProxyManager.js +0 -1
  496. package/dist/newfile.js +0 -2
  497. package/dist/package.json +0 -86
  498. package/dist/utils/command_utils.js +0 -384
  499. package/dist/utils/config_utils.js +0 -249
  500. package/dist/utils/gitUtils.js +0 -42
  501. package/dist/utils/git_utils.js +0 -217
  502. package/dist/utils/modelUtils.js +0 -7
  503. package/dist/utils/model_utils.js +0 -7
  504. package/dist/utils/prompt_utils.js +0 -333
  505. package/dist/utils/prompts/CODEGEN_COULDNT_APPLY.md +0 -5
  506. package/dist/utils/prompts/CODEGEN_EXAMPLES.md +0 -82
  507. package/dist/utils/prompts/CODEGEN_INSTRUCTIONS.md +0 -43
  508. package/dist/utils/prompts/DOCS_INSTRUCTIONS.md +0 -9
  509. package/dist/utils/prompts/INIT_INSTRUCTIONS.md +0 -132
  510. package/dist/utils/prompts/REVIEW_INSTRUCTIONS.md +0 -49
  511. package/dist/utils/prompts/SHELL_INSTRUCTIONS.md +0 -15
  512. package/dist/utils/prompts/SPECIAL_FILES.md +0 -66
  513. package/dist/utils/prompts/index.js +0 -27
  514. package/dist/utils/string_utils.js +0 -505
  515. package/dist/utils/types.js +0 -2
@@ -0,0 +1,254 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFile, rename, rm, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { setTimeout as delay } from "node:timers/promises";
5
+ import { send } from "../cli/client.js";
6
+ import { record } from "../protocol.js";
7
+ import { runIdentity } from "../service/submission-handler.js";
8
+ function savedHold(value) {
9
+ if (value === undefined)
10
+ return undefined;
11
+ const held = record(value);
12
+ if (typeof held?.["mark"] !== "string" ||
13
+ typeof held["startedAt"] !== "number" ||
14
+ !Number.isFinite(held["startedAt"]) ||
15
+ held["startedAt"] <= 0)
16
+ throw new Error("invalid-queue-commands");
17
+ return { mark: held["mark"], startedAt: held["startedAt"] };
18
+ }
19
+ function identifiers(value) {
20
+ if (!Array.isArray(value) ||
21
+ !value.every((id) => typeof id === "string" && id.length > 0))
22
+ throw new Error("invalid-queue-commands");
23
+ return value.map(String);
24
+ }
25
+ async function journal(directory) {
26
+ const file = join(directory, "queue-commands.json");
27
+ const text = await readFile(file, "utf8").catch((error) => {
28
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
29
+ return "[]";
30
+ throw error;
31
+ });
32
+ const value = JSON.parse(text);
33
+ const saved = record(value);
34
+ const commands = new Set(identifiers(Array.isArray(value) ? value : saved?.["commands"]));
35
+ const failures = Array.isArray(value) ? [] : identifiers(saved?.["failures"]);
36
+ if (failures.length > 3)
37
+ throw new Error("invalid-queue-commands");
38
+ const pending = {
39
+ commands,
40
+ failures,
41
+ retryCommandId: undefined,
42
+ selfUpdateHold: savedHold(saved?.["selfUpdateHold"]),
43
+ save: async () => {
44
+ await writeFile(`${file}.tmp`, JSON.stringify({
45
+ commands: [...commands],
46
+ failures,
47
+ selfUpdateHold: pending.selfUpdateHold,
48
+ }) + "\n", { mode: 0o600, flush: true });
49
+ await rename(`${file}.tmp`, file);
50
+ },
51
+ };
52
+ return pending;
53
+ }
54
+ function terminal(run) {
55
+ return ["completed", "failed", "cancelled"].includes(String(run["state"]));
56
+ }
57
+ async function runStatus(runtimeDirectory, commandId) {
58
+ const reply = await send(runtimeDirectory, {
59
+ operation: "status",
60
+ parameters: { runId: runIdentity(commandId) },
61
+ });
62
+ if (reply.kind === "error" && reply.error.code === "unknown-run")
63
+ return undefined;
64
+ if (reply.kind === "error")
65
+ throw new Error(reply.error.code);
66
+ const run = record(reply.result["run"]);
67
+ if (run === undefined)
68
+ throw new Error("invalid-run-status");
69
+ return run;
70
+ }
71
+ async function recover(settings, pending) {
72
+ for (const commandId of pending.commands) {
73
+ if (await runStatus(settings.runtimeDirectory, commandId))
74
+ continue;
75
+ pending.commands.delete(commandId);
76
+ await pending.save();
77
+ }
78
+ }
79
+ function handedOff(run) {
80
+ const outcome = record(run["outcome"]);
81
+ return (run["state"] === "completed" &&
82
+ outcome?.["kind"] === "handoff_requested" &&
83
+ outcome["issueUpdate"] !== "failed");
84
+ }
85
+ class QueueFailureLimit extends Error {
86
+ }
87
+ function checkFailureLimit(pending) {
88
+ if (pending.failures.length >= 3)
89
+ throw new QueueFailureLimit(`3 runs in a row ended without handoff: ${pending.failures.join(", ")}`);
90
+ }
91
+ async function completed(settings, pending) {
92
+ checkFailureLimit(pending);
93
+ let pendingRun = false;
94
+ const tracked = [...pending.commands].filter((commandId) => commandId !== pending.retryCommandId);
95
+ for (const commandId of tracked) {
96
+ const run = await runStatus(settings.runtimeDirectory, commandId);
97
+ if (run === undefined)
98
+ throw new Error("queue-run-missing");
99
+ if (!terminal(run)) {
100
+ pendingRun = true;
101
+ continue;
102
+ }
103
+ pending.commands.delete(commandId);
104
+ if (handedOff(run))
105
+ pending.failures.length = 0;
106
+ else
107
+ pending.failures.push(runIdentity(commandId));
108
+ await pending.save();
109
+ checkFailureLimit(pending);
110
+ if (!handedOff(run)) {
111
+ const outcome = record(run["outcome"]);
112
+ process.stderr.write(`Queue run ended ${String(outcome?.["kind"] ?? run["state"])}${outcome?.["issueUpdate"] === "failed" ? "; issueUpdate: failed" : ""}: ${runIdentity(commandId)}; continuing\n`);
113
+ }
114
+ }
115
+ return pendingRun;
116
+ }
117
+ async function active(runtimeDirectory) {
118
+ let after = "";
119
+ do {
120
+ const reply = await send(runtimeDirectory, {
121
+ operation: "status",
122
+ parameters: { after, limit: 500 },
123
+ });
124
+ if (reply.kind === "error")
125
+ throw new Error(reply.error.code);
126
+ const runs = reply.result["runs"];
127
+ if (!Array.isArray(runs))
128
+ throw new Error("invalid-run-list");
129
+ if (runs.some((value) => {
130
+ const run = record(value);
131
+ return run?.["workflowId"] === "develop-issue" && !terminal(run);
132
+ }))
133
+ return true;
134
+ const next = reply.result["next"];
135
+ if (next !== null && (typeof next !== "string" || next <= after))
136
+ throw new Error("invalid-run-page");
137
+ after = next;
138
+ } while (after !== null);
139
+ return false;
140
+ }
141
+ async function submit(settings, pending) {
142
+ const commandId = pending.retryCommandId ?? randomUUID();
143
+ pending.commands.add(commandId);
144
+ await pending.save();
145
+ const reply = await send(settings.runtimeDirectory, {
146
+ operation: "run",
147
+ parameters: {
148
+ workflowId: "develop-issue",
149
+ source: "ticket",
150
+ submission: { ticket: "next" },
151
+ commandId,
152
+ },
153
+ });
154
+ pending.retryCommandId = undefined;
155
+ if (reply.kind === "result")
156
+ return;
157
+ if ([
158
+ "resolver-timeout",
159
+ "next-ticket-not-available",
160
+ "ticket-not-available",
161
+ ].includes(reply.error.code)) {
162
+ pending.retryCommandId = commandId;
163
+ process.stderr.write(`Queue ${reply.error.code}: command ${commandId}; will retry\n`);
164
+ return;
165
+ }
166
+ if (!["no-ready-ticket", "workflow-active"].includes(reply.error.code))
167
+ throw new Error(reply.error.code);
168
+ pending.commands.delete(commandId);
169
+ await pending.save();
170
+ }
171
+ function updateHold(directory, pending) {
172
+ let notice;
173
+ return async () => {
174
+ const mark = await readFile(join(directory, "pending-self-update"), "utf8").catch((error) => {
175
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
176
+ return undefined;
177
+ throw error;
178
+ });
179
+ if (mark === undefined && pending.selfUpdateHold !== undefined) {
180
+ pending.selfUpdateHold = undefined;
181
+ await pending.save();
182
+ }
183
+ if (mark === undefined) {
184
+ notice = undefined;
185
+ return false;
186
+ }
187
+ const timestamp = Number(mark);
188
+ if (!Number.isFinite(timestamp) || timestamp <= 0)
189
+ throw new Error("invalid-pending-self-update");
190
+ if (pending.selfUpdateHold?.mark !== mark) {
191
+ pending.selfUpdateHold = { mark, startedAt: Date.now() };
192
+ await pending.save();
193
+ }
194
+ const holding = Date.now() - pending.selfUpdateHold.startedAt < 30 * 60 * 1000;
195
+ const line = holding
196
+ ? "Queue holding for pending self-update\n"
197
+ : "Queue continuing after pending self-update time limit\n";
198
+ const key = mark + line;
199
+ if (notice !== key)
200
+ process.stderr.write(line);
201
+ notice = key;
202
+ return holding;
203
+ };
204
+ }
205
+ async function admission(settings, attempt) {
206
+ const file = join(settings.directory, "queue-submission");
207
+ await writeFile(file, "", { mode: 0o600 });
208
+ try {
209
+ if (!(await attempt.holding()) && !attempt.signal.aborted)
210
+ await submit(settings, attempt.pending);
211
+ }
212
+ finally {
213
+ await rm(file, { force: true });
214
+ }
215
+ }
216
+ async function cycle(settings, signal) {
217
+ const pending = await journal(settings.directory);
218
+ if (settings.resetQueue === true) {
219
+ pending.failures.length = 0;
220
+ await pending.save();
221
+ }
222
+ const holding = updateHold(settings.directory, pending);
223
+ await rm(join(settings.directory, "queue-submission"), { force: true });
224
+ await recover(settings, pending);
225
+ const stopped = () => signal.aborted;
226
+ while (!stopped()) {
227
+ await delay(settings.intervalMilliseconds, undefined, { signal }).catch(() => undefined);
228
+ if (stopped())
229
+ return;
230
+ if (await completed(settings, pending))
231
+ continue;
232
+ if (await active(settings.runtimeDirectory))
233
+ continue;
234
+ if (await holding())
235
+ continue;
236
+ if (stopped())
237
+ return;
238
+ await admission(settings, { pending, holding, signal });
239
+ }
240
+ }
241
+ export function issueQueue(settings) {
242
+ const stopping = new AbortController();
243
+ const running = cycle(settings, stopping.signal).catch((error) => {
244
+ const reason = error instanceof Error ? error.message : String(error);
245
+ const diagnostic = error instanceof QueueFailureLimit ? reason : JSON.stringify(reason);
246
+ process.stderr.write(`Queue stopped: ${diagnostic}\n`);
247
+ });
248
+ return {
249
+ stop: async () => {
250
+ stopping.abort();
251
+ await running;
252
+ },
253
+ };
254
+ }
@@ -0,0 +1,14 @@
1
+ import { type Fields } from "../protocol.ts";
2
+ export interface Notification {
3
+ readonly event: "decision" | "blocked" | "failed";
4
+ readonly runId: string;
5
+ readonly workflowId: string;
6
+ readonly subject: string;
7
+ readonly body: string;
8
+ }
9
+ export interface NotifyEvent {
10
+ readonly key: string;
11
+ readonly message: Notification;
12
+ }
13
+ export declare function decisionNotification(run: Fields, decision: Fields): NotifyEvent;
14
+ export declare function outcomeNotification(run: Fields): NotifyEvent | undefined;
@@ -0,0 +1,48 @@
1
+ import { decisionLines, runStatus } from "../cli/render.js";
2
+ import { record } from "../protocol.js";
3
+ function body(text, commands) {
4
+ const tail = commands.join("\n");
5
+ const available = 4000 - tail.length - 1;
6
+ const shortened = text.length <= available ? text : `${text.slice(0, available - 1)}…`;
7
+ return `${shortened}\n${tail}`;
8
+ }
9
+ function message(run, content) {
10
+ const workflowId = String(run["workflowId"]);
11
+ const action = content.event === "decision" ? "waits for your decision" : content.event;
12
+ return {
13
+ ...content,
14
+ runId: String(run["runId"]),
15
+ workflowId,
16
+ subject: `Cloving: ${workflowId} ${action}`.replace(/[\r\n]/g, " "),
17
+ };
18
+ }
19
+ export function decisionNotification(run, decision) {
20
+ const lines = decisionLines(decision);
21
+ const allowed = decision["allowed"];
22
+ const count = Array.isArray(allowed) ? allowed.length : 0;
23
+ const split = lines.length - count;
24
+ return {
25
+ key: `decision:${String(decision["decisionId"])}`,
26
+ message: message(run, {
27
+ event: "decision",
28
+ body: body(lines.slice(0, split).join("\n"), lines.slice(split)),
29
+ }),
30
+ };
31
+ }
32
+ export function outcomeNotification(run) {
33
+ const outcome = record(run["outcome"]);
34
+ const blocked = run["state"] === "completed" && outcome?.["kind"] === "blocked";
35
+ if (!blocked && run["state"] !== "failed")
36
+ return undefined;
37
+ const event = blocked ? "blocked" : "failed";
38
+ const lines = runStatus({ run });
39
+ return {
40
+ key: `${event}:${String(run["runId"])}`,
41
+ message: message(run, {
42
+ event,
43
+ body: body(String(lines[blocked ? 3 : 5]), [
44
+ `cloving status ${String(run["runId"])}`,
45
+ ]),
46
+ }),
47
+ };
48
+ }
@@ -0,0 +1,12 @@
1
+ import { type Notification } from "./notify-message.ts";
2
+ interface NotifySettings {
3
+ readonly directory: string;
4
+ readonly runtimeDirectory: string;
5
+ readonly command: readonly string[];
6
+ readonly intervalMilliseconds?: number;
7
+ }
8
+ export declare function notifyCommand(command: readonly string[], notification: Notification): Promise<void>;
9
+ export declare function notifyRuns(settings: NotifySettings): Promise<{
10
+ readonly stop: () => Promise<void>;
11
+ }>;
12
+ export {};
@@ -0,0 +1,161 @@
1
+ import { spawn } from "node:child_process";
2
+ import { readFile, rename, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { send } from "../cli/client.js";
5
+ import { record } from "../protocol.js";
6
+ import { decisionNotification, outcomeNotification, } from "./notify-message.js";
7
+ async function request(runtimeDirectory, request) {
8
+ const reply = await send(runtimeDirectory, request);
9
+ if (reply.kind === "error")
10
+ throw new Error(reply.error.code);
11
+ return reply.result;
12
+ }
13
+ function rows(value) {
14
+ if (!Array.isArray(value))
15
+ throw new Error("invalid-notify-list");
16
+ return value.map((item) => {
17
+ const row = record(item);
18
+ if (row === undefined)
19
+ throw new Error("invalid-notify-row");
20
+ return row;
21
+ });
22
+ }
23
+ async function observedOutcome(summary, source) {
24
+ const { runtimeDirectory, cache } = source;
25
+ const latestSequence = summary["latestSequence"];
26
+ if (typeof latestSequence !== "number")
27
+ throw new Error("invalid-notify-sequence");
28
+ const runId = String(summary["runId"]);
29
+ const previous = cache.get(runId);
30
+ if (previous !== undefined && previous.latestSequence === latestSequence)
31
+ return previous.event;
32
+ const status = await request(runtimeDirectory, {
33
+ operation: "status",
34
+ parameters: { runId },
35
+ });
36
+ const run = record(status["run"]);
37
+ if (run === undefined)
38
+ throw new Error("invalid-notify-status");
39
+ const event = outcomeNotification(run);
40
+ cache.set(runId, { latestSequence, event });
41
+ return event;
42
+ }
43
+ async function events(runtimeDirectory, cache) {
44
+ const found = [];
45
+ const runs = new Map();
46
+ let after = "";
47
+ do {
48
+ const page = await request(runtimeDirectory, {
49
+ operation: "status",
50
+ parameters: { after, limit: 500 },
51
+ });
52
+ for (const summary of rows(page["runs"])) {
53
+ runs.set(String(summary["runId"]), summary);
54
+ const outcome = await observedOutcome(summary, {
55
+ runtimeDirectory,
56
+ cache,
57
+ });
58
+ if (outcome !== undefined)
59
+ found.push(outcome);
60
+ }
61
+ const next = page["next"];
62
+ if (next !== null && (typeof next !== "string" || next <= after))
63
+ throw new Error("invalid-notify-page");
64
+ after = next;
65
+ } while (after !== null);
66
+ const questions = await request(runtimeDirectory, {
67
+ operation: "questions",
68
+ parameters: {},
69
+ });
70
+ for (const decision of rows(questions["decisions"])) {
71
+ const run = runs.get(String(decision["runId"]));
72
+ if (run !== undefined)
73
+ found.push(decisionNotification(run, decision));
74
+ }
75
+ return found;
76
+ }
77
+ async function recorded(file) {
78
+ const text = await readFile(file, "utf8").catch((error) => {
79
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
80
+ return undefined;
81
+ throw error;
82
+ });
83
+ if (text === undefined)
84
+ return undefined;
85
+ const value = JSON.parse(text);
86
+ if (!Array.isArray(value) || !value.every((key) => typeof key === "string"))
87
+ throw new Error("invalid-notify-record");
88
+ return new Set(value.map(String));
89
+ }
90
+ async function save(file, keys) {
91
+ await writeFile(`${file}.tmp`, JSON.stringify([...keys]) + "\n", {
92
+ mode: 0o600,
93
+ flush: true,
94
+ });
95
+ await rename(`${file}.tmp`, file);
96
+ }
97
+ export function notifyCommand(command, notification) {
98
+ return new Promise((resolve, reject) => {
99
+ const [executable = "", ...argumentsList] = command;
100
+ const child = spawn(executable, argumentsList, {
101
+ stdio: ["pipe", "ignore", "ignore"],
102
+ timeout: 30_000,
103
+ killSignal: "SIGKILL",
104
+ });
105
+ child.once("error", reject);
106
+ child.stdin.on("error", reject);
107
+ child.once("close", (code, signal) => {
108
+ if (code === 0)
109
+ resolve();
110
+ else
111
+ reject(new Error(signal === null ? `exit code ${String(code)}` : `signal ${signal}`));
112
+ });
113
+ child.stdin.end(JSON.stringify(notification) + "\n");
114
+ });
115
+ }
116
+ function report(label, error) {
117
+ const reason = error instanceof Error ? error.message : String(error);
118
+ process.stderr.write(`${label}: ${JSON.stringify(reason)}\n`);
119
+ }
120
+ async function check(settings, journal) {
121
+ for (const event of await events(settings.runtimeDirectory, journal.cache)) {
122
+ if (journal.keys.has(event.key))
123
+ continue;
124
+ await save(journal.file, new Set([...journal.keys, event.key]));
125
+ journal.keys.add(event.key);
126
+ await notifyCommand(settings.command, event.message).catch((error) => {
127
+ report("Notify command failed", error);
128
+ });
129
+ }
130
+ }
131
+ export async function notifyRuns(settings) {
132
+ const file = join(settings.directory, "notify-events.json");
133
+ const keys = await recorded(file);
134
+ const cache = new Map();
135
+ const journal = { file, keys: keys ?? new Set(), cache };
136
+ if (keys === undefined) {
137
+ for (const event of await events(settings.runtimeDirectory, cache))
138
+ journal.keys.add(event.key);
139
+ await save(file, journal.keys);
140
+ }
141
+ let busy = false;
142
+ let running = Promise.resolve();
143
+ const timer = setInterval(() => {
144
+ if (busy)
145
+ return;
146
+ busy = true;
147
+ running = check(settings, journal)
148
+ .catch((error) => {
149
+ report("Notify check failed", error);
150
+ })
151
+ .finally(() => {
152
+ busy = false;
153
+ });
154
+ }, settings.intervalMilliseconds ?? 15_000);
155
+ return {
156
+ stop: async () => {
157
+ clearInterval(timer);
158
+ await running;
159
+ },
160
+ };
161
+ }
@@ -0,0 +1,43 @@
1
+ import type { AdapterOutcome, ProtectedIntent } from "../broker/actor/delivery-intents.ts";
2
+ export interface WorkerReport {
3
+ readonly runId: string;
4
+ readonly commandId: string;
5
+ readonly operationId: string;
6
+ readonly inputDigest: string;
7
+ readonly leaseGeneration: number;
8
+ readonly worker: string;
9
+ readonly outcome: "completed" | "failed" | "stopped";
10
+ readonly result?: string;
11
+ readonly reason?: string;
12
+ }
13
+ export interface Recorded {
14
+ readonly outcome: WorkerReport["outcome"];
15
+ readonly result?: string;
16
+ readonly reason?: string;
17
+ readonly detail?: string;
18
+ readonly endedAt: string;
19
+ }
20
+ export interface Located {
21
+ readonly key: string;
22
+ readonly folder: string;
23
+ }
24
+ export type Reported = Pick<ProtectedIntent, "runId" | "operationId" | "inputDigest" | "leaseGeneration">;
25
+ export interface Identity {
26
+ readonly receipt: string;
27
+ readonly worker: string;
28
+ }
29
+ export declare function operationKey(text: string): string;
30
+ export declare function located(journal: string, operationId: string): Located;
31
+ export declare function readRecord(folder: string, name: string): Promise<unknown>;
32
+ export declare function writeRecord(folder: string, record: {
33
+ readonly name: string;
34
+ readonly value: unknown;
35
+ readonly permissions?: "private";
36
+ }): Promise<void>;
37
+ export declare function replied(identity: Identity, recorded: unknown): AdapterOutcome;
38
+ export declare function interrupted(reason: string): Recorded;
39
+ export declare function reportOf(operation: {
40
+ readonly intent: Reported;
41
+ readonly commandId: string;
42
+ readonly worker: string;
43
+ }, recorded: Recorded): WorkerReport;
@@ -0,0 +1,55 @@
1
+ import { createHash } from "node:crypto";
2
+ import { chmod, mkdir, readFile, rename, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ export function operationKey(text) {
5
+ return createHash("sha256").update(text).digest("hex").slice(0, 32);
6
+ }
7
+ export function located(journal, operationId) {
8
+ const key = operationKey(operationId);
9
+ return { key, folder: join(journal, key) };
10
+ }
11
+ export async function readRecord(folder, name) {
12
+ const text = await readFile(join(folder, name), "utf8").catch(() => undefined);
13
+ const value = text === undefined ? undefined : JSON.parse(text);
14
+ return value;
15
+ }
16
+ export async function writeRecord(folder, record) {
17
+ const path = join(folder, record.name);
18
+ await mkdir(folder, { recursive: true });
19
+ if (record.permissions === "private")
20
+ await chmod(folder, 0o700);
21
+ await writeFile(`${path}.staged`, JSON.stringify(record.value, null, 2), record.permissions === "private" ? { mode: 0o600 } : {});
22
+ await rename(`${path}.staged`, path);
23
+ }
24
+ export function replied(identity, recorded) {
25
+ const field = (name) => Reflect.get(Object(recorded), name);
26
+ if (field("outcome") === "completed")
27
+ return { kind: "completed", ...identity, result: String(field("result")) };
28
+ if (field("outcome") === "stopped")
29
+ return { kind: "stopped", ...identity };
30
+ const result = field("result");
31
+ return {
32
+ kind: "failed",
33
+ ...identity,
34
+ reason: String(field("reason")),
35
+ ...(typeof result === "string" ? { result } : {}),
36
+ };
37
+ }
38
+ export function interrupted(reason) {
39
+ return { outcome: "failed", reason, endedAt: new Date().toISOString() };
40
+ }
41
+ export function reportOf(operation, recorded) {
42
+ const { intent, commandId, worker } = operation;
43
+ const { outcome, result, reason } = recorded;
44
+ return {
45
+ runId: intent.runId,
46
+ commandId,
47
+ operationId: intent.operationId,
48
+ inputDigest: intent.inputDigest,
49
+ leaseGeneration: intent.leaseGeneration,
50
+ worker,
51
+ outcome,
52
+ ...(result === undefined ? {} : { result }),
53
+ ...(reason === undefined ? {} : { reason }),
54
+ };
55
+ }
@@ -0,0 +1,9 @@
1
+ import { type RunningTurn, type TurnStart } from "./claude-turn.ts";
2
+ export interface RetrySettings {
3
+ readonly retryDelay?: (milliseconds: number, signal: AbortSignal) => Promise<void>;
4
+ }
5
+ interface RetryOptions extends RetrySettings {
6
+ readonly metadata: Readonly<Record<string, unknown>>;
7
+ }
8
+ export declare function startRetriedTurn(start: TurnStart, options: RetryOptions): Promise<RunningTurn>;
9
+ export {};