cloving 1.3.0 → 1.4.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 (396) hide show
  1. package/README.md +235 -206
  2. package/dist/src/agent-harness-shell.d.ts +2 -1
  3. package/dist/src/agent-harness-shell.js +8 -5
  4. package/dist/src/authority/command-wait-checks.d.ts +8 -0
  5. package/dist/src/authority/command-wait-checks.js +88 -0
  6. package/dist/src/authority/command-wait-results.d.ts +15 -0
  7. package/dist/src/authority/command-wait-results.js +73 -0
  8. package/dist/src/authority/command-wait-view.d.ts +21 -0
  9. package/dist/src/authority/command-wait-view.js +34 -0
  10. package/dist/src/authority/command-waits.d.ts +39 -0
  11. package/dist/src/authority/command-waits.js +97 -0
  12. package/dist/src/authority/commands.js +22 -1
  13. package/dist/src/authority/dispatch-decision.d.ts +8 -0
  14. package/dist/src/authority/dispatch-decision.js +26 -1
  15. package/dist/src/authority/effect-requests.js +6 -3
  16. package/dist/src/authority/effect-results.js +4 -2
  17. package/dist/src/authority/history-state.d.ts +2 -0
  18. package/dist/src/authority/history-state.js +13 -1
  19. package/dist/src/authority/instants.d.ts +1 -0
  20. package/dist/src/authority/instants.js +21 -0
  21. package/dist/src/authority/reduction-state.d.ts +2 -0
  22. package/dist/src/authority/reduction-state.js +5 -0
  23. package/dist/src/authority/reduction.js +24 -0
  24. package/dist/src/authority/status-input.d.ts +2 -0
  25. package/dist/src/authority/status.d.ts +2 -0
  26. package/dist/src/authority/status.js +1 -0
  27. package/dist/src/authority/stop-sequence.d.ts +1 -0
  28. package/dist/src/authority/stop-sequence.js +2 -1
  29. package/dist/src/authority/transitions.d.ts +6 -4
  30. package/dist/src/authority/transitions.js +7 -0
  31. package/dist/src/broker/actor/authority-queries.d.ts +2 -1
  32. package/dist/src/broker/actor/authority-queries.js +14 -5
  33. package/dist/src/broker/actor/authority-receipts.js +1 -1
  34. package/dist/src/broker/actor/authority-settings.js +2 -2
  35. package/dist/src/broker/actor/authority-upgrades.d.ts +19 -2
  36. package/dist/src/broker/actor/authority-upgrades.js +7 -2
  37. package/dist/src/broker/actor/delivery-intents.js +2 -0
  38. package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
  39. package/dist/src/broker/actor/effect-delivery.js +15 -2
  40. package/dist/src/broker/actor/effect-plan.js +11 -2
  41. package/dist/src/broker/actor/effect-queries.d.ts +4 -0
  42. package/dist/src/broker/actor/effect-queries.js +9 -1
  43. package/dist/src/broker/actor/effect-turn.js +2 -0
  44. package/dist/src/broker/actor/stop-plan.js +9 -3
  45. package/dist/src/broker/actor/stop-turn.d.ts +2 -0
  46. package/dist/src/broker/actor/stop-turn.js +24 -11
  47. package/dist/src/broker/actor/turn-draft.d.ts +1 -0
  48. package/dist/src/broker/actor/turn-draft.js +4 -0
  49. package/dist/src/broker/actor/turn-state.js +5 -1
  50. package/dist/src/broker/authority-admission.js +60 -0
  51. package/dist/src/broker/authority-restore.d.ts +2 -0
  52. package/dist/src/broker/authority-restore.js +35 -1
  53. package/dist/src/broker/command-wait-restore.d.ts +31 -0
  54. package/dist/src/broker/command-wait-restore.js +86 -0
  55. package/dist/src/broker/decision-restore.d.ts +1 -1
  56. package/dist/src/broker/decision-restore.js +1 -0
  57. package/dist/src/broker/effect-upgrade.d.ts +2 -0
  58. package/dist/src/broker/effect-upgrade.js +8 -2
  59. package/dist/src/cli/arguments.d.ts +13 -0
  60. package/dist/src/cli/arguments.js +42 -3
  61. package/dist/src/cli/chat-stores.d.ts +2 -0
  62. package/dist/src/cli/chat-stores.js +113 -0
  63. package/dist/src/cli/client.d.ts +4 -1
  64. package/dist/src/cli/client.js +9 -3
  65. package/dist/src/cli/command-requests.d.ts +17 -0
  66. package/dist/src/cli/command-requests.js +43 -0
  67. package/dist/src/cli/command-waits.d.ts +9 -0
  68. package/dist/src/cli/command-waits.js +51 -0
  69. package/dist/src/cli/commands.js +14 -41
  70. package/dist/src/cli/config-file.d.ts +2 -2
  71. package/dist/src/cli/config-file.js +4 -2
  72. package/dist/src/cli/doctor-workflows.d.ts +5 -2
  73. package/dist/src/cli/doctor-workflows.js +12 -7
  74. package/dist/src/cli/doctor.js +6 -9
  75. package/dist/src/cli/harness-probes.d.ts +2 -0
  76. package/dist/src/cli/harness-probes.js +1 -1
  77. package/dist/src/cli/harness-processes.d.ts +6 -0
  78. package/dist/src/cli/harness-processes.js +36 -0
  79. package/dist/src/cli/init-command.d.ts +9 -0
  80. package/dist/src/cli/init-command.js +52 -0
  81. package/dist/src/cli/init-prompt-command.d.ts +10 -0
  82. package/dist/src/cli/init-prompt-command.js +145 -0
  83. package/dist/src/cli/init-prompt.d.ts +35 -0
  84. package/dist/src/cli/init-prompt.js +74 -0
  85. package/dist/src/cli/init-selection.d.ts +13 -0
  86. package/dist/src/cli/init-selection.js +75 -0
  87. package/dist/src/cli/main.d.ts +2 -0
  88. package/dist/src/cli/main.js +37 -7
  89. package/dist/src/cli/mcp-server.d.ts +1 -0
  90. package/dist/src/cli/mcp-server.js +156 -0
  91. package/dist/src/cli/mcp-tools.d.ts +15 -0
  92. package/dist/src/cli/mcp-tools.js +80 -0
  93. package/dist/src/cli/render.d.ts +1 -1
  94. package/dist/src/cli/render.js +17 -30
  95. package/dist/src/cli/report-ci-jobs.d.ts +23 -0
  96. package/dist/src/cli/report-ci-jobs.js +103 -0
  97. package/dist/src/cli/report-ci-usage.d.ts +9 -0
  98. package/dist/src/cli/report-ci-usage.js +185 -0
  99. package/dist/src/cli/report-ci.d.ts +13 -0
  100. package/dist/src/cli/report-ci.js +74 -0
  101. package/dist/src/cli/report-closures.d.ts +6 -0
  102. package/dist/src/cli/report-closures.js +97 -0
  103. package/dist/src/cli/report-flow.d.ts +7 -0
  104. package/dist/src/cli/report-flow.js +122 -0
  105. package/dist/src/cli/report-github-reader.d.ts +29 -0
  106. package/dist/src/cli/report-github-reader.js +157 -0
  107. package/dist/src/cli/report-github.d.ts +15 -8
  108. package/dist/src/cli/report-github.js +131 -150
  109. package/dist/src/cli/report-operator.d.ts +3 -0
  110. package/dist/src/cli/report-operator.js +40 -0
  111. package/dist/src/cli/report-ready.d.ts +3 -0
  112. package/dist/src/cli/report-ready.js +96 -0
  113. package/dist/src/cli/report-text.d.ts +9 -0
  114. package/dist/src/cli/report-text.js +33 -0
  115. package/dist/src/cli/report.d.ts +1 -0
  116. package/dist/src/cli/report.js +104 -27
  117. package/dist/src/cli/runtime-arguments.d.ts +2 -1
  118. package/dist/src/cli/runtime-arguments.js +7 -2
  119. package/dist/src/cli/schedule-arguments.d.ts +14 -0
  120. package/dist/src/cli/schedule-arguments.js +26 -0
  121. package/dist/src/cli/schedule-render.d.ts +22 -0
  122. package/dist/src/cli/schedule-render.js +73 -0
  123. package/dist/src/cli/terminal-text.d.ts +3 -0
  124. package/dist/src/cli/terminal-text.js +28 -0
  125. package/dist/src/cli/usage-render.d.ts +1 -0
  126. package/dist/src/cli/usage-render.js +28 -1
  127. package/dist/src/cli/usage.d.ts +1 -1
  128. package/dist/src/cli/usage.js +50 -7
  129. package/dist/src/cli/watch-actions.js +2 -2
  130. package/dist/src/cli/watch-board-view.js +19 -2
  131. package/dist/src/cli/watch-board.d.ts +4 -2
  132. package/dist/src/cli/watch-board.js +53 -43
  133. package/dist/src/cli/watch-card-forms.d.ts +1 -1
  134. package/dist/src/cli/watch-card-forms.js +11 -10
  135. package/dist/src/cli/watch-client.d.ts +1 -1
  136. package/dist/src/cli/watch-client.js +2 -11
  137. package/dist/src/cli/watch-header-view.d.ts +0 -5
  138. package/dist/src/cli/watch-header-view.js +8 -20
  139. package/dist/src/cli/watch-model.d.ts +4 -1
  140. package/dist/src/cli/watch-model.js +17 -11
  141. package/dist/src/cli/watch-page.js +12 -14
  142. package/dist/src/cli/watch-phases.d.ts +12 -3
  143. package/dist/src/cli/watch-phases.js +68 -11
  144. package/dist/src/cli/watch-pr-board.js +1 -1
  145. package/dist/src/cli/watch-pr-command.d.ts +1 -0
  146. package/dist/src/cli/watch-pull-request.js +18 -8
  147. package/dist/src/cli/watch-reads.d.ts +2 -0
  148. package/dist/src/cli/watch-reads.js +17 -16
  149. package/dist/src/cli/watch-render.d.ts +14 -0
  150. package/dist/src/cli/watch-run-input.d.ts +0 -1
  151. package/dist/src/cli/watch-run-input.js +0 -13
  152. package/dist/src/cli/watch-server.js +6 -6
  153. package/dist/src/cli/watch-view.d.ts +0 -3
  154. package/dist/src/cli/watch-view.js +13 -13
  155. package/dist/src/cli.js +59 -5
  156. package/dist/src/command-wait.d.ts +4 -0
  157. package/dist/src/command-wait.js +45 -0
  158. package/dist/src/configuration-change.d.ts +7 -0
  159. package/dist/src/configuration-change.js +14 -0
  160. package/dist/src/configuration-schema.d.ts +9 -0
  161. package/dist/src/configuration-schema.js +6 -2
  162. package/dist/src/daemon/attachment-file.d.ts +6 -0
  163. package/dist/src/daemon/attachment-file.js +86 -0
  164. package/dist/src/daemon/attachments.d.ts +14 -0
  165. package/dist/src/daemon/attachments.js +17 -0
  166. package/dist/src/daemon/claude-recovery.d.ts +50 -0
  167. package/dist/src/daemon/claude-recovery.js +204 -0
  168. package/dist/src/daemon/claude-stream.d.ts +27 -0
  169. package/dist/src/daemon/claude-stream.js +63 -0
  170. package/dist/src/daemon/claude-turn.d.ts +11 -25
  171. package/dist/src/daemon/claude-turn.js +64 -81
  172. package/dist/src/daemon/claude-worker.d.ts +2 -1
  173. package/dist/src/daemon/claude-worker.js +124 -122
  174. package/dist/src/daemon/daemon-adapters.d.ts +2 -0
  175. package/dist/src/daemon/daemon-adapters.js +26 -2
  176. package/dist/src/daemon/daemon-loops.d.ts +3 -1
  177. package/dist/src/daemon/daemon-loops.js +3 -1
  178. package/dist/src/daemon/daemon.js +14 -6
  179. package/dist/src/daemon/github-attach.d.ts +2 -0
  180. package/dist/src/daemon/github-attach.js +149 -0
  181. package/dist/src/daemon/github-ci-filters.d.ts +6 -0
  182. package/dist/src/daemon/github-ci-filters.js +138 -0
  183. package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
  184. package/dist/src/daemon/github-ci-workflows.js +148 -0
  185. package/dist/src/daemon/github-ci.js +22 -4
  186. package/dist/src/daemon/github-issue-methods.d.ts +2 -0
  187. package/dist/src/daemon/github-issue-methods.js +37 -2
  188. package/dist/src/daemon/github-merge-call.d.ts +2 -1
  189. package/dist/src/daemon/github-merge-call.js +10 -3
  190. package/dist/src/daemon/github-merge.js +52 -24
  191. package/dist/src/daemon/github-methods.js +12 -2
  192. package/dist/src/daemon/github-operation.d.ts +4 -0
  193. package/dist/src/daemon/github-operation.js +6 -0
  194. package/dist/src/daemon/github-worker.d.ts +4 -0
  195. package/dist/src/daemon/github-worker.js +6 -0
  196. package/dist/src/daemon/issue-queue.d.ts +1 -1
  197. package/dist/src/daemon/issue-queue.js +16 -11
  198. package/dist/src/daemon/notify-events.d.ts +6 -0
  199. package/dist/src/daemon/notify-events.js +84 -0
  200. package/dist/src/daemon/notify-journal.js +1 -1
  201. package/dist/src/daemon/notify-message.d.ts +4 -1
  202. package/dist/src/daemon/notify-message.js +36 -0
  203. package/dist/src/daemon/notify.d.ts +1 -1
  204. package/dist/src/daemon/notify.js +5 -77
  205. package/dist/src/daemon/operation-journal.d.ts +1 -0
  206. package/dist/src/daemon/queue-status.d.ts +9 -3
  207. package/dist/src/daemon/queue-status.js +17 -4
  208. package/dist/src/daemon/resume-index-lock.d.ts +13 -0
  209. package/dist/src/daemon/resume-index-lock.js +160 -0
  210. package/dist/src/daemon/resume-worktree.d.ts +7 -0
  211. package/dist/src/daemon/resume-worktree.js +29 -0
  212. package/dist/src/daemon/retrying-turn.d.ts +2 -12
  213. package/dist/src/daemon/retrying-turn.js +98 -172
  214. package/dist/src/daemon/schedule-control.d.ts +26 -0
  215. package/dist/src/daemon/schedule-control.js +110 -0
  216. package/dist/src/daemon/schedule-journal.d.ts +2 -15
  217. package/dist/src/daemon/schedule-journal.js +67 -4
  218. package/dist/src/daemon/ticket-registration.d.ts +2 -7
  219. package/dist/src/daemon/ticket-registration.js +15 -81
  220. package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
  221. package/dist/src/daemon/turn-attempt-journal.js +136 -0
  222. package/dist/src/daemon/turn-attempts.d.ts +47 -0
  223. package/dist/src/daemon/turn-attempts.js +166 -0
  224. package/dist/src/daemon/turn-report.d.ts +8 -1
  225. package/dist/src/daemon/turn-report.js +39 -0
  226. package/dist/src/daemon/work-tree.d.ts +9 -0
  227. package/dist/src/daemon/work-tree.js +20 -0
  228. package/dist/src/daemon/worker-profile.d.ts +8 -0
  229. package/dist/src/daemon/worker-profile.js +40 -0
  230. package/dist/src/daemon/workflow-schedules.d.ts +3 -0
  231. package/dist/src/daemon/workflow-schedules.js +98 -45
  232. package/dist/src/daemon/worktree-processes.d.ts +9 -0
  233. package/dist/src/daemon/worktree-processes.js +151 -0
  234. package/dist/src/doctor-report.d.ts +3 -5
  235. package/dist/src/doctor-report.js +6 -13
  236. package/dist/src/harness-start.d.ts +15 -0
  237. package/dist/src/harness-start.js +37 -0
  238. package/dist/src/host/command-wait.d.ts +38 -0
  239. package/dist/src/host/command-wait.js +115 -0
  240. package/dist/src/host/start-delivery.d.ts +5 -7
  241. package/dist/src/host/start-delivery.js +3 -15
  242. package/dist/src/host/step-bridge-host.d.ts +2 -0
  243. package/dist/src/host/step-bridge-host.js +21 -0
  244. package/dist/src/operation-identity.d.ts +1 -0
  245. package/dist/src/operation-identity.js +4 -0
  246. package/dist/src/private-config.schema.json +40 -0
  247. package/dist/src/project-config.schema.json +40 -0
  248. package/dist/src/project-settings.d.ts +2 -2
  249. package/dist/src/project-settings.js +3 -1
  250. package/dist/src/queue-spend.d.ts +4 -0
  251. package/dist/src/queue-spend.js +21 -0
  252. package/dist/src/relay/relay-service.d.ts +3 -0
  253. package/dist/src/relay/relay-service.js +5 -3
  254. package/dist/src/report-ci.d.ts +164 -0
  255. package/dist/src/report-ci.js +32 -0
  256. package/dist/src/report-effects.d.ts +15 -0
  257. package/dist/src/report-effects.js +212 -0
  258. package/dist/src/report-flow-types.d.ts +38 -0
  259. package/dist/src/report-flow-types.js +7 -0
  260. package/dist/src/report-flow.d.ts +43 -0
  261. package/dist/src/report-flow.js +193 -0
  262. package/dist/src/report-operator.d.ts +67 -0
  263. package/dist/src/report-operator.js +25 -0
  264. package/dist/src/report-quality.d.ts +221 -0
  265. package/dist/src/report-quality.js +94 -0
  266. package/dist/src/report-ready.d.ts +23 -0
  267. package/dist/src/report-ready.js +117 -0
  268. package/dist/src/report-statistics.d.ts +2 -1
  269. package/dist/src/report-statistics.js +40 -4
  270. package/dist/src/report.d.ts +588 -47
  271. package/dist/src/report.js +156 -41
  272. package/dist/src/schedule-progress.d.ts +33 -0
  273. package/dist/src/schedule-progress.js +45 -0
  274. package/dist/src/service/active-tickets.js +6 -6
  275. package/dist/src/service/command-waits.d.ts +34 -0
  276. package/dist/src/service/command-waits.js +86 -0
  277. package/dist/src/service/expiry.js +2 -0
  278. package/dist/src/service/gateway.js +3 -1
  279. package/dist/src/service/queue-spend.d.ts +6 -0
  280. package/dist/src/service/queue-spend.js +68 -0
  281. package/dist/src/service/replies.d.ts +8 -1
  282. package/dist/src/service/replies.js +11 -0
  283. package/dist/src/service/run-handlers.js +22 -2
  284. package/dist/src/service/run-metadata.d.ts +15 -1
  285. package/dist/src/service/run-metadata.js +93 -8
  286. package/dist/src/service/service.d.ts +4 -0
  287. package/dist/src/service/service.js +8 -8
  288. package/dist/src/service/submission-handler.js +18 -4
  289. package/dist/src/service/worker-port.js +9 -1
  290. package/dist/src/service/worker-totals.d.ts +2 -0
  291. package/dist/src/service/worker-totals.js +1 -1
  292. package/dist/src/step-bridge.d.ts +20 -0
  293. package/dist/src/steps/command-wait.d.ts +12 -0
  294. package/dist/src/steps/command-wait.js +26 -0
  295. package/dist/src/steps/open-decision-wait.d.ts +2 -0
  296. package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
  297. package/dist/src/steps/review-by-person.js +4 -1
  298. package/dist/src/steps/wait-for-command.d.ts +3 -0
  299. package/dist/src/steps/wait-for-command.js +17 -0
  300. package/dist/src/steps/wait-for-decision.js +1 -1
  301. package/dist/src/storage/command-wait-rows.d.ts +30 -0
  302. package/dist/src/storage/command-wait-rows.js +96 -0
  303. package/dist/src/storage/decision-snapshots.d.ts +8 -1
  304. package/dist/src/storage/decision-snapshots.js +15 -1
  305. package/dist/src/storage/domain-changes.d.ts +2 -0
  306. package/dist/src/storage/domain-changes.js +3 -0
  307. package/dist/src/storage/domain-schema.d.ts +13 -1
  308. package/dist/src/storage/domain-schema.js +31 -4
  309. package/dist/src/storage/effect-schema.d.ts +1 -0
  310. package/dist/src/storage/effect-schema.js +5 -0
  311. package/dist/src/testing-requests.d.ts +15 -0
  312. package/dist/src/testing-requests.js +93 -0
  313. package/dist/src/testing.d.ts +4 -10
  314. package/dist/src/testing.js +33 -86
  315. package/dist/src/worker-usage.d.ts +1 -0
  316. package/dist/src/worker-usage.js +3 -0
  317. package/dist/src/workflow-candidate.d.ts +1 -0
  318. package/dist/src/workflow-candidate.js +12 -1
  319. package/dist/src/workflow-contracts.d.ts +1 -0
  320. package/dist/src/workflow-contracts.js +9 -2
  321. package/dist/src/workflow-discovery.d.ts +2 -13
  322. package/dist/src/workflow-discovery.js +1 -13
  323. package/dist/src/workflow-refusals.js +0 -1
  324. package/dist/src/workflows.d.ts +1 -1
  325. package/dist/src/workflows.js +1 -1
  326. package/dist/tools/red-green-command.d.ts +1 -0
  327. package/dist/tools/red-green-command.js +174 -0
  328. package/dist/tools/red-green-process.d.ts +10 -0
  329. package/dist/tools/red-green-process.js +59 -0
  330. package/dist/tools/self-host-processes.d.ts +2 -0
  331. package/dist/tools/self-host-processes.js +32 -13
  332. package/dist/tools/self-host-project.js +13 -78
  333. package/dist/tools/self-host-runtime.js +1 -1
  334. package/dist/tools/self-host.js +42 -10
  335. package/dist/tools/template-command.d.ts +1 -0
  336. package/dist/tools/template-command.js +160 -0
  337. package/dist/tools/template-copy.d.ts +11 -0
  338. package/dist/tools/template-copy.js +130 -0
  339. package/dist/tools/template-files.d.ts +17 -0
  340. package/dist/tools/template-files.js +74 -0
  341. package/dist/tools/workflow-bundles.js +1 -0
  342. package/dist/tools/workflow-candidate-counts.js +2 -2
  343. package/dist/tools/workflow-candidate-shape.d.ts +3 -0
  344. package/dist/tools/workflow-candidate-shape.js +90 -0
  345. package/dist/tools/workflow-candidate-source.js +15 -1
  346. package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
  347. package/dist/tools/workflow-candidate-syntax.js +24 -94
  348. package/dist/tools/workflow-command.js +1 -2
  349. package/dist/tools/workflow-folders.d.ts +2 -3
  350. package/dist/tools/workflow-folders.js +1 -1
  351. package/package.json +16 -8
  352. package/templates/develop/README.md +12 -0
  353. package/templates/develop/develop/flow-tests.ts +37 -0
  354. package/templates/develop/develop/pull.ts +5 -1
  355. package/templates/develop/develop/refusal-tests.ts +77 -0
  356. package/templates/develop/develop/turn.ts +2 -1
  357. package/templates/idea-to-issue/README.md +27 -0
  358. package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
  359. package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
  360. package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
  361. package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
  362. package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
  363. package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
  364. package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
  365. package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
  366. package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
  367. package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
  368. package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
  369. package/templates/idea-to-issue/idea-to-issue.ts +49 -0
  370. package/templates/idea-to-issue/template.json +81 -0
  371. package/templates/review-day/README.md +97 -0
  372. package/templates/review-day/review-day/critique.ts +58 -0
  373. package/templates/review-day/review-day/decision.ts +29 -0
  374. package/templates/review-day/review-day/facts.ts +69 -0
  375. package/templates/review-day/review-day/label.ts +29 -0
  376. package/templates/review-day/review-day/next.ts +28 -0
  377. package/templates/review-day/review-day/post.ts +27 -0
  378. package/templates/review-day/review-day/report.ts +98 -0
  379. package/templates/review-day/review-day/rules.ts +12 -0
  380. package/templates/review-day/review-day/scenarios.ts +76 -0
  381. package/templates/review-day/review-day/turn.ts +73 -0
  382. package/templates/review-day/review-day.declaration.json +16 -0
  383. package/templates/review-day/review-day.test.ts +362 -0
  384. package/templates/review-day/review-day.ts +37 -0
  385. package/templates/review-day/template.json +56 -0
  386. package/dist/src/cli/watch-start-view.d.ts +0 -18
  387. package/dist/src/cli/watch-start-view.js +0 -77
  388. package/dist/src/steps/decision-gate.d.ts +0 -3
  389. package/dist/workflows/develop-prd.d.ts +0 -7
  390. package/dist/workflows/develop-prd.js +0 -165
  391. package/dist/workflows/develop-ticket.d.ts +0 -9
  392. package/dist/workflows/develop-ticket.js +0 -207
  393. package/dist/workflows/issue-labels.d.ts +0 -16
  394. package/dist/workflows/issue-labels.js +0 -70
  395. package/dist/workflows/ticket-prompts.d.ts +0 -35
  396. package/dist/workflows/ticket-prompts.js +0 -147
@@ -1,9 +1,16 @@
1
+ import { type Configuration } from "./configuration-schema.ts";
1
2
  export interface SettingChange {
2
3
  readonly field: string;
3
4
  readonly action: "set" | "unset";
4
5
  readonly value?: string;
5
6
  readonly scope: "project" | "private";
6
7
  }
8
+ export type HarnessSelection = Required<Pick<NonNullable<Configuration["harness"]>, "name" | "kind" | "path">>;
9
+ export interface HarnessChange {
10
+ readonly harness: HarnessSelection;
11
+ readonly scope: "private";
12
+ }
13
+ export declare function selectedHarnessConfiguration(contents: string | undefined, selection: HarnessSelection): string;
7
14
  export type JsonValue = null | boolean | number | string | readonly JsonValue[] | {
8
15
  readonly [name: string]: JsonValue;
9
16
  };
@@ -1,6 +1,20 @@
1
1
  import { configuration, settingScope, validateSetting, } from "./configuration-schema.js";
2
2
  import { configurationValues, parseConfiguration } from "./project-settings.js";
3
3
  import { record } from "./protocol.js";
4
+ export function selectedHarnessConfiguration(contents, selection) {
5
+ const previous = parseConfiguration(contents, "private");
6
+ const harness = previous.harness;
7
+ const same = harness?.name === selection.name &&
8
+ harness.kind === selection.kind &&
9
+ harness.path === selection.path;
10
+ const next = {
11
+ version: 1,
12
+ ...previous,
13
+ harness: { ...(same ? harness : {}), ...selection },
14
+ };
15
+ configuration(next, "private");
16
+ return JSON.stringify(next, null, 2) + "\n";
17
+ }
4
18
  function isJsonValue(value) {
5
19
  if (value === null || typeof value === "boolean" || typeof value === "string")
6
20
  return true;
@@ -1,10 +1,18 @@
1
1
  import type { TurnProfiles } from "./turn-profile.ts";
2
2
  import type { TokenPrices } from "./token-prices.ts";
3
+ export interface RedGreenSettings {
4
+ readonly test: readonly string[];
5
+ readonly testFiles: readonly string[];
6
+ readonly prepare?: readonly string[];
7
+ readonly assertionPattern?: string;
8
+ readonly skipPattern?: string;
9
+ }
3
10
  export interface Configuration {
4
11
  readonly version: 1;
5
12
  readonly checks?: {
6
13
  readonly beforeMerge?: readonly string[];
7
14
  readonly required?: readonly string[];
15
+ readonly redGreen?: RedGreenSettings;
8
16
  };
9
17
  readonly tickets?: {
10
18
  readonly command?: readonly string[];
@@ -13,6 +21,7 @@ export interface Configuration {
13
21
  readonly queue?: {
14
22
  readonly everySeconds?: number;
15
23
  readonly lanes?: number;
24
+ readonly dailySpendLimitUsd?: number;
16
25
  };
17
26
  readonly harness?: {
18
27
  readonly name?: string;
@@ -88,12 +88,16 @@ function validate(value, checked) {
88
88
  scalar(value, checked);
89
89
  if (schema.type === "object")
90
90
  validateObject(value, checked);
91
- if (schema.type !== "array")
92
- return;
91
+ if (schema.type === "array")
92
+ validateArray(value, checked);
93
+ }
94
+ function validateArray(value, { schema, field }) {
93
95
  if (!Array.isArray(value))
94
96
  invalid(field);
95
97
  if (schema.maxItems !== undefined && value.length > schema.maxItems)
96
98
  invalid(field);
99
+ if (schema.minItems !== undefined && value.length < schema.minItems)
100
+ invalid(field);
97
101
  if (schema.items === undefined)
98
102
  return;
99
103
  for (const [index, item] of value.entries())
@@ -0,0 +1,6 @@
1
+ import { type FileHandle } from "node:fs/promises";
2
+ export declare function openedAttachment(place: {
3
+ readonly folder: string;
4
+ readonly name: string;
5
+ }): Promise<FileHandle>;
6
+ export declare function copiedAttachment(handle: FileHandle, copy: string): Promise<void>;
@@ -0,0 +1,86 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, open, rm } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ const maximumBytes = 104_857_600;
5
+ const chunkBytes = 1_048_576;
6
+ const pngSignature = Buffer.from([
7
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
8
+ ]);
9
+ const webmSignature = Buffer.from([0x1a, 0x45, 0xdf, 0xa3]);
10
+ const signatures = new Map([
11
+ ["mp4", (head) => head.subarray(4, 8).toString("latin1") === "ftyp"],
12
+ ["webm", (head) => head.subarray(0, 4).equals(webmSignature)],
13
+ ["png", (head) => head.subarray(0, 8).equals(pngSignature)],
14
+ ]);
15
+ function listedStatus(path) {
16
+ return lstat(path).catch(() => undefined);
17
+ }
18
+ async function realFolder(path) {
19
+ const status = await listedStatus(path);
20
+ return (status !== undefined && status.isDirectory() && !status.isSymbolicLink());
21
+ }
22
+ async function realFolders(folder) {
23
+ return (await realFolder(dirname(folder))) && (await realFolder(folder));
24
+ }
25
+ function sameFile(opened, listed) {
26
+ return (listed !== undefined &&
27
+ listed.isFile() &&
28
+ listed.ino === opened.ino &&
29
+ listed.dev === opened.dev);
30
+ }
31
+ async function signed(handle, name) {
32
+ const head = Buffer.alloc(8);
33
+ const { bytesRead } = await handle.read(head, 0, 8, 0);
34
+ const check = signatures.get(name.slice(name.lastIndexOf(".") + 1));
35
+ return bytesRead === 8 && check !== undefined && check(head);
36
+ }
37
+ async function checkedHandle(handle, place) {
38
+ const opened = await handle.stat();
39
+ const listed = await listedStatus(join(place.folder, place.name));
40
+ if (!opened.isFile() || opened.nlink !== 1 || !sameFile(opened, listed))
41
+ throw new Error("attachment-not-available");
42
+ if (!(await realFolders(place.folder)))
43
+ throw new Error("attachment-not-available");
44
+ if (opened.size > maximumBytes)
45
+ throw new Error("attachment-too-large");
46
+ if (!(await signed(handle, place.name)))
47
+ throw new Error("attachment-not-available");
48
+ }
49
+ export async function openedAttachment(place) {
50
+ if (!(await realFolders(place.folder)))
51
+ throw new Error("attachment-not-available");
52
+ const handle = await open(join(place.folder, place.name), constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK).catch(() => undefined);
53
+ if (handle === undefined)
54
+ throw new Error("attachment-not-available");
55
+ try {
56
+ await checkedHandle(handle, place);
57
+ return handle;
58
+ }
59
+ catch (error) {
60
+ await handle.close();
61
+ throw error;
62
+ }
63
+ }
64
+ async function copiedChunks(source, target) {
65
+ const chunk = Buffer.alloc(chunkBytes);
66
+ let position = 0;
67
+ for (;;) {
68
+ const { bytesRead } = await source.read(chunk, 0, chunkBytes, position);
69
+ if (bytesRead === 0)
70
+ return;
71
+ position += bytesRead;
72
+ if (position > maximumBytes)
73
+ throw new Error("attachment-too-large");
74
+ await target.write(chunk, 0, bytesRead);
75
+ }
76
+ }
77
+ export async function copiedAttachment(handle, copy) {
78
+ await rm(copy, { force: true });
79
+ const target = await open(copy, "wx");
80
+ try {
81
+ await copiedChunks(handle, target);
82
+ }
83
+ finally {
84
+ await target.close();
85
+ }
86
+ }
@@ -0,0 +1,14 @@
1
+ export declare function attachmentFolder(place: {
2
+ readonly worktrees: string;
3
+ readonly target: string;
4
+ }): string;
5
+ export declare function attachmentEnvironment(settings: {
6
+ readonly worktrees: string;
7
+ }, start: {
8
+ readonly intent: {
9
+ readonly target: string;
10
+ };
11
+ readonly profile: {
12
+ readonly env?: Readonly<Record<string, string>>;
13
+ };
14
+ }): Promise<Readonly<Record<string, string>>>;
@@ -0,0 +1,17 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { treeName } from "./work-tree.js";
4
+ export function attachmentFolder(place) {
5
+ return join(dirname(place.worktrees), "attachments", treeName(place.target));
6
+ }
7
+ export async function attachmentEnvironment(settings, start) {
8
+ const attachments = attachmentFolder({
9
+ worktrees: settings.worktrees,
10
+ target: start.intent.target,
11
+ });
12
+ await mkdir(attachments, { recursive: true });
13
+ return {
14
+ ...(start.profile.env ?? {}),
15
+ CLOVING_ATTACHMENTS_DIRECTORY: attachments,
16
+ };
17
+ }
@@ -0,0 +1,50 @@
1
+ import type { TurnEnd } from "./claude-turn.ts";
2
+ import { type Located, type WorkerReport } from "./operation-journal.ts";
3
+ import type { WorkTree } from "./work-tree.ts";
4
+ import { type WorkerProfiles } from "./worker-profile.ts";
5
+ import type { AdapterOutcome, DeliveryIntent, ProtectedIntent } from "../broker/actor/delivery-intents.ts";
6
+ export interface TurnResume {
7
+ readonly startedAt: string;
8
+ readonly turnStartCommit: string | null;
9
+ readonly sessionId: string;
10
+ readonly ends: readonly TurnEnd[];
11
+ }
12
+ export declare const resumePrompt = "This turn stopped because the Cloving daemon restarted. Continue the task from the point where it stopped. Run again each command or subagent that did not end. End with the result line that the task asks for.";
13
+ export declare function turnIntent(intent: DeliveryIntent): intent is ProtectedIntent;
14
+ export declare function resumableHarness(harness: unknown): boolean;
15
+ export declare function resumedCommand(request: {
16
+ readonly worker: string | undefined;
17
+ readonly command: readonly string[];
18
+ readonly sessionId: string;
19
+ }): readonly string[] | undefined;
20
+ export declare function recordedField(value: unknown, name: string): unknown;
21
+ export declare function processAlive(processId: unknown): boolean;
22
+ export declare function uncertainProcess(started: unknown): Promise<boolean>;
23
+ export declare function recordedTree(started: unknown): WorkTree | undefined;
24
+ export declare function resumePlan(settings: WorkerProfiles & {
25
+ readonly stopMilliseconds?: number;
26
+ }, request: {
27
+ readonly folder: string;
28
+ readonly started: unknown;
29
+ readonly intent: ProtectedIntent;
30
+ readonly signal: AbortSignal;
31
+ }): Promise<"worktree-index-unknown" | "worktree-index-locked" | "claude-turn-interrupted" | {
32
+ resume: TurnResume;
33
+ tree: WorkTree;
34
+ profile: import("../turn-profile.ts").TurnProfile;
35
+ harness: {
36
+ readonly worker: string;
37
+ readonly command: readonly string[];
38
+ readonly shell?: string;
39
+ readonly output?: "text";
40
+ };
41
+ }>;
42
+ export declare function readResume(folder: string, started: unknown): Promise<TurnResume | undefined>;
43
+ export declare function recordedHarness(journal: string, operationId: string): Promise<string | undefined>;
44
+ export declare function interruptedReply(place: Located, reason: string): Promise<AdapterOutcome>;
45
+ export declare function recoverTurn(operation: {
46
+ readonly intent: ProtectedIntent;
47
+ readonly journal: string;
48
+ readonly report: (report: WorkerReport) => Promise<unknown>;
49
+ readonly signal: AbortSignal;
50
+ }, reconcile: () => Promise<AdapterOutcome>): Promise<void>;
@@ -0,0 +1,204 @@
1
+ import { usageOf, priceOf } from "../worker-usage.js";
2
+ import { located, readRecord, writeRecord, interrupted, replied, reportOf, } from "./operation-journal.js";
3
+ import { turnHarness } from "../harness-defaults.js";
4
+ import { selectedProfile } from "./worker-profile.js";
5
+ import { recordedProcessDirectory } from "./worktree-processes.js";
6
+ import { resumeWorktree } from "./resume-worktree.js";
7
+ export const resumePrompt = "This turn stopped because the Cloving daemon restarted. Continue the task from the point where it stopped. Run again each command or subagent that did not end. End with the result line that the task asks for.";
8
+ export function turnIntent(intent) {
9
+ return (intent.capability === "claude" &&
10
+ intent.method !== "run-turn:analyze-chats" &&
11
+ (intent.method === "run-turn" ||
12
+ /^run-turn:[A-Za-z0-9_-]{1,119}$/.test(intent.method ?? "")) &&
13
+ intent.target !== undefined &&
14
+ intent.payload !== undefined &&
15
+ intent.leaseGeneration !== undefined);
16
+ }
17
+ export function resumableHarness(harness) {
18
+ return harness === "claude" || harness === "codex";
19
+ }
20
+ export function resumedCommand(request) {
21
+ const { worker = "claude", command, sessionId } = request;
22
+ if (worker === "codex")
23
+ return codexResume(command, sessionId);
24
+ if (worker !== "claude")
25
+ return undefined;
26
+ const separator = command.indexOf("--");
27
+ const boundary = separator < 0 ? command.length : separator;
28
+ return [
29
+ ...command.slice(0, boundary),
30
+ "--resume",
31
+ sessionId,
32
+ ...command.slice(boundary),
33
+ ];
34
+ }
35
+ function codexResume(command, sessionId) {
36
+ const exec = command.indexOf("exec");
37
+ if (exec < 0)
38
+ return undefined;
39
+ return [
40
+ ...command.slice(0, exec + 1),
41
+ "resume",
42
+ sessionId,
43
+ ...command.slice(exec + 1),
44
+ ];
45
+ }
46
+ export function recordedField(value, name) {
47
+ if (typeof value !== "object" || value === null)
48
+ return undefined;
49
+ return Reflect.get(value, name);
50
+ }
51
+ export function processAlive(processId) {
52
+ if (typeof processId !== "number")
53
+ return false;
54
+ try {
55
+ process.kill(processId, 0);
56
+ return true;
57
+ }
58
+ catch (error) {
59
+ return recordedField(error, "code") === "EPERM";
60
+ }
61
+ }
62
+ export async function uncertainProcess(started) {
63
+ const processId = recordedField(started, "processId");
64
+ if (typeof processId !== "number" || !processAlive(processId))
65
+ return false;
66
+ return (!resumableHarness(recordedField(started, "harness")) ||
67
+ (await recordedProcessDirectory(processId)) === undefined);
68
+ }
69
+ export function recordedTree(started) {
70
+ const path = recordedField(started, "worktree");
71
+ const branch = recordedField(started, "branch");
72
+ const startCommit = recordedField(started, "startCommit");
73
+ return typeof path === "string" &&
74
+ typeof branch === "string" &&
75
+ typeof startCommit === "string"
76
+ ? { path, branch, startCommit }
77
+ : undefined;
78
+ }
79
+ export async function resumePlan(settings, request) {
80
+ const { folder, started, intent, signal } = request;
81
+ const resume = await readResume(folder, started);
82
+ const tree = recordedTree(started);
83
+ if (resume === undefined || tree === undefined)
84
+ return "claude-turn-interrupted";
85
+ const profile = await selectedProfile(settings, intent);
86
+ if (typeof profile === "string")
87
+ return "claude-turn-interrupted";
88
+ const harness = turnHarness(settings, profile);
89
+ if (recordedField(started, "harness") !== harness.worker ||
90
+ resumedCommand({
91
+ worker: harness.worker,
92
+ command: harness.command,
93
+ sessionId: resume.sessionId,
94
+ }) === undefined)
95
+ return "claude-turn-interrupted";
96
+ const locked = await resumeWorktree({
97
+ ...settings,
98
+ directory: tree.path,
99
+ folder,
100
+ signal,
101
+ });
102
+ return locked === null ? { resume, tree, profile, harness } : locked.reason;
103
+ }
104
+ function priorEnd(record) {
105
+ const field = (name) => recordedField(record, name);
106
+ const sessionId = field("sessionId");
107
+ const model = field("model");
108
+ const retryKind = field("retryKind");
109
+ return {
110
+ ...(retryKind === "capacity" ||
111
+ retryKind === "network" ||
112
+ retryKind === null
113
+ ? { retryKind }
114
+ : {}),
115
+ ...(field("resumedAfter") === "daemon-restart"
116
+ ? { resumedAfter: "daemon-restart" }
117
+ : {}),
118
+ exitCode: null,
119
+ result: {
120
+ sessionId: typeof sessionId === "string" ? sessionId : null,
121
+ model: typeof model === "string" ? model : null,
122
+ text: "",
123
+ failed: true,
124
+ costUsd: recordedSessionCost(record),
125
+ turns: typeof field("turns") === "number" ? Number(field("turns")) : null,
126
+ usage: usageOf(field("usage")),
127
+ },
128
+ };
129
+ }
130
+ function recordedSessionCost(record) {
131
+ const fields = typeof record === "object" && record !== null ? record : {};
132
+ const name = Object.hasOwn(fields, "sessionCostUsd")
133
+ ? "sessionCostUsd"
134
+ : "costUsd";
135
+ return priceOf(Reflect.get(fields, name));
136
+ }
137
+ function resumeHeader(started) {
138
+ if (recordedField(started, "phase") === "waiting")
139
+ return undefined;
140
+ const attempt = recordedField(started, "attempt");
141
+ const startedAt = recordedField(started, "startedAt");
142
+ const head = recordedField(started, "turnStartCommit");
143
+ if (typeof attempt !== "number" ||
144
+ !Number.isSafeInteger(attempt) ||
145
+ attempt < 1 ||
146
+ attempt > 5 ||
147
+ typeof startedAt !== "string")
148
+ return undefined;
149
+ return {
150
+ attempt,
151
+ startedAt,
152
+ turnStartCommit: typeof head === "string" ? head : null,
153
+ };
154
+ }
155
+ export async function readResume(folder, started) {
156
+ const header = resumeHeader(started);
157
+ if (header === undefined)
158
+ return undefined;
159
+ const records = [];
160
+ for (let number = 1; number <= header.attempt; number += 1)
161
+ records.push(await readRecord(folder, `attempt-${String(number)}.json`));
162
+ const sessionId = recordedField(records.at(-1), "sessionId");
163
+ if (typeof sessionId !== "string" ||
164
+ sessionId === "" ||
165
+ records.filter((record) => recordedField(record, "resumedAfter") === "daemon-restart").length >= 2)
166
+ return undefined;
167
+ return {
168
+ sessionId,
169
+ ends: records.map(priorEnd),
170
+ startedAt: header.startedAt,
171
+ turnStartCommit: header.turnStartCommit,
172
+ };
173
+ }
174
+ export async function recordedHarness(journal, operationId) {
175
+ const { folder } = located(journal, operationId);
176
+ const started = await readRecord(folder, "started.json").catch(() => undefined);
177
+ const harness = recordedField(started, "harness");
178
+ return typeof harness === "string" ? harness : undefined;
179
+ }
180
+ export async function interruptedReply(place, reason) {
181
+ const ending = interrupted(reason);
182
+ await writeRecord(place.folder, { name: "result.json", value: ending });
183
+ return replied({ receipt: place.key, worker: "claude" }, ending);
184
+ }
185
+ export async function recoverTurn(operation, reconcile) {
186
+ const { intent, journal, report } = operation;
187
+ if (!resumableHarness(await recordedHarness(journal, intent.operationId)))
188
+ return;
189
+ const result = await reconcile();
190
+ if (operation.signal.aborted)
191
+ return;
192
+ if (result.kind === "completed" ||
193
+ result.kind === "failed" ||
194
+ result.kind === "stopped")
195
+ await report(reportOf({
196
+ intent,
197
+ worker: "claude",
198
+ commandId: `claude-turn:${located(journal, intent.operationId).key}`,
199
+ }, {
200
+ ...result,
201
+ outcome: result.kind,
202
+ endedAt: new Date().toISOString(),
203
+ }));
204
+ }
@@ -0,0 +1,27 @@
1
+ import type { ReviewVerdict } from "../review-subject.ts";
2
+ import type { TicketStatus } from "../ticket-status.ts";
3
+ import { type WorkerUsage, type WorkerAttemptUsage, type WorkerModelUsage, type RetryKind } from "../worker-usage.ts";
4
+ export type Worker = string;
5
+ export interface StreamResult {
6
+ readonly reviewFeedback?: string;
7
+ readonly reviewVerdict?: ReviewVerdict | null;
8
+ readonly models?: readonly WorkerModelUsage[];
9
+ readonly ticketStatusTooLarge?: true;
10
+ readonly ticketStatus?: TicketStatus;
11
+ readonly attempts?: readonly WorkerAttemptUsage[];
12
+ readonly pricingModel?: string | null;
13
+ readonly subtype?: string;
14
+ readonly errorType?: string;
15
+ readonly model: string | null;
16
+ readonly text: string;
17
+ readonly failed: boolean;
18
+ readonly costUsd: number | null;
19
+ readonly usage: WorkerUsage;
20
+ readonly sessionId: string | null;
21
+ readonly turns: number | null;
22
+ }
23
+ export declare function parsed(line: string): unknown;
24
+ export declare function textOf(value: unknown): string | null;
25
+ export declare function capacityRefusal(result: StreamResult | undefined): boolean;
26
+ export declare function retryKind(result: StreamResult | undefined): RetryKind | null;
27
+ export declare function streamResult(line: string, worker?: Worker): StreamResult | undefined;
@@ -0,0 +1,63 @@
1
+ import { grokResultFields } from "../grok-result.js";
2
+ import { priceOf, modelUsageOf, usageOf, } from "../worker-usage.js";
3
+ export function parsed(line) {
4
+ try {
5
+ const value = JSON.parse(line);
6
+ return value;
7
+ }
8
+ catch {
9
+ return undefined;
10
+ }
11
+ }
12
+ function numberOf(value) {
13
+ return typeof value === "number" ? value : null;
14
+ }
15
+ export function textOf(value) {
16
+ return typeof value === "string" ? value : null;
17
+ }
18
+ function networkFailure(result) {
19
+ return (result?.failed === true &&
20
+ result.text.startsWith("API Error: Can't reach the API server"));
21
+ }
22
+ export function capacityRefusal(result) {
23
+ if (networkFailure(result))
24
+ return false;
25
+ return (result?.failed === true &&
26
+ ["success", "error_during_execution"].includes(result.subtype ?? "error_during_execution") &&
27
+ (result.text ===
28
+ "Selected model is at capacity. Please try a different model." ||
29
+ result.errorType === "overloaded"));
30
+ }
31
+ export function retryKind(result) {
32
+ if (networkFailure(result))
33
+ return "network";
34
+ return capacityRefusal(result) ? "capacity" : null;
35
+ }
36
+ export function streamResult(line, worker) {
37
+ if (!line.includes('"result"'))
38
+ return undefined;
39
+ const record = parsed(line);
40
+ if (typeof record !== "object" || record === null)
41
+ return undefined;
42
+ const field = (name) => Reflect.get(record, name);
43
+ if (field("type") !== "result")
44
+ return undefined;
45
+ const models = modelUsageOf(field("models"));
46
+ return {
47
+ ...(models === undefined ? {} : { models }),
48
+ ...(typeof field("subtype") === "string"
49
+ ? { subtype: String(field("subtype")) }
50
+ : {}),
51
+ ...(typeof field("error") === "string"
52
+ ? { errorType: String(field("error")) }
53
+ : {}),
54
+ text: textOf(field("result")) ?? "",
55
+ failed: field("is_error") === true,
56
+ costUsd: priceOf(field("total_cost_usd")),
57
+ usage: usageOf(field("usage")),
58
+ model: textOf(field("model")),
59
+ sessionId: textOf(field("session_id")),
60
+ turns: numberOf(field("num_turns")),
61
+ ...(worker === "grok" ? grokResultFields(record) : {}),
62
+ };
63
+ }
@@ -1,26 +1,10 @@
1
- import type { ReviewVerdict } from "../review-subject.ts";
2
- import type { TicketStatus } from "../ticket-status.ts";
3
- import { type WorkerUsage, type WorkerAttemptUsage, type WorkerModelUsage, type RetryKind } from "../worker-usage.ts";
4
- export type Worker = string;
5
- export interface StreamResult {
6
- readonly reviewFeedback?: string;
7
- readonly reviewVerdict?: ReviewVerdict | null;
8
- readonly models?: readonly WorkerModelUsage[];
9
- readonly ticketStatusTooLarge?: true;
10
- readonly ticketStatus?: TicketStatus;
11
- readonly attempts?: readonly WorkerAttemptUsage[];
12
- readonly pricingModel?: string | null;
13
- readonly subtype?: string;
14
- readonly errorType?: string;
15
- readonly model: string | null;
16
- readonly text: string;
17
- readonly failed: boolean;
18
- readonly costUsd: number | null;
19
- readonly usage: WorkerUsage;
20
- readonly sessionId: string | null;
21
- readonly turns: number | null;
22
- }
1
+ import { type Worker, type StreamResult } from "./claude-stream.ts";
2
+ import { type RetryKind } from "../worker-usage.ts";
3
+ export { streamResult, capacityRefusal, retryKind } from "./claude-stream.ts";
4
+ export type { Worker, StreamResult } from "./claude-stream.ts";
23
5
  export interface TurnEnd {
6
+ readonly retryKind?: RetryKind | null;
7
+ readonly resumedAfter?: "daemon-restart";
24
8
  readonly reason?: string;
25
9
  readonly detail?: string;
26
10
  readonly stopped?: boolean;
@@ -28,6 +12,7 @@ export interface TurnEnd {
28
12
  readonly result: StreamResult | undefined;
29
13
  }
30
14
  export interface TurnStart {
15
+ readonly progress?: (progress: TurnProgress) => Promise<void>;
31
16
  readonly resultBytes?: number;
32
17
  readonly output?: "text";
33
18
  readonly shell?: string;
@@ -40,14 +25,15 @@ export interface TurnStart {
40
25
  readonly activityFolder?: string;
41
26
  readonly prompt: string;
42
27
  }
28
+ export interface TurnProgress {
29
+ readonly sessionId: string | null;
30
+ readonly result: StreamResult | undefined;
31
+ }
43
32
  export interface RunningTurn {
44
33
  readonly processId: number | null;
45
34
  readonly ended: Promise<TurnEnd>;
46
35
  readonly stop: (graceMilliseconds: number) => void;
47
36
  }
48
- export declare function capacityRefusal(result: StreamResult | undefined): boolean;
49
- export declare function retryKind(result: StreamResult | undefined): RetryKind | null;
50
37
  export declare function succeeded(end: TurnEnd): boolean;
51
- export declare function streamResult(line: string, worker?: Worker): StreamResult | undefined;
52
38
  export declare function turnEnvironment(configuration: string, start: TurnStart): NodeJS.ProcessEnv;
53
39
  export declare function startTurn(start: TurnStart): RunningTurn;