cloving 1.3.0 → 1.5.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 (484) hide show
  1. package/README.md +329 -215
  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-health.d.ts +9 -0
  32. package/dist/src/broker/actor/authority-health.js +24 -0
  33. package/dist/src/broker/actor/authority-queries.d.ts +2 -1
  34. package/dist/src/broker/actor/authority-queries.js +14 -5
  35. package/dist/src/broker/actor/authority-receipts.js +1 -1
  36. package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
  37. package/dist/src/broker/actor/authority-runtime.js +29 -20
  38. package/dist/src/broker/actor/authority-session.d.ts +6 -19
  39. package/dist/src/broker/actor/authority-session.js +66 -88
  40. package/dist/src/broker/actor/authority-settings.d.ts +2 -1
  41. package/dist/src/broker/actor/authority-settings.js +6 -3
  42. package/dist/src/broker/actor/authority-upgrades.d.ts +23 -2
  43. package/dist/src/broker/actor/authority-upgrades.js +8 -2
  44. package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
  45. package/dist/src/broker/actor/authority-watchdog.js +31 -9
  46. package/dist/src/broker/actor/authority.js +3 -1
  47. package/dist/src/broker/actor/delivery-intents.js +2 -0
  48. package/dist/src/broker/actor/effect-delivery.d.ts +1 -1
  49. package/dist/src/broker/actor/effect-delivery.js +15 -2
  50. package/dist/src/broker/actor/effect-plan.js +11 -2
  51. package/dist/src/broker/actor/effect-queries.d.ts +4 -0
  52. package/dist/src/broker/actor/effect-queries.js +9 -1
  53. package/dist/src/broker/actor/effect-turn.js +2 -0
  54. package/dist/src/broker/actor/projection-memory.d.ts +43 -0
  55. package/dist/src/broker/actor/projection-memory.js +207 -0
  56. package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
  57. package/dist/src/broker/actor/runtime-parts.js +8 -3
  58. package/dist/src/broker/actor/stop-plan.js +9 -3
  59. package/dist/src/broker/actor/stop-turn.d.ts +2 -0
  60. package/dist/src/broker/actor/stop-turn.js +24 -11
  61. package/dist/src/broker/actor/turn-draft.d.ts +1 -0
  62. package/dist/src/broker/actor/turn-draft.js +4 -0
  63. package/dist/src/broker/actor/turn-state.js +5 -1
  64. package/dist/src/broker/authority-admission.js +60 -0
  65. package/dist/src/broker/authority-restore.d.ts +2 -0
  66. package/dist/src/broker/authority-restore.js +35 -1
  67. package/dist/src/broker/command-wait-restore.d.ts +31 -0
  68. package/dist/src/broker/command-wait-restore.js +86 -0
  69. package/dist/src/broker/decision-restore.d.ts +1 -1
  70. package/dist/src/broker/decision-restore.js +1 -0
  71. package/dist/src/broker/effect-upgrade.d.ts +3 -0
  72. package/dist/src/broker/effect-upgrade.js +11 -2
  73. package/dist/src/cli/arguments.d.ts +13 -0
  74. package/dist/src/cli/arguments.js +43 -3
  75. package/dist/src/cli/chat-stores.d.ts +2 -0
  76. package/dist/src/cli/chat-stores.js +113 -0
  77. package/dist/src/cli/client.d.ts +7 -2
  78. package/dist/src/cli/client.js +13 -7
  79. package/dist/src/cli/command-requests.d.ts +46 -0
  80. package/dist/src/cli/command-requests.js +84 -0
  81. package/dist/src/cli/command-waits.d.ts +9 -0
  82. package/dist/src/cli/command-waits.js +51 -0
  83. package/dist/src/cli/commands.js +70 -88
  84. package/dist/src/cli/config-file.d.ts +2 -2
  85. package/dist/src/cli/config-file.js +4 -2
  86. package/dist/src/cli/config-notice.js +5 -2
  87. package/dist/src/cli/doctor-retention.d.ts +2 -0
  88. package/dist/src/cli/doctor-retention.js +93 -0
  89. package/dist/src/cli/doctor-workflows.d.ts +5 -2
  90. package/dist/src/cli/doctor-workflows.js +12 -7
  91. package/dist/src/cli/doctor.js +11 -9
  92. package/dist/src/cli/harness-probes.d.ts +2 -0
  93. package/dist/src/cli/harness-probes.js +1 -1
  94. package/dist/src/cli/harness-processes.d.ts +6 -0
  95. package/dist/src/cli/harness-processes.js +36 -0
  96. package/dist/src/cli/init-command.d.ts +9 -0
  97. package/dist/src/cli/init-command.js +52 -0
  98. package/dist/src/cli/init-prompt-command.d.ts +10 -0
  99. package/dist/src/cli/init-prompt-command.js +145 -0
  100. package/dist/src/cli/init-prompt.d.ts +35 -0
  101. package/dist/src/cli/init-prompt.js +74 -0
  102. package/dist/src/cli/init-selection.d.ts +13 -0
  103. package/dist/src/cli/init-selection.js +75 -0
  104. package/dist/src/cli/main.d.ts +2 -0
  105. package/dist/src/cli/main.js +37 -7
  106. package/dist/src/cli/mcp-server.d.ts +1 -0
  107. package/dist/src/cli/mcp-server.js +156 -0
  108. package/dist/src/cli/mcp-tools.d.ts +15 -0
  109. package/dist/src/cli/mcp-tools.js +242 -0
  110. package/dist/src/cli/queue-arguments.d.ts +15 -0
  111. package/dist/src/cli/queue-arguments.js +31 -0
  112. package/dist/src/cli/queue-render.d.ts +3 -0
  113. package/dist/src/cli/queue-render.js +26 -0
  114. package/dist/src/cli/reload-render.d.ts +2 -0
  115. package/dist/src/cli/reload-render.js +12 -0
  116. package/dist/src/cli/render.d.ts +1 -1
  117. package/dist/src/cli/render.js +54 -38
  118. package/dist/src/cli/report-ci-jobs.d.ts +23 -0
  119. package/dist/src/cli/report-ci-jobs.js +103 -0
  120. package/dist/src/cli/report-ci-usage.d.ts +9 -0
  121. package/dist/src/cli/report-ci-usage.js +185 -0
  122. package/dist/src/cli/report-ci.d.ts +13 -0
  123. package/dist/src/cli/report-ci.js +74 -0
  124. package/dist/src/cli/report-closures.d.ts +6 -0
  125. package/dist/src/cli/report-closures.js +97 -0
  126. package/dist/src/cli/report-flow.d.ts +7 -0
  127. package/dist/src/cli/report-flow.js +122 -0
  128. package/dist/src/cli/report-github-reader.d.ts +29 -0
  129. package/dist/src/cli/report-github-reader.js +157 -0
  130. package/dist/src/cli/report-github.d.ts +15 -8
  131. package/dist/src/cli/report-github.js +131 -150
  132. package/dist/src/cli/report-operator.d.ts +3 -0
  133. package/dist/src/cli/report-operator.js +40 -0
  134. package/dist/src/cli/report-ready.d.ts +3 -0
  135. package/dist/src/cli/report-ready.js +96 -0
  136. package/dist/src/cli/report-text.d.ts +9 -0
  137. package/dist/src/cli/report-text.js +33 -0
  138. package/dist/src/cli/report.d.ts +1 -0
  139. package/dist/src/cli/report.js +104 -27
  140. package/dist/src/cli/runtime-arguments.d.ts +18 -3
  141. package/dist/src/cli/runtime-arguments.js +29 -20
  142. package/dist/src/cli/schedule-arguments.d.ts +14 -0
  143. package/dist/src/cli/schedule-arguments.js +26 -0
  144. package/dist/src/cli/schedule-render.d.ts +22 -0
  145. package/dist/src/cli/schedule-render.js +73 -0
  146. package/dist/src/cli/terminal-text.d.ts +3 -0
  147. package/dist/src/cli/terminal-text.js +28 -0
  148. package/dist/src/cli/toolchain.d.ts +1 -0
  149. package/dist/src/cli/toolchain.js +1 -0
  150. package/dist/src/cli/usage-render.d.ts +1 -0
  151. package/dist/src/cli/usage-render.js +28 -1
  152. package/dist/src/cli/usage.d.ts +2 -2
  153. package/dist/src/cli/usage.js +89 -11
  154. package/dist/src/cli/watch-actions.js +2 -2
  155. package/dist/src/cli/watch-api-document.d.ts +430 -0
  156. package/dist/src/cli/watch-api-document.js +291 -0
  157. package/dist/src/cli/watch-api-run.d.ts +56 -0
  158. package/dist/src/cli/watch-api-run.js +112 -0
  159. package/dist/src/cli/watch-api.d.ts +17 -0
  160. package/dist/src/cli/watch-api.js +230 -0
  161. package/dist/src/cli/watch-board-view.js +19 -2
  162. package/dist/src/cli/watch-board.d.ts +4 -2
  163. package/dist/src/cli/watch-board.js +53 -43
  164. package/dist/src/cli/watch-card-forms.d.ts +1 -1
  165. package/dist/src/cli/watch-card-forms.js +11 -10
  166. package/dist/src/cli/watch-client.d.ts +1 -1
  167. package/dist/src/cli/watch-client.js +2 -11
  168. package/dist/src/cli/watch-header-view.d.ts +1 -5
  169. package/dist/src/cli/watch-header-view.js +17 -21
  170. package/dist/src/cli/watch-model.d.ts +5 -1
  171. package/dist/src/cli/watch-model.js +20 -11
  172. package/dist/src/cli/watch-page.js +15 -15
  173. package/dist/src/cli/watch-phases.d.ts +12 -3
  174. package/dist/src/cli/watch-phases.js +68 -11
  175. package/dist/src/cli/watch-pr-board.js +1 -1
  176. package/dist/src/cli/watch-pr-command.d.ts +1 -0
  177. package/dist/src/cli/watch-pull-request.js +18 -8
  178. package/dist/src/cli/watch-reads.d.ts +3 -0
  179. package/dist/src/cli/watch-reads.js +22 -20
  180. package/dist/src/cli/watch-render.d.ts +15 -0
  181. package/dist/src/cli/watch-run-input.d.ts +0 -1
  182. package/dist/src/cli/watch-run-input.js +0 -13
  183. package/dist/src/cli/watch-server.js +24 -10
  184. package/dist/src/cli/watch-view.d.ts +0 -3
  185. package/dist/src/cli/watch-view.js +13 -13
  186. package/dist/src/cli.js +73 -12
  187. package/dist/src/command-wait.d.ts +4 -0
  188. package/dist/src/command-wait.js +45 -0
  189. package/dist/src/configuration-change.d.ts +7 -0
  190. package/dist/src/configuration-change.js +14 -0
  191. package/dist/src/configuration-display.js +2 -0
  192. package/dist/src/configuration-schema.d.ts +14 -0
  193. package/dist/src/configuration-schema.js +6 -2
  194. package/dist/src/daemon/attachment-file.d.ts +6 -0
  195. package/dist/src/daemon/attachment-file.js +86 -0
  196. package/dist/src/daemon/attachments.d.ts +14 -0
  197. package/dist/src/daemon/attachments.js +17 -0
  198. package/dist/src/daemon/claude-recovery.d.ts +50 -0
  199. package/dist/src/daemon/claude-recovery.js +208 -0
  200. package/dist/src/daemon/claude-stream.d.ts +27 -0
  201. package/dist/src/daemon/claude-stream.js +63 -0
  202. package/dist/src/daemon/claude-turn.d.ts +11 -25
  203. package/dist/src/daemon/claude-turn.js +64 -81
  204. package/dist/src/daemon/claude-worker.d.ts +5 -4
  205. package/dist/src/daemon/claude-worker.js +127 -126
  206. package/dist/src/daemon/daemon-adapters.d.ts +9 -0
  207. package/dist/src/daemon/daemon-adapters.js +33 -5
  208. package/dist/src/daemon/daemon-loops.d.ts +5 -1
  209. package/dist/src/daemon/daemon-loops.js +18 -10
  210. package/dist/src/daemon/daemon.js +80 -61
  211. package/dist/src/daemon/github-attach.d.ts +2 -0
  212. package/dist/src/daemon/github-attach.js +222 -0
  213. package/dist/src/daemon/github-calls.js +1 -1
  214. package/dist/src/daemon/github-ci-filters.d.ts +6 -0
  215. package/dist/src/daemon/github-ci-filters.js +138 -0
  216. package/dist/src/daemon/github-ci-workflows.d.ts +10 -0
  217. package/dist/src/daemon/github-ci-workflows.js +148 -0
  218. package/dist/src/daemon/github-ci.js +22 -4
  219. package/dist/src/daemon/github-issue-methods.d.ts +2 -0
  220. package/dist/src/daemon/github-issue-methods.js +37 -2
  221. package/dist/src/daemon/github-merge-call.d.ts +2 -1
  222. package/dist/src/daemon/github-merge-call.js +10 -3
  223. package/dist/src/daemon/github-merge.js +52 -24
  224. package/dist/src/daemon/github-methods.js +18 -4
  225. package/dist/src/daemon/github-operation.d.ts +4 -0
  226. package/dist/src/daemon/github-operation.js +6 -0
  227. package/dist/src/daemon/github-worker.d.ts +4 -0
  228. package/dist/src/daemon/github-worker.js +6 -0
  229. package/dist/src/daemon/issue-queue.d.ts +4 -1
  230. package/dist/src/daemon/issue-queue.js +76 -78
  231. package/dist/src/daemon/merge-turns.d.ts +10 -0
  232. package/dist/src/daemon/merge-turns.js +37 -0
  233. package/dist/src/daemon/notify-events.d.ts +6 -0
  234. package/dist/src/daemon/notify-events.js +84 -0
  235. package/dist/src/daemon/notify-journal.js +1 -1
  236. package/dist/src/daemon/notify-message.d.ts +4 -1
  237. package/dist/src/daemon/notify-message.js +36 -0
  238. package/dist/src/daemon/notify.d.ts +1 -1
  239. package/dist/src/daemon/notify.js +5 -77
  240. package/dist/src/daemon/operation-journal.d.ts +1 -0
  241. package/dist/src/daemon/queue-control.d.ts +13 -0
  242. package/dist/src/daemon/queue-control.js +86 -0
  243. package/dist/src/daemon/queue-journal.d.ts +20 -0
  244. package/dist/src/daemon/queue-journal.js +89 -0
  245. package/dist/src/daemon/queue-status.d.ts +9 -3
  246. package/dist/src/daemon/queue-status.js +17 -4
  247. package/dist/src/daemon/record-archive.d.ts +19 -0
  248. package/dist/src/daemon/record-archive.js +82 -0
  249. package/dist/src/daemon/record-sweep.d.ts +24 -0
  250. package/dist/src/daemon/record-sweep.js +147 -0
  251. package/dist/src/daemon/resume-index-lock.d.ts +13 -0
  252. package/dist/src/daemon/resume-index-lock.js +160 -0
  253. package/dist/src/daemon/resume-worktree.d.ts +7 -0
  254. package/dist/src/daemon/resume-worktree.js +29 -0
  255. package/dist/src/daemon/retrying-turn.d.ts +2 -12
  256. package/dist/src/daemon/retrying-turn.js +98 -172
  257. package/dist/src/daemon/schedule-control.d.ts +26 -0
  258. package/dist/src/daemon/schedule-control.js +110 -0
  259. package/dist/src/daemon/schedule-journal.d.ts +2 -15
  260. package/dist/src/daemon/schedule-journal.js +67 -4
  261. package/dist/src/daemon/settings-reload.d.ts +26 -0
  262. package/dist/src/daemon/settings-reload.js +82 -0
  263. package/dist/src/daemon/ticket-registration.d.ts +2 -7
  264. package/dist/src/daemon/ticket-registration.js +15 -81
  265. package/dist/src/daemon/turn-attempt-journal.d.ts +38 -0
  266. package/dist/src/daemon/turn-attempt-journal.js +136 -0
  267. package/dist/src/daemon/turn-attempts.d.ts +47 -0
  268. package/dist/src/daemon/turn-attempts.js +166 -0
  269. package/dist/src/daemon/turn-details.d.ts +4 -0
  270. package/dist/src/daemon/turn-details.js +33 -0
  271. package/dist/src/daemon/turn-report.d.ts +8 -1
  272. package/dist/src/daemon/turn-report.js +39 -0
  273. package/dist/src/daemon/work-tree.d.ts +9 -0
  274. package/dist/src/daemon/work-tree.js +20 -0
  275. package/dist/src/daemon/worker-profile.d.ts +9 -0
  276. package/dist/src/daemon/worker-profile.js +44 -0
  277. package/dist/src/daemon/workflow-generations.d.ts +7 -4
  278. package/dist/src/daemon/workflow-generations.js +22 -14
  279. package/dist/src/daemon/workflow-reload.d.ts +41 -0
  280. package/dist/src/daemon/workflow-reload.js +244 -0
  281. package/dist/src/daemon/workflow-replay.d.ts +2 -1
  282. package/dist/src/daemon/workflow-replay.js +7 -3
  283. package/dist/src/daemon/workflow-schedules.d.ts +3 -0
  284. package/dist/src/daemon/workflow-schedules.js +98 -45
  285. package/dist/src/daemon/worktree-processes.d.ts +9 -0
  286. package/dist/src/daemon/worktree-processes.js +151 -0
  287. package/dist/src/doctor-report.d.ts +4 -6
  288. package/dist/src/doctor-report.js +8 -13
  289. package/dist/src/harness-start.d.ts +15 -0
  290. package/dist/src/harness-start.js +37 -0
  291. package/dist/src/host/command-wait.d.ts +38 -0
  292. package/dist/src/host/command-wait.js +115 -0
  293. package/dist/src/host/start-delivery.d.ts +5 -7
  294. package/dist/src/host/start-delivery.js +3 -15
  295. package/dist/src/host/step-bridge-host.d.ts +2 -0
  296. package/dist/src/host/step-bridge-host.js +21 -0
  297. package/dist/src/operation-identity.d.ts +1 -0
  298. package/dist/src/operation-identity.js +4 -0
  299. package/dist/src/private-config.schema.json +71 -0
  300. package/dist/src/project-config.schema.json +40 -0
  301. package/dist/src/project-settings.d.ts +16 -2
  302. package/dist/src/project-settings.js +35 -1
  303. package/dist/src/queue-spend.d.ts +4 -0
  304. package/dist/src/queue-spend.js +21 -0
  305. package/dist/src/queue-state.d.ts +26 -0
  306. package/dist/src/queue-state.js +34 -0
  307. package/dist/src/record-retention.d.ts +46 -0
  308. package/dist/src/record-retention.js +81 -0
  309. package/dist/src/relay/relay-service.d.ts +3 -0
  310. package/dist/src/relay/relay-service.js +5 -3
  311. package/dist/src/report-ci.d.ts +164 -0
  312. package/dist/src/report-ci.js +32 -0
  313. package/dist/src/report-effects.d.ts +15 -0
  314. package/dist/src/report-effects.js +212 -0
  315. package/dist/src/report-flow-types.d.ts +38 -0
  316. package/dist/src/report-flow-types.js +7 -0
  317. package/dist/src/report-flow.d.ts +43 -0
  318. package/dist/src/report-flow.js +193 -0
  319. package/dist/src/report-operator.d.ts +67 -0
  320. package/dist/src/report-operator.js +25 -0
  321. package/dist/src/report-quality.d.ts +221 -0
  322. package/dist/src/report-quality.js +94 -0
  323. package/dist/src/report-ready.d.ts +23 -0
  324. package/dist/src/report-ready.js +117 -0
  325. package/dist/src/report-statistics.d.ts +2 -1
  326. package/dist/src/report-statistics.js +40 -4
  327. package/dist/src/report.d.ts +588 -47
  328. package/dist/src/report.js +156 -41
  329. package/dist/src/schedule-progress.d.ts +33 -0
  330. package/dist/src/schedule-progress.js +45 -0
  331. package/dist/src/service/active-tickets.js +11 -6
  332. package/dist/src/service/command-waits.d.ts +34 -0
  333. package/dist/src/service/command-waits.js +86 -0
  334. package/dist/src/service/dispatcher.d.ts +4 -0
  335. package/dist/src/service/dispatcher.js +33 -0
  336. package/dist/src/service/expiry.js +2 -0
  337. package/dist/src/service/gateway.js +3 -1
  338. package/dist/src/service/queue-handlers.d.ts +4 -0
  339. package/dist/src/service/queue-handlers.js +32 -0
  340. package/dist/src/service/queue-spend.d.ts +6 -0
  341. package/dist/src/service/queue-spend.js +68 -0
  342. package/dist/src/service/registry.d.ts +28 -2
  343. package/dist/src/service/registry.js +48 -0
  344. package/dist/src/service/replies.d.ts +22 -8
  345. package/dist/src/service/replies.js +16 -2
  346. package/dist/src/service/run-handlers.js +37 -12
  347. package/dist/src/service/run-metadata.d.ts +15 -1
  348. package/dist/src/service/run-metadata.js +93 -8
  349. package/dist/src/service/service.d.ts +11 -3
  350. package/dist/src/service/service.js +22 -37
  351. package/dist/src/service/submission-handler.js +18 -4
  352. package/dist/src/service/worker-port.js +9 -1
  353. package/dist/src/service/worker-totals.d.ts +6 -0
  354. package/dist/src/service/worker-totals.js +8 -1
  355. package/dist/src/service/workflow-reload.d.ts +35 -0
  356. package/dist/src/service/workflow-reload.js +52 -0
  357. package/dist/src/step-bridge.d.ts +20 -0
  358. package/dist/src/steps/command-wait.d.ts +12 -0
  359. package/dist/src/steps/command-wait.js +26 -0
  360. package/dist/src/steps/open-decision-wait.d.ts +2 -0
  361. package/dist/src/steps/{decision-gate.js → open-decision-wait.js} +0 -7
  362. package/dist/src/steps/review-by-person.js +4 -1
  363. package/dist/src/steps/wait-for-command.d.ts +3 -0
  364. package/dist/src/steps/wait-for-command.js +17 -0
  365. package/dist/src/steps/wait-for-decision.js +1 -1
  366. package/dist/src/storage/command-wait-rows.d.ts +30 -0
  367. package/dist/src/storage/command-wait-rows.js +96 -0
  368. package/dist/src/storage/decision-snapshots.d.ts +8 -2
  369. package/dist/src/storage/decision-snapshots.js +16 -8
  370. package/dist/src/storage/domain-changes.d.ts +3 -1
  371. package/dist/src/storage/domain-changes.js +4 -0
  372. package/dist/src/storage/domain-schema.d.ts +16 -1
  373. package/dist/src/storage/domain-schema.js +35 -4
  374. package/dist/src/storage/effect-schema.d.ts +2 -0
  375. package/dist/src/storage/effect-schema.js +9 -0
  376. package/dist/src/storage/projection-changes.d.ts +12 -0
  377. package/dist/src/storage/projection-changes.js +194 -0
  378. package/dist/src/storage/projection-lookups.d.ts +7 -0
  379. package/dist/src/storage/projection-lookups.js +30 -0
  380. package/dist/src/testing-requests.d.ts +15 -0
  381. package/dist/src/testing-requests.js +93 -0
  382. package/dist/src/testing.d.ts +4 -10
  383. package/dist/src/testing.js +33 -86
  384. package/dist/src/worker-usage.d.ts +1 -0
  385. package/dist/src/worker-usage.js +3 -0
  386. package/dist/src/workflow-candidate.d.ts +1 -0
  387. package/dist/src/workflow-candidate.js +12 -1
  388. package/dist/src/workflow-contracts.d.ts +1 -0
  389. package/dist/src/workflow-contracts.js +9 -2
  390. package/dist/src/workflow-declaration.d.ts +1 -0
  391. package/dist/src/workflow-declaration.js +3 -0
  392. package/dist/src/workflow-discovery.d.ts +2 -13
  393. package/dist/src/workflow-discovery.js +1 -13
  394. package/dist/src/workflow-refusals.js +0 -1
  395. package/dist/src/workflows.d.ts +1 -1
  396. package/dist/src/workflows.js +1 -1
  397. package/dist/tools/compile-workflows.js +3 -0
  398. package/dist/tools/project-configuration.d.ts +7 -2
  399. package/dist/tools/project-configuration.js +30 -1
  400. package/dist/tools/red-green-command.d.ts +1 -0
  401. package/dist/tools/red-green-command.js +174 -0
  402. package/dist/tools/red-green-process.d.ts +10 -0
  403. package/dist/tools/red-green-process.js +59 -0
  404. package/dist/tools/self-host-processes.d.ts +2 -0
  405. package/dist/tools/self-host-processes.js +69 -26
  406. package/dist/tools/self-host-project.d.ts +2 -0
  407. package/dist/tools/self-host-project.js +30 -77
  408. package/dist/tools/self-host-runtime.js +1 -1
  409. package/dist/tools/self-host.js +76 -34
  410. package/dist/tools/template-command.d.ts +1 -0
  411. package/dist/tools/template-command.js +160 -0
  412. package/dist/tools/template-copy.d.ts +11 -0
  413. package/dist/tools/template-copy.js +130 -0
  414. package/dist/tools/template-files.d.ts +17 -0
  415. package/dist/tools/template-files.js +74 -0
  416. package/dist/tools/workflow-bundles.js +1 -0
  417. package/dist/tools/workflow-candidate-counts.js +2 -2
  418. package/dist/tools/workflow-candidate-program.d.ts +4 -2
  419. package/dist/tools/workflow-candidate-program.js +30 -11
  420. package/dist/tools/workflow-candidate-shape.d.ts +3 -0
  421. package/dist/tools/workflow-candidate-shape.js +90 -0
  422. package/dist/tools/workflow-candidate-source.d.ts +1 -0
  423. package/dist/tools/workflow-candidate-source.js +26 -4
  424. package/dist/tools/workflow-candidate-syntax.d.ts +2 -2
  425. package/dist/tools/workflow-candidate-syntax.js +24 -94
  426. package/dist/tools/workflow-command.js +1 -2
  427. package/dist/tools/workflow-folders.d.ts +2 -3
  428. package/dist/tools/workflow-folders.js +1 -1
  429. package/package.json +17 -9
  430. package/templates/develop/README.md +93 -4
  431. package/templates/develop/develop/flow-tests.ts +38 -1
  432. package/templates/develop/develop/interruption-tests.ts +157 -0
  433. package/templates/develop/develop/local.ts +1 -0
  434. package/templates/develop/develop/option-tests.ts +138 -9
  435. package/templates/develop/develop/pull.ts +5 -1
  436. package/templates/develop/develop/red-green.ts +55 -0
  437. package/templates/develop/develop/refusal-tests.ts +77 -0
  438. package/templates/develop/develop/report.ts +31 -11
  439. package/templates/develop/develop/round.ts +1 -0
  440. package/templates/develop/develop/scenarios.ts +27 -0
  441. package/templates/develop/develop/turn.ts +28 -7
  442. package/templates/develop/develop.declaration.json +1 -1
  443. package/templates/develop/develop.test.ts +4 -0
  444. package/templates/develop/template.json +29 -2
  445. package/templates/idea-to-issue/README.md +27 -0
  446. package/templates/idea-to-issue/idea-to-issue/effects.ts +52 -0
  447. package/templates/idea-to-issue/idea-to-issue/leave.ts +10 -0
  448. package/templates/idea-to-issue/idea-to-issue/next.ts +29 -0
  449. package/templates/idea-to-issue/idea-to-issue/post-person.ts +18 -0
  450. package/templates/idea-to-issue/idea-to-issue/post.ts +50 -0
  451. package/templates/idea-to-issue/idea-to-issue/queue.ts +27 -0
  452. package/templates/idea-to-issue/idea-to-issue/review.ts +42 -0
  453. package/templates/idea-to-issue/idea-to-issue/scenarios.ts +50 -0
  454. package/templates/idea-to-issue/idea-to-issue/turn.ts +40 -0
  455. package/templates/idea-to-issue/idea-to-issue.declaration.json +16 -0
  456. package/templates/idea-to-issue/idea-to-issue.test.ts +79 -0
  457. package/templates/idea-to-issue/idea-to-issue.ts +49 -0
  458. package/templates/idea-to-issue/template.json +81 -0
  459. package/templates/review-day/README.md +97 -0
  460. package/templates/review-day/review-day/critique.ts +58 -0
  461. package/templates/review-day/review-day/decision.ts +29 -0
  462. package/templates/review-day/review-day/facts.ts +69 -0
  463. package/templates/review-day/review-day/label.ts +29 -0
  464. package/templates/review-day/review-day/next.ts +28 -0
  465. package/templates/review-day/review-day/post.ts +27 -0
  466. package/templates/review-day/review-day/report.ts +98 -0
  467. package/templates/review-day/review-day/rules.ts +12 -0
  468. package/templates/review-day/review-day/scenarios.ts +76 -0
  469. package/templates/review-day/review-day/turn.ts +73 -0
  470. package/templates/review-day/review-day.declaration.json +16 -0
  471. package/templates/review-day/review-day.test.ts +362 -0
  472. package/templates/review-day/review-day.ts +37 -0
  473. package/templates/review-day/template.json +56 -0
  474. package/dist/src/cli/watch-start-view.d.ts +0 -18
  475. package/dist/src/cli/watch-start-view.js +0 -77
  476. package/dist/src/steps/decision-gate.d.ts +0 -3
  477. package/dist/workflows/develop-prd.d.ts +0 -7
  478. package/dist/workflows/develop-prd.js +0 -165
  479. package/dist/workflows/develop-ticket.d.ts +0 -9
  480. package/dist/workflows/develop-ticket.js +0 -207
  481. package/dist/workflows/issue-labels.d.ts +0 -16
  482. package/dist/workflows/issue-labels.js +0 -70
  483. package/dist/workflows/ticket-prompts.d.ts +0 -35
  484. package/dist/workflows/ticket-prompts.js +0 -147
@@ -0,0 +1,208 @@
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 tree = recordedTree(started);
82
+ if (tree === undefined)
83
+ return "claude-turn-interrupted";
84
+ const locked = await resumeWorktree({
85
+ ...settings,
86
+ directory: tree.path,
87
+ folder,
88
+ signal,
89
+ });
90
+ if (locked !== null)
91
+ return locked.reason;
92
+ const resume = await readResume(folder, started);
93
+ if (resume === undefined)
94
+ return "claude-turn-interrupted";
95
+ const profile = await selectedProfile(settings, intent);
96
+ if (typeof profile === "string")
97
+ return "claude-turn-interrupted";
98
+ const harness = turnHarness(settings, profile);
99
+ if (recordedField(started, "harness") !== harness.worker ||
100
+ resumedCommand({
101
+ worker: harness.worker,
102
+ command: harness.command,
103
+ sessionId: resume.sessionId,
104
+ }) === undefined)
105
+ return "claude-turn-interrupted";
106
+ return { resume, tree, profile, harness };
107
+ }
108
+ function priorEnd(record) {
109
+ const field = (name) => recordedField(record, name);
110
+ const sessionId = field("sessionId");
111
+ const model = field("model");
112
+ const retryKind = field("retryKind");
113
+ return {
114
+ ...(retryKind === "capacity" ||
115
+ retryKind === "network" ||
116
+ retryKind === null
117
+ ? { retryKind }
118
+ : {}),
119
+ ...(field("resumedAfter") === "daemon-restart"
120
+ ? { resumedAfter: "daemon-restart" }
121
+ : {}),
122
+ exitCode: null,
123
+ result: {
124
+ sessionId: typeof sessionId === "string" ? sessionId : null,
125
+ model: typeof model === "string" ? model : null,
126
+ text: "",
127
+ failed: true,
128
+ costUsd: recordedSessionCost(record),
129
+ turns: typeof field("turns") === "number" ? Number(field("turns")) : null,
130
+ usage: usageOf(field("usage")),
131
+ },
132
+ };
133
+ }
134
+ function recordedSessionCost(record) {
135
+ const fields = typeof record === "object" && record !== null ? record : {};
136
+ const name = Object.hasOwn(fields, "sessionCostUsd")
137
+ ? "sessionCostUsd"
138
+ : "costUsd";
139
+ return priceOf(Reflect.get(fields, name));
140
+ }
141
+ function resumeHeader(started) {
142
+ if (recordedField(started, "phase") === "waiting")
143
+ return undefined;
144
+ const attempt = recordedField(started, "attempt");
145
+ const startedAt = recordedField(started, "startedAt");
146
+ const head = recordedField(started, "turnStartCommit");
147
+ if (typeof attempt !== "number" ||
148
+ !Number.isSafeInteger(attempt) ||
149
+ attempt < 1 ||
150
+ attempt > 5 ||
151
+ typeof startedAt !== "string")
152
+ return undefined;
153
+ return {
154
+ attempt,
155
+ startedAt,
156
+ turnStartCommit: typeof head === "string" ? head : null,
157
+ };
158
+ }
159
+ export async function readResume(folder, started) {
160
+ const header = resumeHeader(started);
161
+ if (header === undefined)
162
+ return undefined;
163
+ const records = [];
164
+ for (let number = 1; number <= header.attempt; number += 1)
165
+ records.push(await readRecord(folder, `attempt-${String(number)}.json`));
166
+ const sessionId = recordedField(records.at(-1), "sessionId");
167
+ if (typeof sessionId !== "string" ||
168
+ sessionId === "" ||
169
+ records.filter((record) => recordedField(record, "resumedAfter") === "daemon-restart").length >= 2)
170
+ return undefined;
171
+ return {
172
+ sessionId,
173
+ ends: records.map(priorEnd),
174
+ startedAt: header.startedAt,
175
+ turnStartCommit: header.turnStartCommit,
176
+ };
177
+ }
178
+ export async function recordedHarness(journal, operationId) {
179
+ const { folder } = located(journal, operationId);
180
+ const started = await readRecord(folder, "started.json").catch(() => undefined);
181
+ const harness = recordedField(started, "harness");
182
+ return typeof harness === "string" ? harness : undefined;
183
+ }
184
+ export async function interruptedReply(place, reason) {
185
+ const ending = interrupted(reason);
186
+ await writeRecord(place.folder, { name: "result.json", value: ending });
187
+ return replied({ receipt: place.key, worker: "claude" }, ending);
188
+ }
189
+ export async function recoverTurn(operation, reconcile) {
190
+ const { intent, journal, report } = operation;
191
+ if (!resumableHarness(await recordedHarness(journal, intent.operationId)))
192
+ return;
193
+ const result = await reconcile();
194
+ if (operation.signal.aborted)
195
+ return;
196
+ if (result.kind === "completed" ||
197
+ result.kind === "failed" ||
198
+ result.kind === "stopped")
199
+ await report(reportOf({
200
+ intent,
201
+ worker: "claude",
202
+ commandId: `claude-turn:${located(journal, intent.operationId).key}`,
203
+ }, {
204
+ ...result,
205
+ outcome: result.kind,
206
+ endedAt: new Date().toISOString(),
207
+ }));
208
+ }
@@ -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;
@@ -6,75 +6,18 @@ import { codexStream } from "./codex-stream.js";
6
6
  import { cursorStream } from "./cursor-stream.js";
7
7
  import { opencodeStream } from "./opencode-stream.js";
8
8
  import { textOutput } from "./text-output.js";
9
- import { grokResultFields, grokUsageWarnings } from "../grok-result.js";
9
+ import { grokUsageWarnings } from "../grok-result.js";
10
10
  import { geminiStream } from "./gemini-stream.js";
11
- import { priceOf, modelUsageOf, usageOf, } from "../worker-usage.js";
11
+ import { parsed, textOf, streamResult, } from "./claude-stream.js";
12
+ import { usageOf } from "../worker-usage.js";
13
+ export { streamResult, capacityRefusal, retryKind } from "./claude-stream.js";
12
14
  import { commandModel } from "../token-prices.js";
13
15
  import { shellTurnScript } from "../agent-harness-shell.js";
14
- function parsed(line) {
15
- try {
16
- const value = JSON.parse(line);
17
- return value;
18
- }
19
- catch {
20
- return undefined;
21
- }
22
- }
23
- function numberOf(value) {
24
- return typeof value === "number" ? value : null;
25
- }
26
- function textOf(value) {
27
- return typeof value === "string" ? value : null;
28
- }
29
- function networkFailure(result) {
30
- return (result?.failed === true &&
31
- result.text.startsWith("API Error: Can't reach the API server"));
32
- }
33
- export function capacityRefusal(result) {
34
- if (networkFailure(result))
35
- return false;
36
- return (result?.failed === true &&
37
- ["success", "error_during_execution"].includes(result.subtype ?? "error_during_execution") &&
38
- (result.text ===
39
- "Selected model is at capacity. Please try a different model." ||
40
- result.errorType === "overloaded"));
41
- }
42
- export function retryKind(result) {
43
- if (networkFailure(result))
44
- return "network";
45
- return capacityRefusal(result) ? "capacity" : null;
46
- }
47
16
  export function succeeded(end) {
48
17
  return (end.reason === undefined &&
49
18
  end.exitCode === 0 &&
50
19
  end.result?.failed === false);
51
20
  }
52
- export function streamResult(line, worker) {
53
- if (!line.includes('"result"'))
54
- return undefined;
55
- const record = parsed(line);
56
- const field = (name) => Reflect.get(Object(record), name);
57
- if (field("type") !== "result")
58
- return undefined;
59
- const models = modelUsageOf(field("models"));
60
- return {
61
- ...(models === undefined ? {} : { models }),
62
- ...(typeof field("subtype") === "string"
63
- ? { subtype: String(field("subtype")) }
64
- : {}),
65
- ...(typeof field("error") === "string"
66
- ? { errorType: String(field("error")) }
67
- : {}),
68
- text: textOf(field("result")) ?? "",
69
- failed: field("is_error") === true,
70
- costUsd: priceOf(field("total_cost_usd")),
71
- usage: usageOf(field("usage")),
72
- model: textOf(field("model")),
73
- sessionId: textOf(field("session_id")),
74
- turns: numberOf(field("num_turns")),
75
- ...(worker === "grok" ? grokResultFields(record) : {}),
76
- };
77
- }
78
21
  function ended(stream) {
79
22
  return new Promise((settle) => {
80
23
  stream.end(settle);
@@ -129,33 +72,65 @@ function spawnTurn(start) {
129
72
  throw error;
130
73
  }
131
74
  }
75
+ function streamMetadata(stream, event) {
76
+ if (typeof event !== "object" || event === null)
77
+ return false;
78
+ const field = (name) => Reflect.get(event, name);
79
+ const type = field("type");
80
+ const sessionId = textOf(field("session_id"));
81
+ const discovered = stream.sessionId === null && sessionId !== null;
82
+ if (discovered)
83
+ stream.sessionId = sessionId;
84
+ if (type === "assistant" && field("parent_tool_use_id") == null)
85
+ stream.errorType = textOf(field("error"));
86
+ if (type === "system" || type === "result")
87
+ stream.model = textOf(field("model")) ?? stream.model;
88
+ return discovered;
89
+ }
132
90
  function receivedLines(stream, input) {
133
91
  const { lines, worker } = input;
134
92
  for (const line of lines) {
135
- const event = parsed(line);
136
- const field = (name) => Reflect.get(Object(event), name);
137
- const type = field("type");
138
- if (type === "assistant" && field("parent_tool_use_id") == null)
139
- stream.errorType = textOf(field("error"));
140
- if (type === "system" || type === "result")
141
- stream.model = textOf(field("model")) ?? stream.model;
93
+ const discovered = streamMetadata(stream, parsed(line));
142
94
  const result = streamResult(line, worker);
143
95
  if (result !== undefined) {
144
96
  const errorType = result.errorType ?? stream.errorType;
145
97
  stream.result = {
146
98
  ...result,
99
+ sessionId: result.sessionId ?? stream.sessionId,
147
100
  ...(errorType === null ? {} : { errorType }),
148
101
  };
149
102
  }
103
+ if (discovered || result !== undefined) {
104
+ saveProgress(stream, input);
105
+ }
150
106
  }
151
107
  }
108
+ function saveProgress(stream, input) {
109
+ const progress = { sessionId: stream.sessionId, result: stream.result };
110
+ stream.saved = stream.saved
111
+ .then(() => {
112
+ if (stream.failure === undefined)
113
+ return input.progress?.(progress);
114
+ return undefined;
115
+ })
116
+ .catch((error) => {
117
+ stream.failure = { error };
118
+ input.failed();
119
+ });
120
+ }
152
121
  function activityOutput(start) {
153
122
  const output = createWriteStream(join(start.activityFolder ?? start.folder, "turn.jsonl"), { flags: start.activityFolder === undefined ? "w" : "a" });
154
123
  if (start.activityFolder !== undefined)
155
124
  output.write("\n");
156
125
  return output;
157
126
  }
158
- function streamAdapter(worker) {
127
+ function streamAdapter(worker, stderr) {
128
+ if (worker === "opencode") {
129
+ const translated = opencodeStream();
130
+ stderr.setEncoding("utf8");
131
+ stderr.on("data", translated.stderr);
132
+ return translated;
133
+ }
159
134
  if (worker === "codex")
160
135
  return codexStream();
161
136
  if (worker === "cursor-agent")
@@ -164,26 +139,31 @@ function streamAdapter(worker) {
164
139
  return geminiStream();
165
140
  return undefined;
166
141
  }
167
- function turnOutput(start, child) {
168
- const output = activityOutput(start);
169
- if (start.output === "text")
170
- return textOutput(child, { output, limit: start.resultBytes ?? 48_000 });
171
- const translated = start.worker === "opencode" ? opencodeStream() : undefined;
172
- const adapter = translated ?? streamAdapter(start.worker);
173
- const { stdout, stderr } = child;
174
- if (translated !== undefined) {
175
- stderr.setEncoding("utf8");
176
- stderr.on("data", translated.stderr);
177
- }
178
- const stream = {
142
+ function streamState() {
143
+ return {
144
+ failure: undefined,
145
+ sessionId: null,
146
+ saved: Promise.resolve(),
179
147
  pending: "",
180
148
  result: undefined,
181
149
  model: null,
182
150
  errorType: null,
183
151
  };
152
+ }
153
+ function turnOutput(start, child) {
154
+ const output = activityOutput(start);
155
+ if (start.output === "text")
156
+ return textOutput(child, { output, limit: start.resultBytes ?? 48_000 });
157
+ const { stdout, stderr } = child;
158
+ const adapter = streamAdapter(start.worker, stderr);
159
+ const stream = streamState();
184
160
  const received = (lines) => {
185
161
  receivedLines(stream, {
186
162
  lines,
163
+ progress: start.progress,
164
+ failed: () => {
165
+ signalTurn({ child, start }, "SIGKILL");
166
+ },
187
167
  ...(start.worker === undefined ? {} : { worker: start.worker }),
188
168
  });
189
169
  };
@@ -212,6 +192,9 @@ function turnOutput(start, child) {
212
192
  await ended(output);
213
193
  if (adapter === undefined)
214
194
  received([stream.pending]);
195
+ await stream.saved;
196
+ if (stream.failure !== undefined)
197
+ throw stream.failure.error;
215
198
  const result = stream.result;
216
199
  return result === undefined
217
200
  ? undefined
@@ -1,10 +1,10 @@
1
1
  import { type HarnessSettings } from "../harness-defaults.ts";
2
- import { type TurnProfiles } from "../turn-profile.ts";
3
- import type { Delivery } from "../broker/actor/delivery-intents.ts";
2
+ import type { Delivery, DeliveryIntent } from "../broker/actor/delivery-intents.ts";
4
3
  import { type RetrySettings } from "./retrying-turn.ts";
5
4
  import { type WorkerReport } from "./operation-journal.ts";
6
- export interface ClaudeWorkerSettings extends RetrySettings, HarnessSettings {
7
- readonly profiles?: TurnProfiles;
5
+ import type { TurnSettings } from "../project-settings.ts";
6
+ export interface ClaudeWorkerSettings extends Pick<RetrySettings, "retryDelay">, HarnessSettings {
7
+ readonly turnSettings: () => TurnSettings;
8
8
  readonly workflowId?: (runId: string) => Promise<string | undefined>;
9
9
  readonly repository: string;
10
10
  readonly worktrees: string;
@@ -15,6 +15,7 @@ export interface ClaudeWorkerSettings extends RetrySettings, HarnessSettings {
15
15
  readonly stopMilliseconds?: number;
16
16
  }
17
17
  export interface ClaudeWorker extends Delivery {
18
+ readonly recover: (intent: DeliveryIntent) => Promise<void>;
18
19
  readonly harness: (operationId: string) => Promise<string | undefined>;
19
20
  readonly stop: NonNullable<Delivery["stop"]>;
20
21
  readonly close: () => Promise<void>;