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
@@ -1,10 +1,17 @@
1
+ import { passiveCandidateModule, workflowShape, } from "./workflow-candidate-shape.js";
1
2
  import ts from "typescript";
2
3
  import { dirname, relative, sep } from "node:path";
3
- import { candidateProgram, resolvedSymbol, } from "./workflow-candidate-program.js";
4
- import { protectedEffectFact, passiveCandidateModule, unsupportedCandidateNode, workflowShape, } from "./workflow-candidate-syntax.js";
4
+ import { candidateCompiler, candidateProgram, resolvedSymbol, } from "./workflow-candidate-program.js";
5
+ import { protectedEffectFact, commandWaitCall, unsupportedCandidateNode, } from "./workflow-candidate-syntax.js";
6
+ import { literalField } from "./workflow-candidate-fields.js";
5
7
  import { sourceEffectNodes } from "./workflow-source-effects.js";
6
8
  import { candidateEffectTotals } from "./workflow-candidate-counts.js";
7
9
  import { helperEffectTotals } from "./workflow-candidate-helper-counts.js";
10
+ export function createWorkflowCandidateAnalyzer(installed = {}) {
11
+ const compile = candidateCompiler(installed);
12
+ const localSources = Object.keys(installed.helpers ?? {});
13
+ return (text) => analyzeProgram(compile(text), localSources);
14
+ }
8
15
  function exportSnapshot(modules, checker) {
9
16
  return Object.fromEntries([...modules].map(([name, declaration]) => {
10
17
  const symbol = checker.getSymbolAtLocation(declaration);
@@ -32,11 +39,14 @@ function sourceFacts(symbols) {
32
39
  const { source } = symbols;
33
40
  const imports = [];
34
41
  const effects = [];
42
+ const commandWaits = [];
35
43
  const unsupportedForms = [];
36
44
  function visit(node) {
37
45
  const imported = sourceImport(node);
38
46
  if (imported)
39
47
  imports.push(imported);
48
+ if (ts.isCallExpression(node) && commandWaitCall(node, symbols))
49
+ commandWaits.push(literalField(node.arguments[0], "name"));
40
50
  const effect = protectedEffectFact(node, symbols);
41
51
  if (effect)
42
52
  effects.push(effect);
@@ -47,6 +57,7 @@ function sourceFacts(symbols) {
47
57
  visit(source);
48
58
  return {
49
59
  imports,
60
+ ...(commandWaits.length === 0 ? {} : { commandWaits }),
50
61
  effects,
51
62
  directEffects: sourceEffectNodes(source, {
52
63
  checker: symbols.checker,
@@ -84,7 +95,10 @@ function mergeHelpers(modules, checker) {
84
95
  });
85
96
  }
86
97
  export function analyzeWorkflowCandidate(text, installed = {}) {
87
- const { program, source, sources, modules } = candidateProgram(text, installed);
98
+ return analyzeProgram(candidateProgram(text, installed), Object.keys(installed.helpers ?? {}));
99
+ }
100
+ function analyzeProgram(compiled, localSources) {
101
+ const { program, source, sources, modules } = compiled;
88
102
  const checker = program.getTypeChecker();
89
103
  const symbols = {
90
104
  checker,
@@ -99,6 +113,11 @@ export function analyzeWorkflowCandidate(text, installed = {}) {
99
113
  subpath: "cloving/workflows/steps/handoff",
100
114
  name: "handoff",
101
115
  }),
116
+ commandWaitSymbol: protectedHelper(modules, {
117
+ checker,
118
+ subpath: "cloving/workflows/steps/wait-for-command",
119
+ name: "waitForCommand",
120
+ }),
102
121
  commandSymbol: protectedHelper(modules, {
103
122
  checker,
104
123
  subpath: "cloving/workflows/steps/run-command",
@@ -114,7 +133,7 @@ export function analyzeWorkflowCandidate(text, installed = {}) {
114
133
  const facts = sources.map((entry) => analyzedSource({ ...symbols, source: entry }, { program, workflow: source }));
115
134
  return {
116
135
  analysis: combineFacts({
117
- localSources: Object.keys(installed.helpers ?? {}),
136
+ localSources,
118
137
  facts,
119
138
  expanded: helperEffectTotals({
120
139
  symbols: { ...symbols, source },
@@ -154,6 +173,9 @@ function combineFacts(input) {
154
173
  const { localSources, facts } = input;
155
174
  return {
156
175
  localSources,
176
+ ...(facts.some((entry) => entry.commandWaits !== undefined)
177
+ ? { commandWaits: facts.flatMap((entry) => entry.commandWaits ?? []) }
178
+ : {}),
157
179
  imports: facts.flatMap((entry) => entry.imports),
158
180
  effects: facts.flatMap((entry) => entry.effects),
159
181
  directEffects: facts.flatMap((entry) => entry.directEffects),
@@ -5,6 +5,7 @@ export interface CandidateSymbols {
5
5
  readonly source: ts.SourceFile;
6
6
  readonly protectedSymbol: ts.Symbol | undefined;
7
7
  readonly handoffSymbol: ts.Symbol | undefined;
8
+ readonly commandWaitSymbol?: ts.Symbol | undefined;
8
9
  readonly commandSymbol: ts.Symbol | undefined;
9
10
  readonly reviewSymbol: ts.Symbol | undefined;
10
11
  readonly mergeSymbols: readonly ts.Symbol[];
@@ -12,10 +13,9 @@ export interface CandidateSymbols {
12
13
  export declare function protectedCall(node: ts.Node, symbols: CandidateSymbols): node is ts.CallExpression;
13
14
  export declare function handoffCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
14
15
  export declare function commandCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
16
+ export declare function commandWaitCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
15
17
  export declare function reviewCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
16
18
  export declare function helperCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
17
19
  export declare function mergeCall(node: ts.CallExpression, symbols: CandidateSymbols): boolean;
18
20
  export declare function protectedEffectFact(node: ts.Node, symbols: CandidateSymbols): CandidateEffect | undefined;
19
21
  export declare function unsupportedCandidateNode(node: ts.Node, symbols: CandidateSymbols): boolean;
20
- export declare function workflowShape(source: ts.SourceFile): boolean;
21
- export declare function passiveCandidateModule(source: ts.SourceFile, kind?: "workflow" | "helper"): boolean;
@@ -1,7 +1,7 @@
1
1
  import ts from "typescript";
2
2
  import { resolvedSymbol } from "./workflow-candidate-program.js";
3
3
  import { referenceSymbol } from "./workflow-source-effects.js";
4
- import { invalidFields, literalField, propertyInitializer, } from "./workflow-candidate-fields.js";
4
+ import { invalidFields, literalField, propertyInitializer, propertyName, } from "./workflow-candidate-fields.js";
5
5
  export function protectedCall(node, symbols) {
6
6
  if (!ts.isCallExpression(node) || !ts.isIdentifier(node.expression))
7
7
  return false;
@@ -11,6 +11,7 @@ export function protectedCall(node, symbols) {
11
11
  symbols.protectedSymbol,
12
12
  symbols.handoffSymbol,
13
13
  symbols.commandSymbol,
14
+ symbols.commandWaitSymbol,
14
15
  symbols.reviewSymbol,
15
16
  ...symbols.mergeSymbols,
16
17
  ].includes(symbol));
@@ -26,6 +27,10 @@ export function commandCall(node, symbols) {
26
27
  const symbol = symbols.commandSymbol;
27
28
  return symbol !== undefined && calledSymbol(node, symbols) === symbol;
28
29
  }
30
+ export function commandWaitCall(node, symbols) {
31
+ const symbol = symbols.commandWaitSymbol;
32
+ return symbol !== undefined && calledSymbol(node, symbols) === symbol;
33
+ }
29
34
  export function reviewCall(node, symbols) {
30
35
  const symbol = symbols.reviewSymbol;
31
36
  return symbol !== undefined && calledSymbol(node, symbols) === symbol;
@@ -40,7 +45,7 @@ export function mergeCall(node, symbols) {
40
45
  export function protectedEffectFact(node, symbols) {
41
46
  if (!protectedCall(node, symbols))
42
47
  return undefined;
43
- if (handoffCall(node, symbols))
48
+ if (handoffCall(node, symbols) || commandWaitCall(node, symbols))
44
49
  return undefined;
45
50
  const argument = node.arguments[0];
46
51
  if (!argument || !ts.isObjectLiteralExpression(argument))
@@ -81,6 +86,7 @@ function escapedHelper(node, symbols) {
81
86
  symbols.protectedSymbol,
82
87
  symbols.handoffSymbol,
83
88
  symbols.commandSymbol,
89
+ symbols.commandWaitSymbol,
84
90
  symbols.reviewSymbol,
85
91
  ...symbols.mergeSymbols,
86
92
  ].includes(symbol))
@@ -115,9 +121,22 @@ function invalidRequest(node, symbols) {
115
121
  ? propertyInitializer(argument, "reviewer")
116
122
  : undefined;
117
123
  return (invalidFields(argument) ||
118
- (reviewer !== undefined &&
119
- ts.isObjectLiteralExpression(reviewer) &&
120
- invalidFields(reviewer)));
124
+ invalidCommandWaitFields(node, symbols) ||
125
+ invalidReviewer(reviewer));
126
+ }
127
+ function invalidReviewer(reviewer) {
128
+ return (reviewer !== undefined &&
129
+ ts.isObjectLiteralExpression(reviewer) &&
130
+ invalidFields(reviewer));
131
+ }
132
+ function invalidCommandWaitFields(node, symbols) {
133
+ if (!commandWaitCall(node, symbols))
134
+ return false;
135
+ const argument = node.arguments[0];
136
+ return (!!argument &&
137
+ ts.isObjectLiteralExpression(argument) &&
138
+ argument.properties.some((entry) => entry.name &&
139
+ !["name", "input"].includes(propertyName(entry.name) ?? "")));
121
140
  }
122
141
  function workflowBodyCall(node) {
123
142
  let child = node;
@@ -172,92 +191,3 @@ export function unsupportedCandidateNode(node, symbols) {
172
191
  ];
173
192
  return checks.some(Boolean);
174
193
  }
175
- export function workflowShape(source) {
176
- const exported = source.statements.filter((node) => ts.isFunctionDeclaration(node) &&
177
- (ts.getModifiers(node) ?? []).some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
178
- const candidate = exported[0];
179
- if (exported.length !== 1 ||
180
- !candidate ||
181
- !ts.isFunctionDeclaration(candidate))
182
- return false;
183
- if (!workflowFunction(candidate))
184
- return false;
185
- const directives = [];
186
- function visit(node) {
187
- if (ts.isStringLiteral(node) && node.text === "use workflow")
188
- directives.push(node);
189
- ts.forEachChild(node, visit);
190
- }
191
- visit(source);
192
- return directives.length === 1;
193
- }
194
- function workflowFunction(candidate) {
195
- if (!candidate.name || !candidate.body || candidate.asteriskToken)
196
- return false;
197
- const modifiers = ts.getModifiers(candidate) ?? [];
198
- if (!modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) ||
199
- modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword))
200
- return false;
201
- const first = candidate.body.statements[0];
202
- return first !== undefined && workflowDirective(first);
203
- }
204
- function workflowDirective(node) {
205
- return (ts.isExpressionStatement(node) &&
206
- ts.isStringLiteral(node.expression) &&
207
- node.expression.text === "use workflow");
208
- }
209
- function unwrappedInitializer(node) {
210
- if (ts.isParenthesizedExpression(node) ||
211
- ts.isAsExpression(node) ||
212
- ts.isSatisfiesExpression(node) ||
213
- ts.isTypeAssertionExpression(node))
214
- return node.expression;
215
- return undefined;
216
- }
217
- function passiveCompound(node) {
218
- if (ts.isArrayLiteralExpression(node))
219
- return node.elements.every((element) => ts.isOmittedExpression(element) || passiveInitializer(element));
220
- if (ts.isObjectLiteralExpression(node))
221
- return node.properties.every((property) => ts.isPropertyAssignment(property) &&
222
- !ts.isComputedPropertyName(property.name) &&
223
- passiveInitializer(property.initializer));
224
- return false;
225
- }
226
- function passiveInitializer(node) {
227
- if (!node)
228
- return false;
229
- if (ts.isLiteralExpression(node))
230
- return true;
231
- if ([
232
- ts.SyntaxKind.TrueKeyword,
233
- ts.SyntaxKind.FalseKeyword,
234
- ts.SyntaxKind.NullKeyword,
235
- ].includes(node.kind))
236
- return true;
237
- if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))
238
- return true;
239
- if (ts.isPrefixUnaryExpression(node))
240
- return ([ts.SyntaxKind.PlusToken, ts.SyntaxKind.MinusToken].includes(node.operator) && ts.isNumericLiteral(node.operand));
241
- const inner = unwrappedInitializer(node);
242
- return inner ? passiveInitializer(inner) : passiveCompound(node);
243
- }
244
- function passiveStatement(node, kind) {
245
- if (ts.isVariableStatement(node))
246
- return ((node.declarationList.flags & ts.NodeFlags.Const) !== 0 &&
247
- node.declarationList.declarations.every((declaration) => (kind === "helper" ||
248
- (ts.getCombinedModifierFlags(declaration) &
249
- ts.ModifierFlags.Export) ===
250
- 0) &&
251
- ts.isIdentifier(declaration.name) &&
252
- passiveInitializer(declaration.initializer)));
253
- if (ts.isExpressionStatement(node))
254
- return ts.isStringLiteral(node.expression);
255
- return (ts.isImportDeclaration(node) ||
256
- ts.isTypeAliasDeclaration(node) ||
257
- ts.isInterfaceDeclaration(node) ||
258
- ts.isFunctionDeclaration(node) ||
259
- ts.isEmptyStatement(node));
260
- }
261
- export function passiveCandidateModule(source, kind = "workflow") {
262
- return source.statements.every((node) => passiveStatement(node, kind));
263
- }
@@ -80,8 +80,7 @@ function presentWorkflows(workflows, options) {
80
80
  }
81
81
  async function testWorkflows(workflows, options) {
82
82
  const { id, repository } = options;
83
- const selected = workflows.filter((workflow) => workflow.scope !== "bundled" &&
84
- (id === undefined || workflow.workflowId === id));
83
+ const selected = workflows.filter((workflow) => id === undefined || workflow.workflowId === id);
85
84
  if (id !== undefined &&
86
85
  !workflows.some((workflow) => workflow.workflowId === id)) {
87
86
  process.stderr.write("unknown-workflow: " + id + "\n");
@@ -1,6 +1,6 @@
1
1
  import type { WorkflowDeclaration } from "../src/workflow-declaration.ts";
2
2
  import { type CandidateDeclaration, type WorkflowCandidateCode } from "../src/workflow-candidate.ts";
3
- import { type WorkflowConflictCode, type WorkflowReservation } from "../src/workflow-discovery.ts";
3
+ import { type WorkflowConflictCode } from "../src/workflow-discovery.ts";
4
4
  import type { CandidatePackageOptions } from "./workflow-candidate-program.ts";
5
5
  import { type WorkflowCaptureCode } from "./workflow-folder-capture.ts";
6
6
  export interface WorkflowFolderInput {
@@ -8,7 +8,6 @@ export interface WorkflowFolderInput {
8
8
  readonly home: string;
9
9
  readonly xdgConfigHome?: string | undefined;
10
10
  readonly userFolder?: string | undefined;
11
- readonly bundled: readonly WorkflowReservation[];
12
11
  }
13
12
  interface WorkflowLabel {
14
13
  readonly scope: "project" | "user";
@@ -28,7 +27,7 @@ export interface WorkflowFolderRefusal extends WorkflowLabel {
28
27
  readonly codes: readonly (WorkflowCandidateCode | WorkflowCaptureCode | WorkflowConflictCode | "compile-failed")[];
29
28
  }
30
29
  export interface WorkflowListing {
31
- readonly scope: "bundled" | "project" | "user";
30
+ readonly scope: "project" | "user";
32
31
  readonly workflowId: string | null;
33
32
  readonly file: string;
34
33
  readonly admitted: boolean;
@@ -162,7 +162,7 @@ export async function loadWorkflowFolders(input, installed = {}) {
162
162
  const candidates = [];
163
163
  const refusals = [];
164
164
  const { repository, snapshots } = await scanFolders(input, refusals);
165
- const conflicts = workflowConflicts(snapshots.map(identity), input.bundled);
165
+ const conflicts = workflowConflicts(snapshots.map(identity));
166
166
  for (const [index, entry] of snapshots.entries()) {
167
167
  const label = entry.kind === "captured" ? entry.snapshot : entry;
168
168
  const codes = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloving",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Local durable development workflow service",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,10 +31,6 @@
31
31
  "types": "./dist/src/steps/protected-effect.d.ts",
32
32
  "import": "./dist/src/steps/protected-effect.js"
33
33
  },
34
- "./workflows/steps/decision-gate": {
35
- "types": "./dist/src/steps/decision-gate.d.ts",
36
- "import": "./dist/src/steps/decision-gate.js"
37
- },
38
34
  "./workflows/steps/review-subject": {
39
35
  "types": "./dist/src/steps/review-subject.d.ts",
40
36
  "import": "./dist/src/steps/review-subject.js"
@@ -55,6 +51,10 @@
55
51
  "types": "./dist/src/steps/merge-when-green.d.ts",
56
52
  "import": "./dist/src/steps/merge-when-green.js"
57
53
  },
54
+ "./workflows/steps/open-decision-wait": {
55
+ "types": "./dist/src/steps/open-decision-wait.d.ts",
56
+ "import": "./dist/src/steps/open-decision-wait.js"
57
+ },
58
58
  "./workflows/steps/wait-for-decision": {
59
59
  "types": "./dist/src/steps/wait-for-decision.d.ts",
60
60
  "import": "./dist/src/steps/wait-for-decision.js"
@@ -78,12 +78,19 @@
78
78
  "./workflows/steps/sleep": {
79
79
  "types": "./dist/src/steps/sleep.d.ts",
80
80
  "import": "./dist/src/steps/sleep.js"
81
+ },
82
+ "./workflows/steps/wait-for-command": {
83
+ "types": "./dist/src/steps/wait-for-command.d.ts",
84
+ "import": "./dist/src/steps/wait-for-command.js"
85
+ },
86
+ "./workflows/steps/command-wait": {
87
+ "types": "./dist/src/steps/command-wait.d.ts",
88
+ "import": "./dist/src/steps/command-wait.js"
81
89
  }
82
90
  },
83
91
  "files": [
84
92
  "dist/src",
85
93
  "dist/tools",
86
- "dist/workflows",
87
94
  "templates",
88
95
  "assets/watch-fonts/fira-code-latin-400-normal.woff2",
89
96
  "assets/watch-fonts/fira-code-latin-500-normal.woff2",
@@ -112,7 +119,7 @@
112
119
  "x64"
113
120
  ],
114
121
  "scripts": {
115
- "build": "tsc --project tsconfig.build.json && node tools/copy-workflow-declarations.ts workflows dist/workflows",
122
+ "build": "tsc --project tsconfig.build.json",
116
123
  "build:workflows": "node tools/compile-workflows.ts",
117
124
  "check:setup": "node tools/check-shells.ts && tsc --project tsconfig.json --noEmit",
118
125
  "check:quality": "node tools/check-quality.ts",
@@ -121,7 +128,7 @@
121
128
  "check:format": "prettier --check src tools quality test eslint.config.mjs package.json tsconfig.json tsconfig.build.json",
122
129
  "test:quality": "node --test test/quality/*.test.ts",
123
130
  "record:test-durations": "node tools/record-test-durations.ts",
124
- "test:scale": "node --test --test-concurrency=1 test/authority-opening-scale.benchmark.ts",
131
+ "test:scale": "node --test --test-concurrency=1 test/authority-opening-scale.benchmark.ts test/status-scale.benchmark.ts",
125
132
  "check": "node tools/quality-pending.ts",
126
133
  "test:concurrency": "node tools/quality-pending.ts"
127
134
  },
@@ -150,6 +157,7 @@
150
157
  "preact": "11.0.0",
151
158
  "solid-objects": "1.0.2",
152
159
  "typescript": "6.0.3",
153
- "workflow": "5.1.0"
160
+ "workflow": "5.1.0",
161
+ "yaml": "2.9.1"
154
162
  }
155
163
  }
@@ -1,6 +1,6 @@
1
1
  # Develop template decisions
2
2
 
3
- `template.json` describes the five decisions used by the develop template.
3
+ `template.json` describes the six decisions used by the develop template.
4
4
  The default workflow in `develop.ts` accepts the declared ticket input, selects
5
5
  from the queue, opens a pull request, waits for Greptile at 5/5, and calls
6
6
  `mergeWhenGreen` with `check: "beforeMerge"`. Its declaration and helper files
@@ -14,13 +14,26 @@ review or repairable merge result gives its full output and remaining work to
14
14
  the next worker turn. Review, local-check, conflict and CI fixes share a limit
15
15
  of three fix rounds. Pending CI and an unconfigured check stop the run.
16
16
 
17
+ `develop/pull.ts` keeps the first line of the ticket as the pull request title,
18
+ removes leading `#` characters and limits it to 200 characters. For a task with
19
+ a GitHub issue, the pull request body links that issue and names its number:
20
+
21
+ ```text
22
+ Refs cloving-ai/cloving-ai#375
23
+
24
+ Cloving made this change for the ticket 375.
25
+ ```
26
+
27
+ A task without a GitHub issue uses only `Cloving made this change for this task.`
28
+
17
29
  `develop.test.ts` and `develop/flow-tests.ts` test the default composition through the public fake
18
30
  step bridge. The alternative configurations use `develop/option-tests.ts`, with the selected
19
31
  point IDs in `develop/scenarios.ts`. For an edited copy, replace the default
20
32
  `flowTests` and `refusalTests` imports in `develop.test.ts` with
21
33
  `optionTests as flowTests`, then run every `flowTests` scenario. Keep the shared
22
- turn and partial-helper tests. Package tests apply each source edit, validate
23
- its requirements, and test seven complete configurations through the folder
34
+ turn, partial-helper and interruption tests. `develop/interruption-tests.ts`
35
+ follows the selected point IDs, so it tests each configuration. Package tests apply each source edit, validate
36
+ its requirements, and test ten complete configurations through the folder
24
37
  loader and the installed package, covering every option.
25
38
 
26
39
  `develop/turn.ts` implements the development turn for either a resolved
@@ -32,6 +45,22 @@ allow the initial turn and three fix turns; the workflow must stop after that.
32
45
  The package tests also load small compositions of this helper through folder
33
46
  admission for both input forms and test both forms in complete workflows.
34
47
 
48
+ `developReport` in `develop/report.ts` runs the turn again once when its result
49
+ has the reason `claude-turn-interrupted`. This occurs when the daemon cannot
50
+ resume an open turn after a restart. Before the daemon reports this reason, it
51
+ stops the processes of the earlier turn in the work tree. The new turn has the same target, so the
52
+ daemon gives it the same work tree. Its scope adds the key `continuation`, and
53
+ its prompt tells the worker that the earlier turn stopped before its report.
54
+ The worker checks the work tree, the commits since the start of the round, and
55
+ the ticket before it continues.
56
+
57
+ After a second interruption of the same turn, `developReport` returns a blocked
58
+ outcome with the reason `turn-interrupted`. `develop/round.ts` and
59
+ `develop/local.ts` return this outcome before they use the report. A
60
+ pull-request workflow then adds `cloving: blocked` to the GitHub issue of the
61
+ ticket. Other results that are not `completed` fail the run. The default effect
62
+ limit of 31 includes one more turn in each of the four rounds.
63
+
35
64
  `develop/partial.ts` implements the person's partial-work question.
36
65
  `develop/partial-choice.ts` connects its answer to a development report and the
37
66
  next round, or returns a blocked outcome without opening a review or merging. `reviewPartial`
@@ -56,10 +85,70 @@ Task text keeps its full contents, including any issue-looking lines, without
56
85
  selecting an issue to label, close or return to the queue.
57
86
 
58
87
  The first option of each point is the default: ticket input, queue selection,
59
- Greptile at 5/5, merge after checks, and return partial work to the queue.
88
+ no additional verification, Greptile at 5/5, merge after checks, and return
89
+ partial work to the queue.
60
90
  Selecting `person` at selection, acceptance and partial work, with `local` at
61
91
  merge, describes the existing reviewed local-branch process.
62
92
 
93
+ The `verify` point defaults to `none`, preserving the current round and
94
+ declaration. Select `red-green` with either `green` or `person` at `merge`.
95
+ Import `verifyRedGreen` from `develop/red-green.ts` in `develop/round.ts`.
96
+ Immediately after `openPull`, before constructing the review subject or
97
+ calling `acceptWork`, add:
98
+
99
+ ```typescript
100
+ const verification = await verifyRedGreen({
101
+ cycleId: input.cycleId,
102
+ head: pull.commit,
103
+ round,
104
+ });
105
+ if (verification !== null && "kind" in verification) return verification;
106
+ if (verification !== null)
107
+ return repair({ cycleId: input.cycleId, round, report, result: verification });
108
+ ```
109
+
110
+ Add `"command"` to `workflow.capabilities`, `"commands": ["red-green"]` to
111
+ `workflow`, and `"command": ["run:red-green"]` to `methods` in
112
+ `develop.declaration.json`. Increase `workflow.effectLimit` by 4, from 31 to
113
+ 35, allowing one verification command in each of the four development rounds.
114
+ Set `selection.verify` to `"red-green"` in `develop/scenarios.ts` and run the
115
+ option tests. The local merge option does not support this verification.
116
+
117
+ The helper calls the operator command on the pull request's immutable head with
118
+ scope `{ phase: "verify", operation: "red-green", round }`.
119
+ `accepted` and `no-test-change` proceed to review. `false-red`,
120
+ `red-not-assertion`, `skipped-test` and `green-failed` pass the verdict and full
121
+ tool output through `repair` to the next fix turn. These fixes share the
122
+ existing four-round limit with review and merge fixes. `prepare-failed`, a
123
+ failed command or an invalid result blocks immediately with
124
+ `red-green-unavailable`, without a fix turn.
125
+
126
+ Register `red-green` in `CLOVING_COMMANDS` as an argument array containing the
127
+ absolute path of the installed `cloving` executable followed by `"red-green"`.
128
+ Configure the project file `.cloving/config.json`, for example:
129
+
130
+ ```json
131
+ {
132
+ "version": 1,
133
+ "checks": {
134
+ "redGreen": {
135
+ "test": ["node", "--test"],
136
+ "testFiles": ["test/"],
137
+ "prepare": ["npm", "ci", "--ignore-scripts"]
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ The tool appends changed test paths to `test`; optional `prepare` runs in each
144
+ temporary worktree. The daemon passes this configuration as
145
+ `CLOVING_RED_GREEN`. For direct tool use, set that variable to the `redGreen`
146
+ object. The repository needs `refs/remotes/origin/HEAD` to identify the base.
147
+ Increase `CLOVING_COMMAND_SECONDS`, for example to `600`, to cover both
148
+ preparation and test runs. Optional `assertionPattern` and `skipPattern`
149
+ override the defaults for non-terminal `node --test` output. See the package
150
+ README's `cloving red-green` documentation for the tool's complete contract.
151
+
63
152
  Each option has an `id`, `label`, `summary`, `change`, `requires` and `needs`.
64
153
  `change` describes the step call or declaration edit for the setup agent.
65
154
  It is guidance for editing source, rather than an executable patch.
@@ -116,6 +116,10 @@ flowTests.push({
116
116
  (request) => request[0] === "effect" && request[1].method === "open-pr",
117
117
  );
118
118
  assert.ok(opened && opened[0] === "effect");
119
+ assert.deepEqual(JSON.parse(opened[1].payload), {
120
+ title: "Fix the counter",
121
+ body: "Refs acme/demo#42\n\nCloving made this change for the ticket 42.",
122
+ });
119
123
  assert.doesNotMatch(opened[1].payload, /private-check-output/);
120
124
  },
121
125
  });
@@ -123,7 +127,7 @@ flowTests.push({
123
127
  flowTests.push({
124
128
  name: "CLV-221 the default workflow merges only a reviewed pull after the checks",
125
129
  run: async () => {
126
- using bridge = fakeStepBridge({ effects: effects(), effectLimit: 27 });
130
+ using bridge = fakeStepBridge({ effects: effects(), effectLimit: 31 });
127
131
  assert.deepEqual(await develop(input), {
128
132
  kind: "handoff_requested",
129
133
  cycleId: input.cycleId,
@@ -355,3 +359,36 @@ flowTests.push({
355
359
  });
356
360
  },
357
361
  });
362
+
363
+ flowTests.push({
364
+ name: "the develop turns keep fail-closed checks and operator steps out of the remaining list",
365
+ run: async () => {
366
+ const scenario = effects();
367
+ for (const key of [
368
+ "claude run-turn",
369
+ "github open-pr",
370
+ "github wait-review",
371
+ ] as const)
372
+ scenario[key] = [...scenario[key], ...scenario[key]];
373
+ scenario["github merge"] = [
374
+ completed({ reason: "check-failed", output: "Check output.\n" }),
375
+ ...scenario["github merge"],
376
+ ];
377
+ using bridge = fakeStepBridge({ effects: scenario });
378
+ await develop(input);
379
+ const payloads = bridge.requests.flatMap((request) =>
380
+ request[0] === "effect" && request[1].method === "run-turn"
381
+ ? [request[1].payload]
382
+ : [],
383
+ );
384
+ for (const sentence of [
385
+ "List as remaining only work that the task asks for.",
386
+ "A check that the repository keeps fail-closed on purpose is not remaining work.",
387
+ "A step that the task gives to the operator is not remaining work.",
388
+ ])
389
+ assert.ok(payloads[0]?.includes(sentence), sentence);
390
+ assert.ok(
391
+ payloads[1]?.includes("Drop an item that the task does not ask for"),
392
+ );
393
+ },
394
+ });