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,30 +1,15 @@
1
+ import { commandJson, decisionRequest, errorObject, readCommandReply, readCommandRequest, runCommandRequest, runRequest, } from "./command-requests.js";
1
2
  import { reportCommand } from "./report.js";
3
+ import { scheduleServiceRequest } from "./schedule-arguments.js";
4
+ import { queueServiceRequest } from "./queue-arguments.js";
2
5
  import { withCiReruns } from "./github-ci-progress.js";
3
6
  import { readFile } from "node:fs/promises";
4
7
  import { resolve } from "node:path";
5
8
  import { record, } from "../protocol.js";
6
9
  import { follow, listRuns, mutate, send } from "./client.js";
7
- import { errorText, eventText, pendingSummary, rendered, runOverview, statusJson, } from "./render.js";
10
+ import { errorText, eventText, pendingSummary, rendered, runOverview, } from "./render.js";
8
11
  import { commandUsage } from "./usage.js";
9
12
  import { defaultWatchPort, watchServer } from "./watch-server.js";
10
- function errorObject(error, format) {
11
- if (error.code === "event-gap")
12
- return {
13
- schemaVersion: 1,
14
- kind: "event-gap",
15
- after: error["after"],
16
- earliestAvailable: error["earliestAvailable"],
17
- latestSequence: error["latestSequence"],
18
- };
19
- return {
20
- schemaVersion: 1,
21
- kind: "error",
22
- ...error,
23
- commandId: error["commandId"] ?? format.commandId ?? null,
24
- runId: error["runId"] ?? null,
25
- currentRevision: error["currentRevision"] ?? null,
26
- };
27
- }
28
13
  function failed(environment, failure) {
29
14
  const { terminal } = environment;
30
15
  const shown = errorObject(failure.error, failure.format);
@@ -42,16 +27,14 @@ function presented(environment, outcome) {
42
27
  if (reply.kind === "error")
43
28
  return failed(environment, { error: reply.error, format });
44
29
  environment.terminal.out(format.json
45
- ? `${JSON.stringify(statusJson(reply.result))}\n`
30
+ ? `${JSON.stringify(commandJson(reply))}\n`
46
31
  : rendered(reply.result));
47
32
  return 0;
48
33
  }
49
34
  async function requested(environment, exchange) {
50
- const reply = await send(environment.runtimeDirectory, exchange.request);
35
+ const reply = await readCommandReply(environment.runtimeDirectory, exchange.request);
51
36
  return presented(environment, {
52
- reply: exchange.request.operation === "status"
53
- ? await withCiReruns(environment.runtimeDirectory, reply)
54
- : reply,
37
+ reply,
55
38
  format: exchange.format,
56
39
  });
57
40
  }
@@ -73,7 +56,8 @@ function identified(environment, invocation) {
73
56
  environment.terminal.error(`Command ID: ${commandId}\n`);
74
57
  return { json, commandId, announced: !json };
75
58
  }
76
- async function inputFile(environment, file) {
59
+ async function inputFile(environment, input) {
60
+ const { file, commandId } = input;
77
61
  let text;
78
62
  try {
79
63
  text = await readFile(resolve(environment.workingDirectory, file), "utf8");
@@ -87,8 +71,9 @@ async function inputFile(environment, file) {
87
71
  },
88
72
  };
89
73
  }
74
+ let submission;
90
75
  try {
91
- return { kind: "read", submission: JSON.parse(text) };
76
+ submission = record(JSON.parse(text));
92
77
  }
93
78
  catch {
94
79
  return {
@@ -99,37 +84,37 @@ async function inputFile(environment, file) {
99
84
  },
100
85
  };
101
86
  }
102
- }
103
- function typed(source) {
104
- return source.kind === "prompt"
105
- ? { prompt: source.text }
106
- : { ticket: source.id };
87
+ if (submission === undefined)
88
+ return {
89
+ kind: "error",
90
+ error: {
91
+ commandId,
92
+ detail: "The submission is not an object.",
93
+ code: "invalid-submission",
94
+ },
95
+ };
96
+ return { kind: "read", source: { kind: "input", submission } };
107
97
  }
108
98
  async function run(environment, invocation) {
109
99
  const format = identified(environment, invocation);
110
- const { commandId } = format;
111
100
  const { source } = invocation;
112
101
  const read = source.kind === "input"
113
- ? await inputFile(environment, source.file)
114
- : { kind: "read", submission: typed(source) };
102
+ ? await inputFile(environment, {
103
+ file: source.file,
104
+ commandId: format.commandId,
105
+ })
106
+ : { kind: "read", source };
115
107
  if (read.kind === "error")
116
108
  return failed(environment, { error: read.error, format });
117
109
  return mutated(environment, {
118
110
  format,
119
- request: {
120
- operation: "run",
121
- parameters: {
122
- workflowId: invocation.workflowId,
123
- source: source.kind,
124
- submission: read.submission,
125
- commandId,
126
- },
127
- },
111
+ request: runRequest({
112
+ workflowId: invocation.workflowId,
113
+ source: read.source,
114
+ commandId: format.commandId,
115
+ }),
128
116
  });
129
117
  }
130
- function present(values) {
131
- return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== null));
132
- }
133
118
  async function summarized(environment) {
134
119
  const pending = await send(environment.runtimeDirectory, {
135
120
  operation: "questions",
@@ -139,11 +124,11 @@ async function summarized(environment) {
139
124
  environment.terminal.out(pendingSummary(pending.result));
140
125
  }
141
126
  async function status(environment, invocation) {
142
- const { runId, limit, after, json } = invocation;
127
+ const { runId, limit, after, active, json } = invocation;
143
128
  if (!json && runId === null)
144
129
  await summarized(environment);
145
130
  if (!json && runId === null && limit === null && after === null) {
146
- const reply = await withCiReruns(environment.runtimeDirectory, await listRuns(environment.runtimeDirectory));
131
+ const reply = await withCiReruns(environment.runtimeDirectory, await listRuns(environment.runtimeDirectory, active ? { active } : {}));
147
132
  return presented(environment, {
148
133
  format: { json },
149
134
  reply: reply.kind === "result"
@@ -153,45 +138,34 @@ async function status(environment, invocation) {
153
138
  }
154
139
  return requested(environment, {
155
140
  format: { json },
156
- request: {
157
- operation: "status",
158
- parameters: present({ runId, limit, after }),
159
- },
141
+ request: readCommandRequest(invocation),
160
142
  });
161
143
  }
162
144
  function decision(environment, invocation) {
163
145
  const format = identified(environment, invocation);
164
- const { commandId } = format;
165
146
  return mutated(environment, {
166
147
  format,
167
- request: {
168
- operation: "decision",
169
- parameters: present({
170
- command: invocation.command,
171
- reference: invocation.reference,
172
- text: invocation.text,
173
- expectedRevision: invocation.expectedRevision,
174
- generation: invocation.generation,
175
- subjectDigest: invocation.subjectDigest,
176
- commandId,
177
- }),
178
- },
148
+ request: decisionRequest({
149
+ command: invocation.command,
150
+ reference: invocation.reference,
151
+ text: invocation.text,
152
+ expectedRevision: invocation.expectedRevision,
153
+ generation: invocation.generation,
154
+ subjectDigest: invocation.subjectDigest,
155
+ commandId: format.commandId,
156
+ }),
179
157
  });
180
158
  }
181
159
  function runCommand(environment, invocation) {
182
160
  const format = identified(environment, invocation);
183
- const { commandId } = format;
184
161
  return mutated(environment, {
185
162
  format,
186
- request: {
187
- operation: "run-command",
188
- parameters: {
189
- command: invocation.command,
190
- runId: invocation.runId,
191
- expectedRevision: invocation.expectedRevision,
192
- commandId,
193
- },
194
- },
163
+ request: runCommandRequest({
164
+ command: invocation.command,
165
+ runId: invocation.runId,
166
+ expectedRevision: invocation.expectedRevision,
167
+ commandId: format.commandId,
168
+ }),
195
169
  });
196
170
  }
197
171
  async function events(environment, invocation) {
@@ -200,15 +174,7 @@ async function events(environment, invocation) {
200
174
  const print = (event) => {
201
175
  terminal.out(json ? `${JSON.stringify(event)}\n` : `${eventText(event)}\n`);
202
176
  };
203
- const request = {
204
- operation: "events",
205
- parameters: present({
206
- runId: invocation.runId,
207
- after: invocation.after,
208
- limit: invocation.limit,
209
- follow: following,
210
- }),
211
- };
177
+ const request = readCommandRequest(invocation);
212
178
  const reply = following
213
179
  ? await follow(environment.runtimeDirectory, {
214
180
  request,
@@ -240,6 +206,13 @@ export function runtimeCommand(invocation, environment) {
240
206
  return located(invocation, { ...environment, runtimeDirectory });
241
207
  }
242
208
  function located(invocation, environment) {
209
+ if (invocation.kind === "schedule")
210
+ return requested(environment, {
211
+ format: { json: invocation.json },
212
+ request: scheduleServiceRequest(invocation),
213
+ });
214
+ if (invocation.kind === "queue")
215
+ return queue(environment, invocation);
243
216
  if (invocation.kind === "report")
244
217
  return reportCommand(invocation, environment);
245
218
  if (invocation.kind === "run")
@@ -256,10 +229,19 @@ function located(invocation, environment) {
256
229
  return watch(environment, invocation);
257
230
  return requested(environment, {
258
231
  format: { json: invocation.json },
259
- request: {
260
- operation: "questions",
261
- parameters: present({ runId: invocation.runId }),
262
- },
232
+ request: readCommandRequest(invocation),
233
+ });
234
+ }
235
+ function queue(environment, invocation) {
236
+ if (invocation.action === "show")
237
+ return requested(environment, {
238
+ format: { json: invocation.json },
239
+ request: { operation: "queue", parameters: {} },
240
+ });
241
+ const format = identified(environment, invocation);
242
+ return mutated(environment, {
243
+ format,
244
+ request: queueServiceRequest(invocation, format.commandId),
263
245
  });
264
246
  }
265
247
  function watch(environment, invocation) {
@@ -1,3 +1,3 @@
1
- import { type SettingChange } from "../configuration-change.ts";
1
+ import { type SettingChange, type HarnessChange } from "../configuration-change.ts";
2
2
  export declare function readConfigFile(path: string): Promise<string | undefined>;
3
- export declare function changeConfigFile(path: string, change: SettingChange): Promise<void>;
3
+ export declare function changeConfigFile(path: string, change: SettingChange | HarnessChange): Promise<void>;
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { chmod, mkdir, readFile, rename, rm, stat, writeFile, } from "node:fs/promises";
3
3
  import { dirname } from "node:path";
4
4
  import { acquireSettingsLock, releaseSettingsLock } from "./config-lock.js";
5
- import { changedConfiguration, } from "../configuration-change.js";
5
+ import { changedConfiguration, selectedHarnessConfiguration, } from "../configuration-change.js";
6
6
  export async function readConfigFile(path) {
7
7
  try {
8
8
  return await readFile(path, "utf8");
@@ -38,7 +38,9 @@ export async function changeConfigFile(path, change) {
38
38
  }
39
39
  async function writeChange(path, change) {
40
40
  const previous = await readConfigFile(path);
41
- const next = changedConfiguration(previous, change);
41
+ const next = "harness" in change
42
+ ? selectedHarnessConfiguration(previous, change.harness)
43
+ : changedConfiguration(previous, change);
42
44
  const mode = previous !== undefined && change.scope === "project"
43
45
  ? (await stat(path)).mode & 0o777
44
46
  : 0o600;
@@ -1,6 +1,7 @@
1
1
  import net from "node:net";
2
2
  import { join } from "node:path";
3
3
  import { socketAddress } from "../broker/socket-address.js";
4
+ import { reloadedSettingFields } from "../project-settings.js";
4
5
  import { runtimeDirectory } from "./runtime-directory.js";
5
6
  function serviceDirectory(repository) {
6
7
  try {
@@ -40,7 +41,9 @@ export async function configNotice(repository, input) {
40
41
  const source = input.entry?.source;
41
42
  const hidden = source === "environment" ||
42
43
  (input.scope === "project" && source === "private");
43
- return hidden
44
- ? `The ${source} source hides this file value. A restart keeps the value of that source.`
44
+ if (hidden)
45
+ return `The ${source} source hides this file value. A restart keeps the value of that source.`;
46
+ return reloadedSettingFields.includes(String(input.entry?.field))
47
+ ? "Run cloving reload to use the new value."
45
48
  : "Restart the service to use the new value.";
46
49
  }
@@ -0,0 +1,2 @@
1
+ import type { DoctorObservation } from "../doctor-report.ts";
2
+ export declare function retentionObservation(state: string, environment: Readonly<NodeJS.ProcessEnv>): Promise<DoctorObservation>;
@@ -0,0 +1,93 @@
1
+ import { lstat, readdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { retentionSettings, sharedRecordFolders, } from "../record-retention.js";
4
+ const kinds = ["journal", "github"];
5
+ const dayMilliseconds = 86_400_000;
6
+ const warningBytes = 1_000_000_000;
7
+ const units = [
8
+ ["GB", 1_000_000_000],
9
+ ["MB", 1_000_000],
10
+ ["kB", 1_000],
11
+ ];
12
+ function counted(count, noun) {
13
+ return `${String(count)} ${noun}${count === 1 ? "" : "s"}`;
14
+ }
15
+ function sizeText(bytes) {
16
+ const unit = units.find(([, scale]) => bytes >= scale);
17
+ if (unit === undefined)
18
+ return counted(bytes, "byte");
19
+ return `${(bytes / unit[1]).toFixed(1)} ${unit[0]}`;
20
+ }
21
+ async function treeUse(path) {
22
+ const entries = await readdir(path, { withFileTypes: true, recursive: true });
23
+ const files = await Promise.all(entries
24
+ .filter((entry) => entry.isFile())
25
+ .map((entry) => lstat(join(entry.parentPath, entry.name))));
26
+ return files.reduce((use, file) => ({
27
+ size: use.size + file.size,
28
+ changedAt: Math.max(use.changedAt, file.mtimeMs),
29
+ }), { size: 0, changedAt: Number.NEGATIVE_INFINITY });
30
+ }
31
+ async function entryUse(path) {
32
+ const entry = await lstat(path);
33
+ if (!entry.isDirectory())
34
+ return { size: entry.size, changedAt: Number.NaN, folder: false };
35
+ return { ...(await treeUse(path)), folder: true };
36
+ }
37
+ async function kindUse(state, kind) {
38
+ const folder = join(state, kind);
39
+ const names = await readdir(folder).catch(() => []);
40
+ const uses = await Promise.all(names.map(async (name) => {
41
+ const use = await entryUse(join(folder, name));
42
+ const shared = sharedRecordFolders.includes(`${kind}/${name}`);
43
+ return { ...use, record: use.folder && !shared };
44
+ }));
45
+ const records = uses.filter((use) => use.record);
46
+ return {
47
+ kind,
48
+ size: uses.reduce((total, use) => total + use.size, 0),
49
+ folders: records.length,
50
+ oldest: records
51
+ .map((use) => use.changedAt)
52
+ .filter(Number.isFinite)
53
+ .reduce((oldest, changedAt) => Math.min(oldest, changedAt), Infinity),
54
+ };
55
+ }
56
+ function settingsText(settings, state) {
57
+ const archive = settings.archiveFolder ?? `null (${join(state, "archive")})`;
58
+ return `retention.days ${String(settings.days)}, retention.action ${settings.action}, retention.archiveFolder ${archive}`;
59
+ }
60
+ function ageText(oldest, now) {
61
+ if (!Number.isFinite(oldest))
62
+ return "no kept folders";
63
+ const days = Math.floor((now - oldest) / dayMilliseconds);
64
+ return `oldest kept folder ${counted(days, "day")} old`;
65
+ }
66
+ export async function retentionObservation(state, environment) {
67
+ try {
68
+ const settings = retentionSettings(environment);
69
+ const uses = await Promise.all(kinds.map((kind) => kindUse(state, kind)));
70
+ const oldest = Math.min(...uses.map((use) => use.oldest));
71
+ const unlimited = settings.days === null &&
72
+ uses.reduce((total, use) => total + use.size, 0) > warningBytes;
73
+ return {
74
+ result: unlimited ? "warn" : "ok",
75
+ detail: [
76
+ uses
77
+ .map((use) => `${use.kind} ${sizeText(use.size)} in ${counted(use.folders, "folder")}`)
78
+ .join("; "),
79
+ ageText(oldest, Date.now()),
80
+ settingsText(settings, state),
81
+ ...(unlimited
82
+ ? ["the records are larger than 1 GB and retention.days is null"]
83
+ : []),
84
+ ].join("; "),
85
+ };
86
+ }
87
+ catch (error) {
88
+ return {
89
+ result: "fail",
90
+ detail: error instanceof Error ? error.message : "Records unavailable",
91
+ };
92
+ }
93
+ }
@@ -1,3 +1,6 @@
1
- import type { DoctorWorkflow } from "../doctor-report.ts";
2
- export declare const bundledDoctorWorkflows: DoctorWorkflow[];
1
+ import type { DoctorObservation, DoctorWorkflow } from "../doctor-report.ts";
2
+ export declare function workflowObservation(context: {
3
+ readonly workflows: readonly DoctorWorkflow[];
4
+ readonly prerequisite: string | undefined;
5
+ }): DoctorObservation;
3
6
  export declare function doctorWorkflows(repository: string, environment: Readonly<NodeJS.ProcessEnv>): Promise<readonly DoctorWorkflow[]>;
@@ -3,12 +3,17 @@ import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { configurationRoot, absoluteWorkflowFolder, } from "../project-settings.js";
5
5
  import { isCandidateDeclaration } from "../workflow-candidate.js";
6
- import { bundledWorkflowIds } from "../workflow-discovery.js";
7
- export const bundledDoctorWorkflows = Object.values(bundledWorkflowIds).map((workflowId) => ({
8
- scope: "bundled",
9
- workflowId,
10
- capabilities: ["claude", "github"],
11
- }));
6
+ export function workflowObservation(context) {
7
+ if (context.prerequisite !== undefined)
8
+ return { result: "skip", detail: context.prerequisite };
9
+ const found = context.workflows.length > 0;
10
+ return {
11
+ result: found ? "ok" : "fail",
12
+ detail: found
13
+ ? "Project or user workflow found"
14
+ : "No project or user workflow",
15
+ };
16
+ }
12
17
  export async function doctorWorkflows(repository, environment) {
13
18
  const discovered = [];
14
19
  for (const [scope, folder] of [
@@ -41,5 +46,5 @@ export async function doctorWorkflows(repository, environment) {
41
46
  discovered.push({ scope, ...declaration.workflow });
42
47
  }
43
48
  }
44
- return [...bundledDoctorWorkflows, ...discovered];
49
+ return discovered;
45
50
  }
@@ -3,9 +3,10 @@ import { dirname, delimiter, join } from "node:path";
3
3
  import { doctorCodes, doctorExitCode, doctorFixes, requiredDoctorCodes, } from "../doctor-report.js";
4
4
  import { privateSettingsPath, projectSettings } from "./project-settings.js";
5
5
  import { githubObservations } from "./doctor-github.js";
6
- import { bundledDoctorWorkflows, doctorWorkflows } from "./doctor-workflows.js";
6
+ import { doctorWorkflows, workflowObservation } from "./doctor-workflows.js";
7
7
  import { runtimeObservation, serviceObservation } from "./doctor-runtime.js";
8
8
  import { harnessObservations } from "./doctor-harness.js";
9
+ import { retentionObservation } from "./doctor-retention.js";
9
10
  import { commandObservation, nodeObservation, privateTextsObservation, queueObservation, } from "./doctor-local.js";
10
11
  function settings(repository, environment) {
11
12
  try {
@@ -40,7 +41,7 @@ export async function doctorReport(options) {
40
41
  const found = repository === undefined
41
42
  ? {
42
43
  observations: {},
43
- required: requiredDoctorCodes([], { queueSeconds: undefined }),
44
+ required: requiredDoctorCodes([]),
44
45
  }
45
46
  : await repositoryObservations({ ...options, repository });
46
47
  const git = repository === undefined
@@ -76,6 +77,10 @@ async function repositoryObservations(options) {
76
77
  environment,
77
78
  probe,
78
79
  });
80
+ observations["retention"] =
81
+ location.runtime === undefined || location.observation.result !== "ok"
82
+ ? { result: "skip", detail: "Runtime prerequisite unavailable" }
83
+ : await retentionObservation(dirname(location.runtime), environment);
79
84
  const project = location.project;
80
85
  const serviceEnvironment = {
81
86
  ...environment,
@@ -94,18 +99,15 @@ async function repositoryObservations(options) {
94
99
  settingsValid,
95
100
  environment,
96
101
  });
97
- const required = requiredDoctorCodes(workflowContext.workflows, {
98
- queueSeconds: settingsValid
99
- ? environment["CLOVING_QUEUE_SECONDS"]
100
- : undefined,
101
- });
102
+ observations["no-workflow"] = workflowObservation(workflowContext);
103
+ const required = requiredDoctorCodes(workflowContext.workflows);
102
104
  const dependent = await configuredObservations({ ...options, environment }, { prerequisite: workflowContext.prerequisite, project, serviceEnvironment });
103
105
  return { observations: { ...observations, ...dependent }, required };
104
106
  }
105
107
  async function workflowRequirements(repository, context) {
106
108
  if (!context.settingsValid)
107
109
  return {
108
- workflows: bundledDoctorWorkflows,
110
+ workflows: [],
109
111
  prerequisite: "Settings files are invalid",
110
112
  };
111
113
  try {
@@ -116,7 +118,7 @@ async function workflowRequirements(repository, context) {
116
118
  }
117
119
  catch (error) {
118
120
  return {
119
- workflows: bundledDoctorWorkflows,
121
+ workflows: [],
120
122
  prerequisite: `Workflow requirements unavailable: ${error instanceof Error ? error.message : "discovery failed"}`,
121
123
  };
122
124
  }
@@ -1,8 +1,10 @@
1
1
  import type { ProbeRunner } from "./probe-command.ts";
2
+ import { type ShellMode } from "../agent-harness-shell.ts";
2
3
  export interface HarnessEntry {
3
4
  readonly name: string;
4
5
  readonly kind: "file" | "shell";
5
6
  readonly path: string;
7
+ readonly shellMode?: ShellMode;
6
8
  readonly version: string | null;
7
9
  readonly working: boolean;
8
10
  readonly reason: string | null;
@@ -87,7 +87,7 @@ async function probeShell(candidate, context) {
87
87
  env,
88
88
  });
89
89
  const stdout = shellBlock(output.stdout, 0);
90
- return probeEntry({ name, kind, path }, {
90
+ return probeEntry({ name, kind, path, ...(kind === "shell" ? { shellMode: mode } : {}) }, {
91
91
  stdout: stdout ?? "",
92
92
  reason: output.reason ?? (stdout === null ? "shell-protocol" : null),
93
93
  });
@@ -0,0 +1,6 @@
1
+ interface HarnessProcessEffects {
2
+ readonly snapshot: () => string;
3
+ readonly kill: (identifier: number, signal: "SIGTERM") => boolean;
4
+ }
5
+ export declare function terminateHarness(identifier: number | undefined, effects: HarnessProcessEffects): void;
6
+ export {};
@@ -0,0 +1,36 @@
1
+ function harnessProcesses(identifier, effects) {
2
+ let snapshot;
3
+ try {
4
+ snapshot = effects.snapshot();
5
+ }
6
+ catch {
7
+ return [identifier];
8
+ }
9
+ const rows = snapshot
10
+ .trim()
11
+ .split("\n")
12
+ .map((row) => row.trim().split(/\s+/).map(Number));
13
+ const identifiers = [identifier];
14
+ for (let index = 0; index < identifiers.length; index++) {
15
+ for (const [child, parent] of rows) {
16
+ if (parent === identifiers[index] && child !== undefined && child > 0)
17
+ identifiers.push(child);
18
+ }
19
+ }
20
+ return identifiers;
21
+ }
22
+ export function terminateHarness(identifier, effects) {
23
+ if (identifier === undefined)
24
+ return;
25
+ for (const target of harnessProcesses(identifier, effects).reverse()) {
26
+ try {
27
+ effects.kill(target, "SIGTERM");
28
+ }
29
+ catch (error) {
30
+ if (!(error instanceof Error) ||
31
+ !("code" in error) ||
32
+ error.code !== "ESRCH")
33
+ throw error;
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,9 @@
1
+ import { type HarnessStartRequest } from "../harness-start.ts";
2
+ import type { ProbeRunner } from "./probe-command.ts";
3
+ export declare function initCommand(context: {
4
+ readonly repository: string | undefined;
5
+ readonly environment: Readonly<NodeJS.ProcessEnv>;
6
+ readonly probe: ProbeRunner;
7
+ readonly harness: string | undefined;
8
+ readonly start: (request: HarnessStartRequest) => Promise<number | null>;
9
+ }): Promise<number>;
@@ -0,0 +1,52 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { harnessStartRequest, } from "../harness-start.js";
3
+ import { changeConfigFile } from "./config-file.js";
4
+ import { chooseHarness, selectedHarness } from "./init-selection.js";
5
+ import { privateSettingsPath, projectSettings } from "./project-settings.js";
6
+ export async function initCommand(context) {
7
+ if (context.repository === undefined) {
8
+ process.stderr.write("not-a-repository: run git init.\n");
9
+ return 1;
10
+ }
11
+ try {
12
+ const entry = context.harness === undefined
13
+ ? await promptHarness({ ...context, repository: context.repository })
14
+ : await selectedHarness(context.harness, context);
15
+ await changeConfigFile(privateSettingsPath(context.environment, context.repository), {
16
+ harness: { name: entry.name, kind: entry.kind, path: entry.path },
17
+ scope: "private",
18
+ });
19
+ const request = harnessStartRequest(entry, {
20
+ repository: context.repository,
21
+ environment: context.environment,
22
+ message: "run `cloving init-prompt`",
23
+ });
24
+ const status = await context.start(request);
25
+ if (status !== null)
26
+ return status;
27
+ process.stderr.write("Open your agent in this repository and tell it: run `cloving init-prompt`.\n");
28
+ return 1;
29
+ }
30
+ catch (error) {
31
+ process.stderr.write((error instanceof Error ? error.message : "init-failed") + "\n");
32
+ return 2;
33
+ }
34
+ }
35
+ async function promptHarness(context) {
36
+ if (!process.stdin.isTTY || !process.stdout.isTTY)
37
+ throw new Error("harness-not-selected");
38
+ const terminal = createInterface({
39
+ input: process.stdin,
40
+ output: process.stdout,
41
+ });
42
+ try {
43
+ return await chooseHarness({
44
+ ...context,
45
+ current: projectSettings(context.environment, context.repository).harness,
46
+ question: (text) => terminal.question(text),
47
+ });
48
+ }
49
+ finally {
50
+ terminal.close();
51
+ }
52
+ }
@@ -0,0 +1,10 @@
1
+ import { type InitPromptFacts } from "./init-prompt.ts";
2
+ import type { ProbeRunner } from "./probe-command.ts";
3
+ interface PromptContext {
4
+ readonly repository: string | undefined;
5
+ readonly environment: Readonly<NodeJS.ProcessEnv>;
6
+ readonly probe: ProbeRunner;
7
+ }
8
+ export declare function initPromptFacts(context: PromptContext): Promise<InitPromptFacts>;
9
+ export declare function initPromptCommand(context: PromptContext): Promise<number>;
10
+ export {};