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,185 @@
1
+ import { join } from "node:path";
2
+ import { mkdir } from "node:fs/promises";
3
+ import { setTimeout as delay } from "node:timers/promises";
4
+ import { priceOf, sumUsage, usageOf } from "../worker-usage.js";
5
+ import { capacityRefusal, startTurn, } from "./claude-turn.js";
6
+ import { readRecord, writeRecord } from "./operation-journal.js";
7
+ const waits = [60_000, 180_000];
8
+ const continuation = "An earlier attempt stopped because the model was at capacity; continue from the current state of the work tree.\n\n";
9
+ function written(folder, entry) {
10
+ return writeRecord(folder, { ...entry, permissions: "private" });
11
+ }
12
+ function total(values) {
13
+ if (values.includes(null))
14
+ return null;
15
+ return priceOf(values.reduce((sum, value) => sum + (value ?? 0), 0));
16
+ }
17
+ function combined(ends) {
18
+ const last = ends.at(-1) ?? { exitCode: null, result: undefined };
19
+ if (ends.length < 2)
20
+ return last;
21
+ const result = last.result ?? ends.find((end) => end.result)?.result;
22
+ if (result === undefined)
23
+ return last;
24
+ return {
25
+ ...last,
26
+ result: {
27
+ ...result,
28
+ ...(last.result === undefined ? { failed: true, text: "" } : {}),
29
+ usage: sumUsage(ends.map((end) => end.result?.usage ?? usageOf(null))),
30
+ costUsd: total(ends.map((end) => end.result?.costUsd ?? null)),
31
+ turns: total(ends.map((end) => end.result?.turns ?? null)),
32
+ },
33
+ };
34
+ }
35
+ function controlled(attempts, start) {
36
+ const turn = startTurn(start);
37
+ const stop = () => {
38
+ turn.stop(attempts.grace.milliseconds);
39
+ };
40
+ attempts.stopping.signal.addEventListener("abort", stop, { once: true });
41
+ return {
42
+ ...turn,
43
+ ended: turn.ended.finally(() => {
44
+ attempts.stopping.signal.removeEventListener("abort", stop);
45
+ }),
46
+ };
47
+ }
48
+ async function launched(attempts) {
49
+ const { start, options, ends } = attempts;
50
+ const attempt = ends.length + 1;
51
+ const folder = start.mode === "analysis" || attempt === 1
52
+ ? start.folder
53
+ : join(start.folder, `attempt-${String(attempt)}`);
54
+ const entry = {
55
+ ...options.metadata,
56
+ attempt,
57
+ startedAt: attempt === 1 ? attempts.startedAt : new Date().toISOString(),
58
+ };
59
+ await written(start.folder, {
60
+ name: "started.json",
61
+ value: {
62
+ ...entry,
63
+ startedAt: attempts.startedAt,
64
+ phase: "starting",
65
+ processId: null,
66
+ },
67
+ });
68
+ await mkdir(folder, { recursive: true, mode: 0o700 });
69
+ if (attempts.stopping.signal.aborted)
70
+ return undefined;
71
+ const turn = controlled(attempts, {
72
+ ...start,
73
+ folder,
74
+ ...(attempt === 1 ? {} : { activityFolder: start.folder }),
75
+ prompt: attempt === 1 ? start.prompt : continuation + start.prompt,
76
+ });
77
+ try {
78
+ const value = { ...entry, phase: "running", processId: turn.processId };
79
+ await written(start.folder, {
80
+ name: "started.json",
81
+ value: { ...value, startedAt: attempts.startedAt },
82
+ });
83
+ await written(start.folder, {
84
+ name: `attempt-${String(attempt)}.json`,
85
+ value,
86
+ });
87
+ return turn;
88
+ }
89
+ catch (error) {
90
+ turn.stop(0);
91
+ await turn.ended;
92
+ throw error;
93
+ }
94
+ }
95
+ async function recordedEnd(attempts, completion) {
96
+ const { start, ends, options } = attempts;
97
+ const { processId, end } = completion;
98
+ const attempt = ends.length;
99
+ const name = `attempt-${String(attempt)}.json`;
100
+ const started = await readRecord(start.folder, name);
101
+ const startedAt = Reflect.get(Object(started), "startedAt");
102
+ if (typeof startedAt !== "string")
103
+ throw new Error("attempt-start-time-missing");
104
+ await written(start.folder, {
105
+ name,
106
+ value: {
107
+ ...options.metadata,
108
+ attempt,
109
+ processId,
110
+ startedAt,
111
+ endedAt: new Date().toISOString(),
112
+ exitCode: end.exitCode,
113
+ capacity: capacityRefusal(end.result),
114
+ usage: end.result?.usage ?? usageOf(null),
115
+ costUsd: end.result?.costUsd ?? null,
116
+ },
117
+ });
118
+ }
119
+ async function waited(attempts, milliseconds) {
120
+ const { start, options, stopping, ends } = attempts;
121
+ await written(start.folder, {
122
+ name: "started.json",
123
+ value: {
124
+ ...options.metadata,
125
+ startedAt: attempts.startedAt,
126
+ attempt: ends.length,
127
+ phase: "waiting",
128
+ processId: null,
129
+ waitMilliseconds: milliseconds,
130
+ waitingAt: new Date().toISOString(),
131
+ },
132
+ });
133
+ const wait = options.retryDelay ??
134
+ ((duration, signal) => delay(duration, undefined, { signal }));
135
+ await wait(milliseconds, stopping.signal).catch((error) => {
136
+ if (!stopping.signal.aborted)
137
+ throw error;
138
+ });
139
+ }
140
+ async function finished(attempts, first) {
141
+ const { ends } = attempts;
142
+ let turn = first;
143
+ while (turn !== undefined) {
144
+ const end = await turn.ended;
145
+ ends.push(end);
146
+ await recordedEnd(attempts, { processId: turn.processId, end });
147
+ const milliseconds = waits[ends.length - 1];
148
+ if (cancelled(attempts) ||
149
+ !capacityRefusal(end.result) ||
150
+ milliseconds === undefined)
151
+ break;
152
+ await waited(attempts, milliseconds);
153
+ if (cancelled(attempts))
154
+ return { ...combined(ends), stopped: true };
155
+ turn = await launched(attempts);
156
+ }
157
+ return {
158
+ ...combined(ends),
159
+ ...(cancelled(attempts) || turn === undefined ? { stopped: true } : {}),
160
+ };
161
+ }
162
+ function cancelled(attempts) {
163
+ return attempts.stopping.signal.aborted;
164
+ }
165
+ export async function startRetriedTurn(start, options) {
166
+ const attempts = {
167
+ start,
168
+ startedAt: new Date().toISOString(),
169
+ options,
170
+ stopping: new AbortController(),
171
+ ends: [],
172
+ grace: { milliseconds: 2_000 },
173
+ };
174
+ const turn = await launched(attempts);
175
+ if (turn === undefined)
176
+ throw new Error("turn-start-stopped");
177
+ return {
178
+ processId: turn.processId,
179
+ ended: finished(attempts, turn),
180
+ stop: (graceMilliseconds) => {
181
+ attempts.grace.milliseconds = graceMilliseconds;
182
+ attempts.stopping.abort();
183
+ },
184
+ };
185
+ }
@@ -0,0 +1,33 @@
1
+ import type { DeclaredWorkflow } from "../workflow-declaration.ts";
2
+ import type { Resolver, WorkflowRegistration } from "../service/registry.ts";
3
+ export declare const ticketWorkflow = "develop-ticket";
4
+ export declare const promptWorkflow = "develop-prompt";
5
+ export declare const issueWorkflow = "develop-issue";
6
+ export declare const ticketCapabilities: string[];
7
+ export type TicketRegistrations = {
8
+ readonly kind: "admitted";
9
+ readonly registrations: readonly WorkflowRegistration[];
10
+ } | {
11
+ readonly kind: "rejected";
12
+ readonly detail: string;
13
+ };
14
+ export interface TicketSource {
15
+ readonly repository: string;
16
+ readonly command: readonly string[] | undefined;
17
+ readonly nextCommand?: readonly string[] | undefined;
18
+ }
19
+ export interface TicketRegistration {
20
+ readonly workflowId: string;
21
+ readonly functionName: string;
22
+ readonly resolver: Resolver;
23
+ readonly submission: WorkflowRegistration["submission"];
24
+ readonly effectLimit: number;
25
+ readonly capabilities?: readonly string[];
26
+ }
27
+ export declare function ticketResolver(source: TicketSource): Resolver;
28
+ export declare function issueResolver(source: TicketSource): Resolver;
29
+ export declare function promptResolver(repository: string): Resolver;
30
+ export declare function ticketRegistrationTable(source: TicketSource, declarations?: readonly DeclaredWorkflow[]): readonly TicketRegistration[];
31
+ export declare function ticketRegistrations(manifests: Readonly<Record<string, string | undefined>>, options: {
32
+ readonly table: readonly TicketRegistration[];
33
+ }): Promise<TicketRegistrations>;
@@ -0,0 +1,177 @@
1
+ import { createHash } from "node:crypto";
2
+ import { admitCompiled } from "../cli/validate.js";
3
+ import { ticketCommandText, ticketText } from "./ticket-source.js";
4
+ export const ticketWorkflow = "develop-ticket";
5
+ export const promptWorkflow = "develop-prompt";
6
+ export const issueWorkflow = "develop-issue";
7
+ export const ticketCapabilities = ["claude", "github"];
8
+ const ticketIdentifier = /^[A-Za-z0-9._:-]{1,64}$/;
9
+ function rejected(code, detail) {
10
+ return { kind: "rejected", code, detail };
11
+ }
12
+ function digest(commandId) {
13
+ return createHash("sha256").update(commandId).digest("hex");
14
+ }
15
+ async function ticket(source, request) {
16
+ const { command, repository } = source;
17
+ const ticketId = String(request.submission["ticket"]);
18
+ if (ticketId === "next")
19
+ return nextTicket(source, request);
20
+ if (!ticketIdentifier.test(ticketId))
21
+ return rejected("invalid-ticket-id", "A ticket ID has letters, digits and the characters . _ : - only.");
22
+ if (command === undefined)
23
+ return rejected("ticket-source-not-configured", "The daemon has no ticket command. Set CLOVING_TICKET_COMMAND, or use the workflow develop-prompt.");
24
+ const read = await ticketText(command, { ticketId, signal: request.signal });
25
+ if (read.kind === "failed")
26
+ return rejected("ticket-not-available", read.detail);
27
+ const name = ticketId.toLowerCase().replace(/[^a-z0-9-]/g, "-");
28
+ return {
29
+ kind: "resolved",
30
+ input: {
31
+ cycleId: `${name}-${digest(request.commandId).slice(0, 8)}`,
32
+ ticketId,
33
+ ticket: read.text,
34
+ repository,
35
+ },
36
+ };
37
+ }
38
+ async function nextTicket(source, request) {
39
+ if (source.nextCommand === undefined)
40
+ return rejected("next-source-not-configured", "The daemon has no next-ticket command. Set CLOVING_NEXT_COMMAND.");
41
+ const selected = await ticketCommandText(source.nextCommand, request.signal);
42
+ if (selected.kind === "failed")
43
+ return rejected("next-ticket-not-available", selected.detail);
44
+ if (selected.text === "")
45
+ return rejected("no-ready-ticket", "The next-ticket command printed no ticket ID.");
46
+ if (!ticketIdentifier.test(selected.text) || selected.text === "next")
47
+ return rejected("invalid-ticket-id", "The next-ticket command must print one valid ticket ID other than next.");
48
+ return ticket(source, { ...request, submission: { ticket: selected.text } });
49
+ }
50
+ export function ticketResolver(source) {
51
+ return {
52
+ id: "ticket-command",
53
+ version: "1",
54
+ resolve: (request) => ticket(source, request),
55
+ };
56
+ }
57
+ export function issueResolver(source) {
58
+ return {
59
+ id: "issue-command",
60
+ version: "1",
61
+ resolve: async (request) => {
62
+ const resolution = await ticket(source, request);
63
+ if (resolution.kind === "rejected")
64
+ return resolution;
65
+ return {
66
+ kind: "resolved",
67
+ input: { ...Object(resolution.input), delivery: "pull-request" },
68
+ };
69
+ },
70
+ };
71
+ }
72
+ export function promptResolver(repository) {
73
+ return {
74
+ id: "ticket-prompt",
75
+ version: "1",
76
+ resolve: (request) => Promise.resolve({
77
+ kind: "resolved",
78
+ input: {
79
+ cycleId: `task-${digest(request.commandId).slice(0, 12)}`,
80
+ ticket: String(request.submission["prompt"]),
81
+ repository,
82
+ },
83
+ }),
84
+ };
85
+ }
86
+ export function ticketRegistrationTable(source, declarations = []) {
87
+ return [
88
+ {
89
+ workflowId: ticketWorkflow,
90
+ functionName: "developTicket",
91
+ effectLimit: 8,
92
+ submission: { maximumBytes: 4_096, fields: { ticket: "string" } },
93
+ resolver: ticketResolver(source),
94
+ },
95
+ {
96
+ workflowId: issueWorkflow,
97
+ functionName: "developTicket",
98
+ effectLimit: 20,
99
+ submission: { maximumBytes: 4_096, fields: { ticket: "string" } },
100
+ resolver: issueResolver(source),
101
+ },
102
+ {
103
+ workflowId: "develop-prd",
104
+ functionName: "developPrd",
105
+ effectLimit: 8,
106
+ submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
107
+ resolver: promptResolver(source.repository),
108
+ },
109
+ {
110
+ workflowId: promptWorkflow,
111
+ functionName: "developTicket",
112
+ effectLimit: 8,
113
+ submission: { maximumBytes: 65_536, fields: { prompt: "string" } },
114
+ resolver: promptResolver(source.repository),
115
+ },
116
+ ...declarations.map((declaration) => ({
117
+ workflowId: declaration.workflowId,
118
+ functionName: declaration.functionName,
119
+ effectLimit: declaration.effectLimit,
120
+ capabilities: declaration.capabilities,
121
+ submission: declaration.input,
122
+ resolver: declaredResolver(source.repository),
123
+ })),
124
+ ];
125
+ }
126
+ function declaredResolver(repository) {
127
+ return {
128
+ id: "declared-input",
129
+ version: "1",
130
+ resolve: (request) => Promise.resolve({
131
+ kind: "resolved",
132
+ input: {
133
+ cycleId: `task-${digest(request.commandId).slice(0, 12)}`,
134
+ repository,
135
+ input: request.submission,
136
+ },
137
+ }),
138
+ };
139
+ }
140
+ export async function ticketRegistrations(manifests, options) {
141
+ const ids = new Set();
142
+ for (const row of options.table) {
143
+ if (ids.has(row.workflowId))
144
+ return {
145
+ kind: "rejected",
146
+ detail: `duplicate-workflow-id: ${row.workflowId}`,
147
+ };
148
+ ids.add(row.workflowId);
149
+ }
150
+ const registrations = [];
151
+ for (const row of options.table) {
152
+ const manifest = manifests[row.functionName];
153
+ if (manifest === undefined)
154
+ return {
155
+ kind: "rejected",
156
+ detail: `Missing manifest for workflow function ${row.functionName}.`,
157
+ };
158
+ const admission = await admitCompiled(manifest, {
159
+ file: manifest,
160
+ capabilities: row.capabilities ?? ticketCapabilities,
161
+ });
162
+ if (admission.kind === "rejected")
163
+ return {
164
+ kind: "rejected",
165
+ detail: `${admission.error.code}: ${admission.error.detail}`,
166
+ };
167
+ registrations.push({
168
+ workflowId: row.workflowId,
169
+ manifest: admission.manifest,
170
+ availability: "available",
171
+ effectLimit: row.effectLimit,
172
+ submission: row.submission,
173
+ resolver: row.resolver,
174
+ });
175
+ }
176
+ return { kind: "admitted", registrations };
177
+ }
@@ -0,0 +1,17 @@
1
+ export declare const ticketLimits: {
2
+ textBytes: number;
3
+ detailCharacters: number;
4
+ };
5
+ export type TicketRead = {
6
+ readonly kind: "read";
7
+ readonly text: string;
8
+ } | {
9
+ readonly kind: "failed";
10
+ readonly detail: string;
11
+ };
12
+ export interface TicketRequest {
13
+ readonly ticketId: string;
14
+ readonly signal: AbortSignal;
15
+ }
16
+ export declare function ticketText(command: readonly string[], request: TicketRequest): Promise<TicketRead>;
17
+ export declare function ticketCommandText(command: readonly string[], signal: AbortSignal): Promise<TicketRead>;
@@ -0,0 +1,36 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ export const ticketLimits = { textBytes: 48_000, detailCharacters: 300 };
4
+ function failed(detail) {
5
+ return { kind: "failed", detail };
6
+ }
7
+ function printed(output) {
8
+ const text = output.trim();
9
+ if (text === "")
10
+ return failed("The ticket command printed no text.");
11
+ if (Buffer.byteLength(text) > ticketLimits.textBytes)
12
+ return failed(`The ticket text has more than ${String(ticketLimits.textBytes)} bytes.`);
13
+ return { kind: "read", text };
14
+ }
15
+ function ended(error) {
16
+ const code = Reflect.get(Object(error), "code");
17
+ const cause = String(Reflect.get(Object(error), "stderr"))
18
+ .trim()
19
+ .slice(0, ticketLimits.detailCharacters);
20
+ return typeof code === "number"
21
+ ? failed(`The ticket command ended with the code ${String(code)}: ${cause}`)
22
+ : failed(`The ticket command did not complete: ${String(code)}`);
23
+ }
24
+ const executed = promisify(execFile);
25
+ export function ticketText(command, request) {
26
+ const [executable = "", ...fixed] = command;
27
+ return ticketCommandText([executable, ...fixed, request.ticketId], request.signal).then((result) => result.kind === "failed" ? result : printed(result.text));
28
+ }
29
+ export function ticketCommandText(command, signal) {
30
+ const [executable = "", ...fixed] = command;
31
+ return executed(executable, fixed, {
32
+ signal,
33
+ maxBuffer: 4 * ticketLimits.textBytes,
34
+ encoding: "utf8",
35
+ }).then((output) => ({ kind: "read", text: output.stdout.trim() }), ended);
36
+ }
@@ -0,0 +1,26 @@
1
+ export interface WorkTree {
2
+ readonly path: string;
3
+ readonly branch: string;
4
+ readonly startCommit: string;
5
+ }
6
+ export interface TreeRequest {
7
+ readonly repository: string;
8
+ readonly worktrees: string;
9
+ readonly target: string;
10
+ readonly signal: AbortSignal;
11
+ readonly base?: string;
12
+ }
13
+ export interface Changes {
14
+ readonly branch: string;
15
+ readonly commits: readonly string[];
16
+ readonly files: readonly string[];
17
+ readonly uncommitted: readonly string[];
18
+ }
19
+ export declare function treeName(target: string): string;
20
+ export declare function treePlace(request: Pick<TreeRequest, "worktrees" | "target">): {
21
+ readonly path: string;
22
+ readonly branch: string;
23
+ };
24
+ export declare function workTree(request: TreeRequest): Promise<WorkTree>;
25
+ export declare function treeFailure(error: unknown): string;
26
+ export declare function changes(tree: WorkTree): Promise<Changes>;
@@ -0,0 +1,206 @@
1
+ import { execFile, spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { mkdir, realpath } from "node:fs/promises";
4
+ import { join, relative, resolve, sep } from "node:path";
5
+ import { promisify } from "node:util";
6
+ const executed = promisify(execFile);
7
+ const lineLimit = 30;
8
+ const lineLength = 120;
9
+ async function git(call) {
10
+ const { directory, parts, signal } = call;
11
+ const { stdout } = await executed("git", ["-C", directory, ...parts], {
12
+ ...(signal === undefined ? {} : { signal }),
13
+ });
14
+ return stdout;
15
+ }
16
+ export function treeName(target) {
17
+ return target
18
+ .replace(/[^A-Za-z0-9._-]/g, "-")
19
+ .replace(/\.{2,}/g, "-")
20
+ .replace(/^\.|\.$/g, "-")
21
+ .replace(/\.lock$/, "-lock");
22
+ }
23
+ async function added(request, tree) {
24
+ const { repository, worktrees, signal } = request;
25
+ const call = (parts) => git({ directory: repository, parts, signal });
26
+ await call(["worktree", "prune"]);
27
+ await mkdir(worktrees, { recursive: true });
28
+ const known = await call([
29
+ "rev-parse",
30
+ "--verify",
31
+ "--quiet",
32
+ `refs/heads/${tree.branch}`,
33
+ ]).then(() => true, () => false);
34
+ await call(known
35
+ ? ["worktree", "add", tree.path, tree.branch]
36
+ : [
37
+ "worktree",
38
+ "add",
39
+ "-b",
40
+ tree.branch,
41
+ tree.path,
42
+ request.base ?? "HEAD",
43
+ ]);
44
+ }
45
+ export function treePlace(request) {
46
+ const name = treeName(request.target);
47
+ return { path: join(request.worktrees, name), branch: `cloving/${name}` };
48
+ }
49
+ export async function workTree(request) {
50
+ if (request.target.startsWith("branch:"))
51
+ return branchTree(request).catch((error) => {
52
+ const reason = treeFailure(error);
53
+ throw new Error(reason === "work-tree-not-available"
54
+ ? "branch-worktree-not-found"
55
+ : reason);
56
+ });
57
+ const { path, branch } = treePlace(request);
58
+ if (!existsSync(join(path, ".git")))
59
+ await added(request, { path, branch });
60
+ const head = await git({
61
+ directory: path,
62
+ parts: ["rev-parse", "HEAD"],
63
+ signal: request.signal,
64
+ });
65
+ return { path, branch, startCommit: head.trim() };
66
+ }
67
+ async function branchTree(request) {
68
+ const branch = request.target.slice("branch:".length);
69
+ if (branch.startsWith("cloving/"))
70
+ throw new Error("branch-reserved");
71
+ const listing = await git({
72
+ directory: request.repository,
73
+ parts: ["worktree", "list", "--porcelain", "-z"],
74
+ signal: request.signal,
75
+ });
76
+ const entry = listing
77
+ .split("\0\0")
78
+ .slice(1)
79
+ .find((record) => record.split("\0").includes(`branch refs/heads/${branch}`));
80
+ const path = entry?.split("\0")[0]?.slice("worktree ".length);
81
+ if (path === undefined)
82
+ throw new Error("branch-worktree-not-found");
83
+ await sameBranch(request, { path, branch });
84
+ await outsideManaged(request, path);
85
+ await cleanBranch({ directory: path, signal: request.signal });
86
+ const head = await git({
87
+ directory: path,
88
+ parts: ["rev-parse", "HEAD"],
89
+ signal: request.signal,
90
+ });
91
+ return { path, branch, startCommit: head.trim() };
92
+ }
93
+ async function outsideManaged(request, path) {
94
+ const folder = await realpath(request.worktrees).catch((error) => {
95
+ if (typeof error !== "object" ||
96
+ error === null ||
97
+ !("code" in error) ||
98
+ error.code !== "ENOENT")
99
+ throw error;
100
+ return resolve(request.worktrees);
101
+ });
102
+ const location = relative(folder, await realpath(path));
103
+ if (location !== ".." && !location.startsWith(`..${sep}`))
104
+ throw new Error("branch-reserved");
105
+ }
106
+ async function sameBranch(request, tree) {
107
+ const common = async (directory) => {
108
+ const folder = await git({
109
+ directory,
110
+ parts: ["rev-parse", "--git-common-dir"],
111
+ signal: request.signal,
112
+ });
113
+ return realpath(resolve(directory, folder.trim()));
114
+ };
115
+ if ((await common(request.repository)) !== (await common(tree.path)))
116
+ throw new Error("branch-worktree-not-found");
117
+ const head = await git({
118
+ directory: tree.path,
119
+ parts: ["symbolic-ref", "--quiet", "HEAD"],
120
+ signal: request.signal,
121
+ });
122
+ if (head.trim() !== `refs/heads/${tree.branch}`)
123
+ throw new Error("branch-worktree-not-found");
124
+ }
125
+ async function cleanBranch(place) {
126
+ await cleanOutput({
127
+ ...place,
128
+ parts: [
129
+ "-c",
130
+ "core.fileMode=true",
131
+ "status",
132
+ "--porcelain",
133
+ "--untracked-files=all",
134
+ "--ignore-submodules=none",
135
+ ],
136
+ }, hasOutput);
137
+ await cleanOutput({ ...place, parts: ["ls-files", "-v", "-z"] }, hiddenIndex);
138
+ }
139
+ async function hasOutput(output) {
140
+ let present = false;
141
+ for await (const chunk of output) {
142
+ if (chunk.length > 0)
143
+ present = true;
144
+ }
145
+ return present;
146
+ }
147
+ async function hiddenIndex(output) {
148
+ let entryStart = true;
149
+ let hidden = false;
150
+ for await (const chunk of output) {
151
+ for (const character of chunk.toString()) {
152
+ if (entryStart && /[a-zS]/.test(character))
153
+ hidden = true;
154
+ entryStart = character === "\0";
155
+ }
156
+ }
157
+ return hidden;
158
+ }
159
+ async function cleanOutput(call, inspect) {
160
+ const child = spawn("git", ["-C", call.directory, ...call.parts], {
161
+ stdio: ["ignore", "pipe", "ignore"],
162
+ ...(call.signal === undefined ? {} : { signal: call.signal }),
163
+ });
164
+ const ended = new Promise((resolve) => {
165
+ child.once("error", () => {
166
+ resolve(false);
167
+ });
168
+ child.once("close", (code) => {
169
+ resolve(code === 0);
170
+ });
171
+ });
172
+ const dirty = await inspect(child.stdout);
173
+ if (!(await ended))
174
+ throw new Error("branch-worktree-not-found");
175
+ if (dirty)
176
+ throw new Error("branch-worktree-not-clean");
177
+ }
178
+ export function treeFailure(error) {
179
+ const reason = error instanceof Error ? error.message : "";
180
+ return [
181
+ "branch-worktree-not-found",
182
+ "branch-worktree-not-clean",
183
+ "branch-reserved",
184
+ ].includes(reason)
185
+ ? reason
186
+ : "work-tree-not-available";
187
+ }
188
+ export async function changes(tree) {
189
+ const lines = async (parts) => (await git({ directory: tree.path, parts }).catch(() => ""))
190
+ .split("\n")
191
+ .filter((line) => line.trim() !== "")
192
+ .slice(0, lineLimit)
193
+ .map((line) => line.slice(0, lineLength));
194
+ const range = `${tree.startCommit}..HEAD`;
195
+ const [branch = tree.branch] = await lines([
196
+ "rev-parse",
197
+ "--abbrev-ref",
198
+ "HEAD",
199
+ ]);
200
+ return {
201
+ branch,
202
+ commits: await lines(["log", "--oneline", range]),
203
+ files: await lines(["diff", "--stat", range]),
204
+ uncommitted: await lines(["status", "--short"]),
205
+ };
206
+ }