tumwater 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. package/README.md +27 -13
  2. package/dist/build-info.json +2 -2
  3. package/dist/src/agent/agent-args.js +8 -9
  4. package/dist/src/agent/agent-backend.js +8 -6
  5. package/dist/src/agent/backend-traits.js +55 -25
  6. package/dist/src/agent/claude/claude-account.js +71 -204
  7. package/dist/src/agent/claude/claude-args.js +9 -6
  8. package/dist/src/agent/claude/claude-backend.js +10 -10
  9. package/dist/src/agent/claude/claude-env.js +1 -1
  10. package/dist/src/agent/claude/claude-stream.js +6 -4
  11. package/dist/src/agent/claude/claude-write-guard.js +49 -0
  12. package/dist/src/agent/claude/write-guard-hook.js +13 -0
  13. package/dist/src/agent/codex/codex-account.js +119 -0
  14. package/dist/src/agent/codex/codex-args.js +181 -0
  15. package/dist/src/agent/codex/codex-backend.js +279 -0
  16. package/dist/src/agent/codex/codex-catalog.js +97 -0
  17. package/dist/src/agent/codex/codex-env.js +18 -0
  18. package/dist/src/agent/codex/codex-hook-trust.js +246 -0
  19. package/dist/src/agent/codex/codex-patch-paths.js +36 -0
  20. package/dist/src/agent/codex/codex-rollout.js +179 -0
  21. package/dist/src/agent/codex/codex-stream.js +404 -0
  22. package/dist/src/agent/codex/codex-write-guard.js +86 -0
  23. package/dist/src/agent/codex/write-guard-hook.js +12 -0
  24. package/dist/src/agent/image-input.js +29 -24
  25. package/dist/src/agent/notes-shim.js +11 -12
  26. package/dist/src/agent/opencode/opencode-args.js +0 -1
  27. package/dist/src/agent/opencode/opencode-backend.js +12 -9
  28. package/dist/src/agent/opencode/opencode-catalog.js +55 -29
  29. package/dist/src/agent/opencode/opencode-config.js +19 -14
  30. package/dist/src/agent/opencode/opencode-env.js +0 -1
  31. package/dist/src/agent/opencode/opencode-session-id.js +1 -2
  32. package/dist/src/agent/opencode/opencode-stream.js +1 -1
  33. package/dist/src/agent/opencode/write-guard-plugin/index.js +48 -0
  34. package/dist/src/agent/role-notes-write.js +5 -6
  35. package/dist/src/agent/run-agent.js +465 -448
  36. package/dist/src/agent/run-settle.js +214 -0
  37. package/dist/src/agent/session-ledger.js +86 -16
  38. package/dist/src/agent/subscription-account.js +220 -0
  39. package/dist/src/agent/write-guard.js +148 -0
  40. package/dist/src/backlog/backlog-archive.js +281 -55
  41. package/dist/src/backlog/backlog-cli-view.js +255 -0
  42. package/dist/src/backlog/backlog-cli.js +91 -335
  43. package/dist/src/backlog/backlog-commit.js +20 -13
  44. package/dist/src/backlog/backlog-eligibility.js +193 -242
  45. package/dist/src/backlog/backlog-index.js +149 -0
  46. package/dist/src/backlog/backlog-md.js +54 -6
  47. package/dist/src/backlog/backlog-parts.js +264 -0
  48. package/dist/src/backlog/backlog-release.js +134 -0
  49. package/dist/src/backlog/backlog-render.js +27 -0
  50. package/dist/src/backlog/backlog-structure.js +99 -156
  51. package/dist/src/backlog/backlog-write.js +40 -127
  52. package/dist/src/backlog/backlog.js +21 -6
  53. package/dist/src/backlog/question-answer.js +21 -15
  54. package/dist/src/baseline/main-baseline.js +89 -20
  55. package/dist/src/baseline/main-guardrails.js +136 -0
  56. package/dist/src/baseline/main-red.js +153 -36
  57. package/dist/src/baseline/main-watch.js +232 -0
  58. package/dist/src/brief/brief-edit.js +12 -12
  59. package/dist/src/brief/brief.js +31 -51
  60. package/dist/src/budget/budget-fallback-view.js +288 -0
  61. package/dist/src/budget/budget-wiring.js +158 -0
  62. package/dist/src/budget/budget.js +31 -20
  63. package/dist/src/budget/fallback-breaker.js +26 -27
  64. package/dist/src/build/build-check-detect.js +23 -15
  65. package/dist/src/build/build-check-events.js +25 -6
  66. package/dist/src/build/build-check-report.js +49 -9
  67. package/dist/src/build/build-check-scoped.js +18 -11
  68. package/dist/src/build/build-check.js +2 -1
  69. package/dist/src/build/build-info.js +2 -3
  70. package/dist/src/build/build-stage.js +9 -14
  71. package/dist/src/build/dep-install.js +65 -3
  72. package/dist/src/change/change-data.js +123 -31
  73. package/dist/src/change/change-render.js +46 -5
  74. package/dist/src/cli/brief-command.js +3 -4
  75. package/dist/src/cli/cli-args.js +181 -33
  76. package/dist/src/cli/cli-command-args.js +46 -18
  77. package/dist/src/cli/cli-editor.js +2 -1
  78. package/dist/src/cli/cli-flag-specs.js +183 -45
  79. package/dist/src/cli/cli-init.js +51 -0
  80. package/dist/src/cli/cli-marker-commands.js +4 -4
  81. package/dist/src/cli/cli-query-commands.js +291 -598
  82. package/dist/src/cli/cli-repo-gate.js +11 -1
  83. package/dist/src/cli/cli-review-commands.js +113 -0
  84. package/dist/src/cli/cli-role-command.js +525 -0
  85. package/dist/src/cli/cli-start-summary.js +167 -0
  86. package/dist/src/cli/{cli-run.js → cli-start.js} +193 -237
  87. package/dist/src/cli/completion.js +169 -22
  88. package/dist/src/cli/config-commands.js +58 -26
  89. package/dist/src/cli/follow-view.js +75 -0
  90. package/dist/src/cli/help.js +258 -82
  91. package/dist/src/cli/log-commands.js +164 -85
  92. package/dist/src/cli/question-commands.js +211 -10
  93. package/dist/src/cli.js +173 -45
  94. package/dist/src/collections.js +56 -13
  95. package/dist/src/concurrency/check-permit.js +20 -3
  96. package/dist/src/concurrency/lock.js +17 -13
  97. package/dist/src/concurrency/provider-lease.js +44 -8
  98. package/dist/src/concurrency/semaphore.js +102 -26
  99. package/dist/src/config/config-aliases.js +0 -1
  100. package/dist/src/config/config-editable-keys.js +16 -1
  101. package/dist/src/config/config-fallbacks.js +94 -56
  102. package/dist/src/config/config-field-checks.js +40 -10
  103. package/dist/src/config/config-keys.js +30 -8
  104. package/dist/src/config/config-live.js +63 -24
  105. package/dist/src/config/config-request.js +137 -0
  106. package/dist/src/config/config-schema.js +31 -24
  107. package/dist/src/config/config-selector-checks.js +123 -0
  108. package/dist/src/config/config-validation-agents.js +80 -0
  109. package/dist/src/config/config-validation-model.js +116 -0
  110. package/dist/src/config/config-validation.js +169 -222
  111. package/dist/src/config/config-views.js +136 -54
  112. package/dist/src/config/config-write-core.js +135 -0
  113. package/dist/src/config/config-write.js +164 -265
  114. package/dist/src/config/config.js +53 -38
  115. package/dist/src/config/model-selector.js +34 -34
  116. package/dist/src/doctor/doctor-backlog-bugs.js +330 -0
  117. package/dist/src/doctor/doctor-backlog-plans.js +398 -0
  118. package/dist/src/doctor/doctor-backlog.js +249 -512
  119. package/dist/src/doctor/doctor-check-names.js +85 -0
  120. package/dist/src/doctor/doctor-checks.js +61 -593
  121. package/dist/src/doctor/doctor-claude-checks.js +142 -0
  122. package/dist/src/doctor/doctor-codex-checks.js +276 -0
  123. package/dist/src/doctor/doctor-contention-checks.js +506 -0
  124. package/dist/src/doctor/doctor-fallback-checks.js +130 -0
  125. package/dist/src/doctor/doctor-holds.js +80 -66
  126. package/dist/src/doctor/doctor-install.js +2 -1
  127. package/dist/src/doctor/doctor-model-checks.js +216 -537
  128. package/dist/src/doctor/doctor-notify.js +9 -5
  129. package/dist/src/doctor/doctor-opencode-checks.js +164 -0
  130. package/dist/src/doctor/doctor-orphans.js +182 -63
  131. package/dist/src/doctor/doctor-pi-checks.js +62 -0
  132. package/dist/src/doctor/doctor-project-checks.js +397 -0
  133. package/dist/src/doctor/doctor.js +126 -77
  134. package/dist/src/doctor/image-probe.js +21 -8
  135. package/dist/src/doctor/outcome.js +3 -2
  136. package/dist/src/doctor/probe.js +21 -12
  137. package/dist/src/events/event-format.js +185 -89
  138. package/dist/src/events/event-labels.js +11 -5
  139. package/dist/src/events/event-legacy.js +39 -15
  140. package/dist/src/events/event-read.js +52 -39
  141. package/dist/src/events/event-tally.js +16 -0
  142. package/dist/src/events/event-window.js +80 -26
  143. package/dist/src/events/events.js +30 -13
  144. package/dist/src/events/notify.js +7 -7
  145. package/dist/src/failure/failure-cluster.js +12 -12
  146. package/dist/src/failure/failure-data.js +65 -60
  147. package/dist/src/failure/failure-render.js +29 -21
  148. package/dist/src/failure/failure-state-change.js +17 -12
  149. package/dist/src/failure/time-spend.js +35 -35
  150. package/dist/src/files/file-queue.js +17 -0
  151. package/dist/src/files/files.js +111 -35
  152. package/dist/src/files/json-files.js +3 -3
  153. package/dist/src/files/json-object.js +28 -7
  154. package/dist/src/files/stat-cache.js +2 -2
  155. package/dist/src/files/tail.js +1 -1
  156. package/dist/src/gates/bootstrap-gates.js +4 -5
  157. package/dist/src/gates/budget-gates.js +88 -225
  158. package/dist/src/gates/disk-gate.js +1 -1
  159. package/dist/src/gates/gate-polls.js +101 -143
  160. package/dist/src/gates/maintenance-quota.js +37 -30
  161. package/dist/src/gates/pause-gates.js +28 -10
  162. package/dist/src/gates/readiness.js +7 -3
  163. package/dist/src/gates/role-cap-gates.js +8 -8
  164. package/dist/src/gates/startup-gate.js +94 -32
  165. package/dist/src/gates/streak-gate.js +54 -30
  166. package/dist/src/git/commit-message.js +89 -46
  167. package/dist/src/git/git-diff.js +16 -10
  168. package/dist/src/git/git-run.js +79 -38
  169. package/dist/src/git/git.js +54 -34
  170. package/dist/src/git/slot-salvage.js +253 -0
  171. package/dist/src/git/slots-state.js +6 -6
  172. package/dist/src/git/worktree-pool.js +132 -38
  173. package/dist/src/git/worktree-use.js +4 -11
  174. package/dist/src/git/worktree.js +94 -37
  175. package/dist/src/gui/gui-admin-endpoints.js +96 -0
  176. package/dist/src/gui/gui-args.js +79 -8
  177. package/dist/src/gui/gui-backlog-commands.js +43 -19
  178. package/dist/src/gui/gui-backlog-endpoints.js +156 -0
  179. package/dist/src/gui/gui-command.js +26 -13
  180. package/dist/src/gui/gui-config-commands.js +168 -80
  181. package/dist/src/gui/gui-endpoint-commands.js +5 -4
  182. package/dist/src/gui/gui-endpoint-common.js +4 -4
  183. package/dist/src/gui/gui-endpoints.js +11 -380
  184. package/dist/src/gui/gui-history-endpoints.js +301 -0
  185. package/dist/src/gui/gui-operator-commands.js +235 -13
  186. package/dist/src/gui/gui-prompt-commands.js +26 -20
  187. package/dist/src/gui/gui-report-endpoints.js +97 -0
  188. package/dist/src/gui/gui-server.js +26 -5
  189. package/dist/src/gui/gui-team-commands.js +7 -7
  190. package/dist/src/gui/http-body.js +1 -1
  191. package/dist/src/history/history-data.js +122 -234
  192. package/dist/src/history/history-queued.js +155 -0
  193. package/dist/src/history/history-render.js +42 -22
  194. package/dist/src/history/history.js +190 -49
  195. package/dist/src/inbox/inbox-attachments.js +29 -30
  196. package/dist/src/inbox/inbox-cancel.js +10 -11
  197. package/dist/src/inbox/inbox-edit.js +9 -9
  198. package/dist/src/inbox/inbox-submit.js +18 -18
  199. package/dist/src/inbox/inbox-top.js +28 -17
  200. package/dist/src/inbox/inbox.js +42 -43
  201. package/dist/src/inbox/pending-prompt.js +26 -26
  202. package/dist/src/inbox/prompt-commands.js +62 -49
  203. package/dist/src/inbox/prompt-not-before.js +2 -2
  204. package/dist/src/init/init-templates.js +1 -2
  205. package/dist/src/init/init.js +28 -23
  206. package/dist/src/merge/backlog-conflicts.js +215 -35
  207. package/dist/src/merge/merge-batch.js +14 -8
  208. package/dist/src/merge/merge-cancel.js +53 -0
  209. package/dist/src/merge/merge-check-failures.js +44 -22
  210. package/dist/src/merge/merge-core.js +58 -32
  211. package/dist/src/merge/merge-diff.js +5 -4
  212. package/dist/src/merge/merge-drain.js +45 -19
  213. package/dist/src/merge/merge-git.js +177 -38
  214. package/dist/src/merge/merge-pipeline.js +15 -3
  215. package/dist/src/merge/merge-post-review.js +214 -0
  216. package/dist/src/merge/merge-queue-render.js +48 -11
  217. package/dist/src/merge/merge-queue.js +52 -15
  218. package/dist/src/merge/merge-requeue.js +103 -0
  219. package/dist/src/merge/merge-slot.js +61 -16
  220. package/dist/src/merge/merge-stack.js +27 -11
  221. package/dist/src/merge/merge-to-main.js +77 -26
  222. package/dist/src/merge/merge-top.js +83 -0
  223. package/dist/src/merge/merge-verify.js +75 -18
  224. package/dist/src/notes-cli.js +35 -15
  225. package/dist/src/operator/operator-commands.js +192 -81
  226. package/dist/src/operator/operator-intent.js +69 -42
  227. package/dist/src/operator/operator-requests.js +35 -40
  228. package/dist/src/operator/retire.js +5 -6
  229. package/dist/src/operator/revert.js +142 -34
  230. package/dist/src/orchestrator/orchestrator-launch.js +60 -52
  231. package/dist/src/orchestrator/orchestrator-poll.js +352 -0
  232. package/dist/src/orchestrator/orchestrator-scheduling.js +71 -370
  233. package/dist/src/orchestrator/orchestrator.js +129 -369
  234. package/dist/src/orchestrator/retention.js +42 -8
  235. package/dist/src/orchestrator/scheduling-admit.js +116 -0
  236. package/dist/src/orchestrator/scheduling-scope.js +245 -0
  237. package/dist/src/orchestrator/scheduling-skip.js +195 -0
  238. package/dist/src/orchestrator/startup-migration-steps.js +8 -7
  239. package/dist/src/orchestrator/startup-migrations.js +11 -7
  240. package/dist/src/paths.js +126 -49
  241. package/dist/src/pi/command-shape.js +12 -1
  242. package/dist/src/pi/pi-args.js +6 -4
  243. package/dist/src/pi/pi-backend.js +6 -6
  244. package/dist/src/pi/pi-bin.js +54 -63
  245. package/dist/src/pi/pi-listed-models.js +53 -0
  246. package/dist/src/pi/pi-models.js +63 -30
  247. package/dist/src/pi/pi-run-result.js +1 -1
  248. package/dist/src/pi/pi-settings.js +1 -1
  249. package/dist/src/pi/pi-stream.js +6 -6
  250. package/dist/src/pi/pi-watchdogs.js +18 -19
  251. package/dist/src/pi-extension/bounded-output.js +5 -3
  252. package/dist/src/pi-extension/context-budget.js +2 -2
  253. package/dist/src/pi-extension/context-shake.js +1 -1
  254. package/dist/src/pi-extension/context-window.js +0 -1
  255. package/dist/src/pi-extension/full-output.js +3 -10
  256. package/dist/src/pi-extension/strip-thinking.js +0 -1
  257. package/dist/src/pi-extension/trim-system-prompt.js +3 -4
  258. package/dist/src/pi-extension/write-guard.js +37 -0
  259. package/dist/src/process/launch-services.js +1 -2
  260. package/dist/src/process/node-bin.js +16 -0
  261. package/dist/src/process/process-group.js +8 -18
  262. package/dist/src/process/process.js +41 -2
  263. package/dist/src/process/run-marker.js +26 -6
  264. package/dist/src/process/supervisor.js +22 -21
  265. package/dist/src/prompt/dialect.js +17 -2
  266. package/dist/src/prompt/gate-notes.js +203 -0
  267. package/dist/src/prompt/gate-prompts.js +150 -217
  268. package/dist/src/prompt/notes-backlog.js +184 -0
  269. package/dist/src/prompt/principles.js +1 -2
  270. package/dist/src/prompt/prompt-followup.js +19 -14
  271. package/dist/src/prompt/prompt.js +131 -204
  272. package/dist/src/redeploy/redeploy-policy.js +24 -19
  273. package/dist/src/redeploy/redeploy-probes.js +1 -1
  274. package/dist/src/redeploy/redeploy.js +2 -3
  275. package/dist/src/redeploy/redeployer.js +20 -20
  276. package/dist/src/redeploy/self-reload.js +2 -1
  277. package/dist/src/report/report-data.js +188 -124
  278. package/dist/src/report/report-fold.js +130 -54
  279. package/dist/src/report/report-main-red.js +55 -0
  280. package/dist/src/report/report-render.js +136 -65
  281. package/dist/src/report/report-types.js +1 -0
  282. package/dist/src/report/report.js +23 -9
  283. package/dist/src/request-timeouts.js +2 -2
  284. package/dist/src/review/diff-rules.js +53 -0
  285. package/dist/src/review/known-flakes.js +112 -1
  286. package/dist/src/review/post-merge-review-accept.js +51 -0
  287. package/dist/src/review/post-merge-review-render.js +112 -0
  288. package/dist/src/review/post-merge-review.js +239 -0
  289. package/dist/src/review/protected-edits.js +24 -10
  290. package/dist/src/review/quarantine-render.js +65 -0
  291. package/dist/src/review/review-followup.js +8 -8
  292. package/dist/src/review/review-precheck.js +66 -23
  293. package/dist/src/review/review-run.js +395 -0
  294. package/dist/src/review/review-verdict.js +2 -2
  295. package/dist/src/review/review.js +180 -401
  296. package/dist/src/review/secret-leaks.js +36 -16
  297. package/dist/src/review/suite-rerun.js +0 -1
  298. package/dist/src/roles/legacy-role-migration.js +80 -7
  299. package/dist/src/roles/role-catalog.js +127 -12
  300. package/dist/src/roles/role-guidance.js +65 -20
  301. package/dist/src/roles/role-labels.js +7 -5
  302. package/dist/src/roles/role-render.js +108 -56
  303. package/dist/src/roles/role-view.js +95 -56
  304. package/dist/src/roles/roles.js +33 -33
  305. package/dist/src/roles/runner-ids.js +97 -0
  306. package/dist/src/run/acceptance-greps.js +119 -0
  307. package/dist/src/run/ci-parity.js +121 -0
  308. package/dist/src/run/feedback-filings.js +51 -0
  309. package/dist/src/run/qa-coverage.js +125 -0
  310. package/dist/src/{tick/tick-apply.js → run/run-apply.js} +95 -94
  311. package/dist/src/run/run-detail-data.js +175 -0
  312. package/dist/src/run/run-detail-render.js +91 -0
  313. package/dist/src/run/run-detail.js +168 -0
  314. package/dist/src/{tick/tick-finalize.js → run/run-finalize.js} +73 -60
  315. package/dist/src/{tick/tick-outcome.js → run/run-outcome.js} +6 -7
  316. package/dist/src/{tick/tick-prompt.js → run/run-prompt.js} +122 -73
  317. package/dist/src/{tick/tick-resume.js → run/run-resume.js} +55 -26
  318. package/dist/src/{tick/tick-stage.js → run/run-stage.js} +170 -83
  319. package/dist/src/{tick/tick-timing.js → run/run-timing.js} +43 -41
  320. package/dist/src/{tick/tick-usage.js → run/run-usage.js} +45 -37
  321. package/dist/src/{tick/tick-verdict.js → run/run-verdict.js} +105 -57
  322. package/dist/src/run/selfcheck-digest.js +40 -0
  323. package/dist/src/run/stage-backlog-checks.js +249 -0
  324. package/dist/src/run/stage-check.js +178 -0
  325. package/dist/src/run/stage-checks-shared.js +65 -0
  326. package/dist/src/run/stage-name-checks.js +204 -0
  327. package/dist/src/run/stage-path-checks.js +231 -0
  328. package/dist/src/run/stage-prose-checks.js +261 -0
  329. package/dist/src/runner/leftover.js +216 -0
  330. package/dist/src/{loop → runner}/model-fallback.js +12 -12
  331. package/dist/src/runner/revision.js +191 -0
  332. package/dist/src/{loop/loop-fallback.js → runner/runner-fallback.js} +8 -8
  333. package/dist/src/runner/runner-outcome.js +109 -0
  334. package/dist/src/{loop/loop-pi.js → runner/runner-pi.js} +140 -131
  335. package/dist/src/{loop/loop-recovery.js → runner/runner-recovery.js} +39 -18
  336. package/dist/src/{loop/loop-tick.js → runner/runner-run.js} +236 -245
  337. package/dist/src/{loop/loop-state.js → runner/runner-state-load.js} +61 -114
  338. package/dist/src/runner/runner-state.js +103 -0
  339. package/dist/src/{loop/loop.js → runner/runner.js} +123 -120
  340. package/dist/src/scheduling/backoff.js +38 -38
  341. package/dist/src/scheduling/claim-entries.js +49 -0
  342. package/dist/src/scheduling/claims.js +35 -22
  343. package/dist/src/scheduling/once-round.js +22 -22
  344. package/dist/src/scheduling/quiet-hours.js +5 -6
  345. package/dist/src/scheduling/scheduling.js +74 -64
  346. package/dist/src/scheduling/work-merged-cache.js +2 -2
  347. package/dist/src/status/status-budget.js +55 -47
  348. package/dist/src/status/status-data.js +49 -17
  349. package/dist/src/status/status-inbox.js +2 -2
  350. package/dist/src/status/status-install.js +0 -1
  351. package/dist/src/status/status-polls.js +43 -28
  352. package/dist/src/status/status-roles.js +50 -13
  353. package/dist/src/team/error-storm.js +8 -8
  354. package/dist/src/team/failure-spread.js +2 -2
  355. package/dist/src/team/orchestrator-info.js +15 -9
  356. package/dist/src/team/reclaim.js +7 -8
  357. package/dist/src/team/team-hold.js +7 -7
  358. package/dist/src/team/team-polls.js +91 -50
  359. package/dist/src/team/team-state.js +8 -2
  360. package/dist/src/text/datetime.js +65 -18
  361. package/dist/src/text/format.js +48 -11
  362. package/dist/src/text/markdown.js +8 -5
  363. package/dist/src/text/phrases.js +60 -23
  364. package/dist/src/text/suggest.js +1 -1
  365. package/dist/src/text/text.js +78 -13
  366. package/dist/src/ui/badges.js +99 -38
  367. package/dist/src/ui/gui/gui-client-backlog.js +314 -0
  368. package/dist/src/ui/gui/gui-client-boot.js +89 -61
  369. package/dist/src/ui/gui/gui-client-composer.js +8 -9
  370. package/dist/src/ui/gui/gui-client-drawer-config.js +254 -0
  371. package/dist/src/ui/gui/gui-client-drawer.js +155 -289
  372. package/dist/src/ui/gui/gui-client-feed.js +271 -0
  373. package/dist/src/ui/gui/gui-client-history.js +437 -68
  374. package/dist/src/ui/gui/gui-client-labels.js +6 -3
  375. package/dist/src/ui/gui/gui-client-markdown.js +1 -2
  376. package/dist/src/ui/gui/gui-client-model.js +27 -36
  377. package/dist/src/ui/gui/gui-client-operator.js +60 -52
  378. package/dist/src/ui/gui/gui-client-pending.js +405 -24
  379. package/dist/src/ui/gui/gui-client-report-chart.js +492 -0
  380. package/dist/src/ui/gui/gui-client-report.js +105 -430
  381. package/dist/src/ui/gui/{gui-client-loops.js → gui-client-roles.js} +43 -44
  382. package/dist/src/ui/gui/gui-client-settings.js +163 -5
  383. package/dist/src/ui/gui/gui-client-team.js +36 -465
  384. package/dist/src/ui/gui/gui-client.js +38 -26
  385. package/dist/src/ui/gui/gui-icons.js +0 -2
  386. package/dist/src/ui/gui/gui-page.js +10 -7
  387. package/dist/src/ui/gui/gui-styles.js +38 -34
  388. package/dist/src/ui/progress-data.js +9 -11
  389. package/dist/src/ui/{tick-progress-model.js → run-progress-model.js} +33 -32
  390. package/dist/src/ui/status-model.js +133 -125
  391. package/dist/src/ui/status-payload.js +364 -49
  392. package/dist/src/ui/status-render.js +109 -82
  393. package/dist/src/ui/team-alerts.js +728 -62
  394. package/dist/src/ui/tone.js +12 -6
  395. package/dist/src/ui/transcript-run.js +58 -0
  396. package/dist/src/ui/transcript-tail.js +28 -20
  397. package/dist/src/ui/transcript.js +63 -23
  398. package/dist/src/ui/tui/tui-app.js +0 -1
  399. package/dist/src/ui/tui/tui-backlog.js +53 -14
  400. package/dist/src/ui/tui/tui-editor-answer.js +27 -31
  401. package/dist/src/ui/tui/tui-editor-attach.js +4 -12
  402. package/dist/src/ui/tui/tui-editor-backends.js +127 -0
  403. package/dist/src/ui/tui/tui-editor-brief.js +14 -36
  404. package/dist/src/ui/tui/tui-editor-budget.js +36 -39
  405. package/dist/src/ui/tui/tui-editor-check.js +29 -0
  406. package/dist/src/ui/tui/tui-editor-checks.js +28 -0
  407. package/dist/src/ui/tui/tui-editor-claude-reserve.js +24 -0
  408. package/dist/src/ui/tui/tui-editor-concurrency.js +25 -0
  409. package/dist/src/ui/tui/tui-editor-config.js +99 -0
  410. package/dist/src/ui/tui/tui-editor-entry.js +39 -64
  411. package/dist/src/ui/tui/tui-editor-fallback.js +31 -0
  412. package/dist/src/ui/tui/tui-editor-instances.js +46 -0
  413. package/dist/src/ui/tui/tui-editor-instructions.js +117 -0
  414. package/dist/src/ui/tui/tui-editor-interval.js +29 -16
  415. package/dist/src/ui/tui/tui-editor-model.js +29 -0
  416. package/dist/src/ui/tui/tui-editor-notes.js +9 -29
  417. package/dist/src/ui/tui/tui-editor-notify.js +25 -0
  418. package/dist/src/ui/tui/tui-editor-pause.js +48 -59
  419. package/dist/src/ui/tui/tui-editor-prompt.js +11 -16
  420. package/dist/src/ui/tui/tui-editor-provider-caps.js +27 -0
  421. package/dist/src/ui/tui/tui-editor-queued.js +5 -9
  422. package/dist/src/ui/tui/tui-editor-quiet.js +95 -41
  423. package/dist/src/ui/tui/tui-editor-retire.js +5 -13
  424. package/dist/src/ui/tui/tui-editor-role-enabled.js +126 -0
  425. package/dist/src/ui/tui/tui-editor-role-key.js +71 -0
  426. package/dist/src/ui/tui/tui-editor-role-model.js +28 -0
  427. package/dist/src/ui/tui/tui-editor-search.js +45 -33
  428. package/dist/src/ui/tui/tui-editor-session.js +101 -34
  429. package/dist/src/ui/tui/tui-editor-slots.js +24 -0
  430. package/dist/src/ui/tui/tui-editors.js +44 -2
  431. package/dist/src/ui/tui/tui-frame.js +68 -11
  432. package/dist/src/ui/tui/tui-history.js +8 -9
  433. package/dist/src/ui/tui/tui-input.js +13 -11
  434. package/dist/src/ui/tui/tui-keymap.js +0 -1
  435. package/dist/src/ui/tui/tui-keys.js +33 -9
  436. package/dist/src/ui/tui/tui-pane-activity.js +35 -19
  437. package/dist/src/ui/tui/tui-pane-backlog.js +198 -126
  438. package/dist/src/ui/tui/tui-pane-brief.js +0 -1
  439. package/dist/src/ui/tui/tui-pane-ctx.js +2 -2
  440. package/dist/src/ui/tui/tui-pane-health.js +168 -8
  441. package/dist/src/ui/tui/tui-pane-history.js +446 -82
  442. package/dist/src/ui/tui/tui-pane-pending.js +539 -15
  443. package/dist/src/ui/tui/tui-pane-queued.js +78 -57
  444. package/dist/src/ui/tui/tui-pane-report.js +54 -16
  445. package/dist/src/ui/tui/tui-pane-session.js +34 -6
  446. package/dist/src/ui/tui/tui-pane-transcript.js +111 -37
  447. package/dist/src/ui/tui/tui-pane.js +91 -28
  448. package/dist/src/ui/tui/tui-panes.js +153 -34
  449. package/dist/src/ui/tui/tui.js +18 -15
  450. package/dist/src/verdict/fix-claim.js +129 -33
  451. package/dist/src/verdict/no-change.js +4 -4
  452. package/dist/src/verdict/refusal.js +40 -16
  453. package/dist/src/verdict/reply-contract.js +77 -31
  454. package/dist/src/version.js +0 -1
  455. package/package.json +2 -1
  456. package/dist/src/loop/leftover.js +0 -130
  457. package/dist/src/loop/revision.js +0 -70
  458. package/dist/src/roles/loop-ids.js +0 -77
  459. package/dist/src/tick/qa-coverage.js +0 -108
  460. package/dist/src/tick/stage-check.js +0 -419
  461. package/dist/src/tick/telemetry-digest.js +0 -25
  462. package/dist/src/tick/tick-detail-data.js +0 -108
  463. package/dist/src/tick/tick-detail.js +0 -163
  464. package/dist/src/ui/gui/gui-client-sound.js +0 -53
@@ -4,9 +4,9 @@
4
4
  * <command>` from it by splitting the usage block on its ` tumwater <command>` lines, so a
5
5
  * topic can never drift out of sync with the full listing. */
6
6
  import { suggestClosest } from "../text/suggest.js";
7
- // vocabulary: plain
8
- /** Machine names HELP quotes verbatim; the scripting series renames them. */
9
- const SUMMARY_JSON_KEYS = "{ loops, total }"; // vocabulary-ok: --json keys until the scripting series
7
+ /** The role-grouped summary's JSON keys, quoted verbatim in `history --summary --json` help
8
+ * (its `--by model` twin is the hardcoded `{ models, total }` beside it). */
9
+ const SUMMARY_JSON_KEYS = "{ roles, total }";
10
10
  export const HELP = `tumwater — an autonomous development team, built on pi
11
11
 
12
12
  Usage:
@@ -14,21 +14,26 @@ Usage:
14
14
  TUMWATER.md, --branch <name> seeds a new repo only,
15
15
  --template <id> seeds a starter brief+backlog (--list-templates
16
16
  lists them), --dry-run: write nothing)
17
- tumwater start [--branch <name>] [--once] [--for <duration>] [--role <id>] [--gui] [--tui]
17
+ tumwater start [--branch <name>] [--once] [--json] [--for <duration>] [--role <id>[,<id>...]] [--gui [--port <n>]] [--tui]
18
18
  Start the team: every enabled role runs in turn (headless;
19
19
  Ctrl+C finishes current work, then stops);
20
20
  --once does one round of runs, finishes the
21
21
  merges it produced, and exits (for cron/CI);
22
22
  exits 3 when a run ended in error, review failed,
23
23
  a merge conflicted or was blocked, or main's check is failing;
24
- --once --role <id> limits that round to one role;
24
+ --once --role <id>[,<id>...] limits that round to the listed roles;
25
+ --once --json prints the round's totals, per-result counts, skipped roles and failures as one JSON object on stdout (no banner or event stream) (the --once report; --json is refused without --once or --for);
25
26
  --for <duration> runs for that window then finishes current work, prints a per-role summary
26
27
  (one window across self-redeploys),
28
+ --for --json prints the window's per-role summary as one JSON object on stdout at exit (no banner or event stream); --json with --gui or --tui is refused;
27
29
  and exits like Ctrl+C would (for an overnight
28
30
  trial, a demo, a CI step);
29
31
  --gui also serves the browser dashboard at
30
- http://127.0.0.1:7180 (the \`tumwater gui\`
31
- defaults — see that command for --port and --token);
32
+ http://127.0.0.1:7180 and forwards to it the
33
+ dashboard flags \`--port <n>\` (pick another
34
+ port), \`--all-interfaces\` (serve the LAN) and
35
+ \`--token <secret>\` (the auth gate), exactly as
36
+ \`tumwater gui\` takes them);
32
37
  --tui also hosts the TUI in this terminal
33
38
  (the \`tumwater tui\` view — quitting it stops the
34
39
  team like Ctrl+C)
@@ -37,43 +42,72 @@ Usage:
37
42
  Same dashboard in the browser (default port 7180,
38
43
  localhost only; --all-interfaces serves the whole
39
44
  network — without --token there is no auth, anyone
40
- reaching it can message the director)
41
- tumwater status [--json] One-shot status table (--json prints machine-readable
45
+ reaching it can message the director); booting with
46
+ \`tumwater start --gui\` serves it the same way from
47
+ the one-command start, forwarding \`--port N\`,
48
+ \`--all-interfaces\` and \`--token <secret>\`
49
+ tumwater status [--role <id>[,<id>...]] [-f/--follow] [--json]
50
+ One-shot status table (--json prints machine-readable
42
51
  team state — the GUI's /api/status payload minus the
43
- serving process's serverBuildSha)
44
- tumwater report [--days N] [--role <id>] [--json]
52
+ serving process's serverBuildSha); --role keeps only the
53
+ listed roles' rows (a base id includes its instances);
54
+ -f/--follow repaints the table until Ctrl+C or the
55
+ process that started it exits, so a backgrounded follow
56
+ does not outlive its parent; the header and budget stay
57
+ team-wide
58
+ tumwater report [--days N] [--role <id>[,<id>...]] [-f/--follow] [--json]
45
59
  Markdown usage report — tokens/runs/commits per day (default
46
60
  14 days); totals also include merge runs (reviewer + conflict
47
- resolution); --role <id> scopes the report to one role's runs,
48
- tokens, cost, and commits (merge runs and backlog tallies
49
- omitted); --json prints machine-readable usage data — the
50
- collector's own payload, not the Markdown render
51
- tumwater report --failures [--days N] [--since <duration>] [--role <id>] [--json]
61
+ resolution); --role <id>[,<id>...] scopes the report to the
62
+ listed roles' runs, tokens, cost, and commits (merge runs
63
+ and backlog tallies omitted); --json prints
64
+ machine-readable usage data — the collector's own
65
+ payload, not the Markdown render;
66
+ -f/--follow repaints the report, or with --failures the
67
+ failure digest, every couple of seconds until Ctrl+C or the
68
+ process that started it exits, so a backgrounded follow does
69
+ not outlive its parent; it refuses --json and --since;
70
+ tumwater report --failures [--days N] [--since <duration>] [--role <id>[,<id>...]] [--json]
52
71
  Markdown failure digest — run outcomes, deltas,
53
72
  clustered errors, and team state changes (default
54
- 14 days); --role <id> scopes the digest to one role's
73
+ 14 days); --role <id>[,<id>...] scopes the digest to the listed roles'
55
74
  rows; --since windows the digest over a trailing
56
75
  span (capped at 7d)
57
- tumwater report --failures --since <duration> [--role <id>] [--json]
76
+ tumwater report --failures --since <duration> [--until <duration>] [--role <id>[,<id>...]] [--json]
58
77
  The failure digest over a trailing window, compared
59
- against the equal-length window before it
60
- tumwater report --since <duration> [--role <id>] [--json]
78
+ against the equal-length window before it; --until
79
+ <duration> ends both windows' span that long ago
80
+ tumwater report --since <duration> [--until <duration>] [--role <id>[,<id>...]] [--json]
61
81
  Totals over a trailing window (capped at 7d) —
62
82
  tokens/runs/commits/cost since a point in time; totals
63
83
  also include merge runs (reviewer + conflict
64
- resolution); --role <id> scopes the totals to one role
65
- (merge runs and backlog tallies omitted); not
66
- combinable with --days
67
- tumwater doctor [--json] [--reprobe] [--problems]
84
+ resolution); --role <id>[,<id>...] scopes the totals to the listed roles
85
+ (merge runs and backlog tallies omitted); --until <duration>
86
+ ends that window the given duration ago (requires --since);
87
+ not combinable with --days
88
+ tumwater doctor [<check>...] [--json] [--reprobe] [--problems] [--kill-orphans] [--commit-backlog] [--resync-install] [--drop-broken-pins] [--retire-leftovers]
68
89
  Pre-flight check: node, git, repo, config, fallback
69
90
  model, pi, locks, update, orphans, macOS port leak
70
- (read-only; exit 0/1; --json prints the report object —
91
+ (read-only unless --kill-orphans, --commit-backlog
92
+ or --resync-install or --drop-broken-pins or --retire-leftovers:
93
+ --kill-orphans first kills the orphaned processes the orphans
94
+ check lists, each with its descendants; --commit-backlog first commits each uncommitted tracked
95
+ backlog or brief file (PLANS.md, BUGS.md, QUESTIONS.md, their archives, the
96
+ brief) on the base branch under the primary-worktree lock, so a merge the
97
+ dirty file blocks can proceed; --resync-install re-syncs the root checkout's
98
+ install on demand under the merge lock, so the always-on install alert's
99
+ advice is one command; --drop-broken-pins first drops each refs/tumwater/
100
+ pin whose commit is gone — the manual git update-ref -d the tumwater pins
101
+ row names; --retire-leftovers first retires each disabled role's leftover
102
+ worktree, branch and merge ref, like tumwater retire --role <id> per role,
103
+ never --force; exit 0/1; --json prints the report object —
71
104
  header, the checks array with level, name, and detail,
72
105
  and verdict; probes image-input models — --reprobe
73
106
  re-probes every one, bypassing the 7-day cache; --problems prints only the warn
74
107
  and fail rows (and how many ok rows it hid), the same
75
108
  verdict and exit code; with --json the checks array holds
76
- only those rows)
109
+ only those rows; naming checks (as the report prints them, any case; quote names
110
+ with spaces) runs only those, and the verdict and exit code cover only them)
77
111
  tumwater config [get <key> | set <key> <value> | unset <key>]
78
112
  Show the effective config (defaults + tumwater.json) as
79
113
  JSON; get one key's resolved value as JSON; set one
@@ -89,66 +123,114 @@ Usage:
89
123
  roles still merges the built-in catalog per entry, so
90
124
  disable a role with roles.<id>.enabled false, not by
91
125
  omitting it
92
- tumwater logs [-f/--follow] [-n N] [--since <duration>] [--grep <text>] [--type <event type>] [--count] [--json]
126
+ tumwater logs [-f/--follow] [-n N] [--since <duration>] [--until <duration>] [--role <id>[,<id>...]] [--grep <text>] [--type <event type>[,<event type>...]] [--count] [--notable] [--json]
93
127
  Show (and follow) tumwater events; --since shows the
94
- events of the past window (capped at 7d); --grep shows
128
+ events of the past window (capped at 7d); --until ends that
129
+ window the given duration ago (requires --since); --grep shows
95
130
  only events whose type or rendered line matches,
96
131
  case-insensitively (-n bounds the scanned window, not
97
- the printed rows); --type shows only events of that
98
- exact event type, and an older event name matches its current one (it
132
+ the printed rows; it composes with --since); --type shows only events of the listed
133
+ exact event types (comma-separated), and an older event name matches its current one (it
99
134
  composes with --since); --count
100
135
  prints one \`N \u00d7 <type>\` line per present event type
101
136
  (most-frequent first) over the selected window instead
102
- of the rows; --json
137
+ of the rows; --notable
138
+ keeps only non-routine events, the dashboard feed's Notable
139
+ choice (it composes with --since, --grep, --type, --role,
140
+ -n, -f and --json); --json
103
141
  prints each event as one
104
142
  JSON object per line (NDJSON) — the raw event objects
105
143
  as stored in the log, instead of the rendered text
106
144
  (with --count, one JSON object mapping type \u2192 count)
107
- tumwater logs --role <id> [-f/--follow] [-n N] [--prompt]
145
+ tumwater logs --transcript <id> [-f/--follow] [-n N] [--prompt] [--grep <text>]
108
146
  Show (and follow) that role's pi transcript
109
147
  (--prompt also shows each run's exact prompt text)
148
+ (--grep keeps only the entries containing the text, under their run's separator)
110
149
  tumwater notify --test Run the configured notify hook once with a synthetic event
111
150
  so the command can be checked before a real page
112
- tumwater history [--role <id>] [-n N] [--since <duration>] [--grep <text>]
113
- [--result <merged|none|refused|problems>] [--summary] [--json]
151
+ tumwater history [--role <id>[,<id>...]] [-n N] [-f/--follow] [--since <duration>]
152
+ [--until <duration>] [--grep <text>]
153
+ [--result <merged|none|refused|problems>[,...]] [--model <selector>[,...]]
154
+ [--summary] [--by role|model] [--json]
114
155
  One row per completed run, newest first — time, role,
115
156
  run number, result, duration, tokens/cost, and the
116
157
  summary (or error), each row one line; --since <duration>
117
158
  shows the window's runs instead of the last N (capped at
118
- 7d, like logs --since); --grep <text> keeps only rows whose
119
- line matches, case-insensitively (like logs --grep);
120
- --result <class> narrows to one outcome class — merged
159
+ 7d, like logs --since); --until <duration> ends that
160
+ window the given duration ago (requires --since);
161
+ --grep <text> keeps only rows whose line matches,
162
+ case-insensitively (like logs --grep);
163
+ -f prints the last N rows oldest first, then one row
164
+ per run as it ends, until Ctrl+C or its parent exits (not
165
+ with --since or --summary); with --json, one compact
166
+ JSON row per line (the --json row shape), like logs -f --json;
167
+ --role takes a comma list, keeping the rows of any listed role;
168
+ --result <class>[,<class>...] narrows to the listed outcome classes — merged
121
169
  (merged or waiting to merge), none (no_change/skipped/user_aborted),
122
170
  refused (a run that deliberately declined its entry), or
123
171
  problems (everything else) — composed with --role, --since,
124
- -n, and --grep; --json prints the rows as
172
+ -n, and --grep; --model <selector>[,...] keeps only the
173
+ runs that started on the listed models (the exact selectors --by model prints); --json prints the rows as
125
174
  machine-readable history data — ts, tokens, and costUsd
126
175
  kept raw, the GUI's /api/history payload; --summary prints one line per role
127
176
  counting its runs by outcome class and its run time, with the time of its newest change (and a total line)
128
177
  instead of the rows; with --json, ${SUMMARY_JSON_KEYS}
129
- tumwater history <role> [<n>] [--last] [--stat] [--json]
178
+ --by model groups the summary by the model each run started on instead
179
+ of by role; with --json, { models, total }
180
+ tumwater history <role> [<n>] [--last [--result <class>[,...]] [--model <selector>[,...]]] [--stat] [--patch] [--transcript [--prompt] [--grep <text>]] [--json]
130
181
  One run's full event trail — a summary header (result, or
131
182
  in flight, with duration, tokens and cost, and the commit)
132
183
  then every event of that run in time order; a run still in
133
184
  flight shows its events so far; a run waiting to merge
134
185
  shows its merge verdict once the merge finishes; --last
135
186
  shows the role's newest finished run instead of numbering
136
- one; --stat appends the commit's per-file git show --stat
137
- summary; --json prints the collector's payload
138
- tumwater diff [--json] One line per role holding pending work — the ahead-of-main
187
+ one (with no <role>, the newest finished run of any
188
+ role); --result <class>[,...] (with --last) picks the newest
189
+ run in the listed outcome classes instead (the listing's
190
+ --result classes; scans the role's last 200 runs);
191
+ --model <selector>[,...] (with --last) picks the newest
192
+ run that started on a listed model (the listing's --model
193
+ match; composes with --result);
194
+ --stat appends the commit's per-file git show --stat
195
+ summary; --patch appends the commit's full git show patch
196
+ (after --stat's summary when both are given);
197
+ --transcript appends the agent transcript of the
198
+ runs that started in that run's window;
199
+ --prompt (with --transcript) also shows each run's exact
200
+ prompt text;
201
+ --grep <text> (with --transcript) keeps only the transcript
202
+ entries containing the text, case-insensitively, under their
203
+ run's separator (like logs --transcript --grep);
204
+ --json prints the collector's payload
205
+ tumwater diff [-f/--follow] [--json]
206
+ One line per role holding pending work — the ahead-of-main
139
207
  commit count and uncommitted-file count, no patch; roles
140
208
  with no worktree or nothing pending are skipped, and a
141
209
  missing baseline prints the per-role view's degradation
142
- line; --json prints the {mainBranch, roles} roster
143
- tumwater diff --role <id> [--stat] [--json]
210
+ line; --json prints the {mainBranch, roles} roster;
211
+ -f/--follow repaints the same view every couple of seconds
212
+ until Ctrl+C or the process that started it exits, so a
213
+ backgrounded follow does not outlive its parent; it refuses --json
214
+ tumwater diff --role <id>[,<id>...] [--stat] [--path <path>] [-f/--follow] [--json]
144
215
  Show the change that role holds: its branch's unmerged
145
216
  commits (one line each, plus the ahead-of-main patch) and
146
217
  its worktree's uncommitted edits (the file list, plus the
147
218
  patch — staged and unstaged alike); a role with no workspace
148
219
  yet prints \`no worktree for <id>\`; --stat prints each patch's per-file
149
- \`git diff --stat\` summary instead; --json prints the
150
- collector's payload as machine-readable data
151
- tumwater queue [--json] List the durable merge queue in execution order (oldest
220
+ \`git diff --stat\` summary instead; --path keeps only the commits, patch and
221
+ uncommitted edits under that repo-relative file or directory
222
+ (composes with --stat, --json and a comma list); --json prints the
223
+ collector's payload as machine-readable data; a comma list prints each listed
224
+ role's view in that order, separated by a blank line (--json: {mainBranch, roles})
225
+ tumwater diff --overlaps [--role <id>[,<id>...]] [--path <path>] [-f/--follow] [--json]
226
+ List each file two or more roles' pending changes touch
227
+ (committed ahead of main or uncommitted), one line per path
228
+ naming those roles; --role keeps only the files a listed
229
+ role holds, each still naming every holder; --path keeps only the files
230
+ at or under that repo-relative file or directory;
231
+ --json prints {mainBranch, state, overlaps}
232
+ tumwater queue [--role <id>[,<id>...]] [-f/--follow] [--json] [--cancel <n>] [--top <n>]
233
+ List the durable merge queue in execution order (oldest
152
234
  first): one line per waiting merge — position, role, run
153
235
  number, short pinned sha, age, and summary — plus a bracketed
154
236
  \`[merging 2m · reviewing]\` / \`[approved, waiting to merge]\`
@@ -156,8 +238,41 @@ Usage:
156
238
  prints \`merge queue empty\`, and any torn/foreign queue file
157
239
  the reader skipped is counted on a trailing line; --json
158
240
  prints the collector's own {entries, unreadable} document
159
- (raw sha and numeric enqueuedAt, not the render's age)
160
- tumwater backlog [--ready] [--json]
241
+ (raw sha and numeric enqueuedAt, not the render's age); --role
242
+ keeps only the listed roles' merges (a base role id taking
243
+ its instances too), each under its position in the whole
244
+ queue; --json then lists only those entries;
245
+ -f/--follow repaints the queue every couple of seconds
246
+ until Ctrl+C or the process that started it exits, so a
247
+ backgrounded follow does not outlive its parent; it refuses --json;
248
+ --cancel <n> removes the Nth queued merge before it lands (and
249
+ its role's merge pin, so next-run recovery cannot re-enqueue it),
250
+ refusing an entry a live merge is merging and --role/-f;
251
+ --top <n> moves the Nth queued merge to the front of the
252
+ execution order (so it merges next when ready), preserving any
253
+ notBefore deferral, refusing an entry a live merge is merging and
254
+ --role/-f, and answering already-first for position 1
255
+ tumwater reviews [--accept <n>] [--role <id>[,<id>...]] [--status <state>[,<state>...]] [--json]
256
+ List the post-merge review queue (\.tumwater/state
257
+ /post-review.json) in FIFO order: one line per merged commit
258
+ waiting for its review — position, role, short sha, summary,
259
+ and either its rejected reasons
260
+ (\`[rejected — <reasons>]\`) or its
261
+ failed-review-run count (\`[N failed review runs]\`); an empty
262
+ queue prints \`post-merge review queue empty\`; --json prints
263
+ the normalized { pending: [...] } list for scripts; --role
264
+ keeps only the listed roles' entries (a base role id taking
265
+ its instances too), each under its position in the whole
266
+ queue; --status keeps only the entries in the listed states
267
+ (waiting, failing, rejected; an entry turned back is rejected
268
+ first), each under its position in the whole queue, and
269
+ composes with --role; --accept <n>
270
+ removes the Nth queued entry (the position \`tumwater reviews\`
271
+ prints) as deliberately accepted unreviewed, logging a warning;
272
+ it refuses an entry whose repair already merged (\`fixed\`);
273
+ no ready-repo gate for the read, a missing or torn file degrades
274
+ to the empty or well-formed list
275
+ tumwater backlog [--ready] [--grep <text>] [-f/--follow] [--json]
161
276
  Show planned features, open bugs, and open questions (the
162
277
  dashboards' backlog view); --json prints machine-readable
163
278
  backlog data — the three entry arrays as {title, body}, the
@@ -167,12 +282,25 @@ Usage:
167
282
  working on carries \`[working on it: feature #2]\` (--json:
168
283
  an \`inProgress\` key parallel to the arrays); --ready keeps only the
169
284
  planned plans and open bugs no hold keeps from being
170
- picked (entries a role is working on stay)
171
- tumwater archive Move the finished entries still under PLANS.md ## Done and
285
+ picked (entries a role is working on stay); --grep keeps the
286
+ entries whose heading or body contains the text, case-insensitively;
287
+ -f/--follow repaints the backlog every couple of seconds until
288
+ Ctrl+C or the process that started it exits, so a backgrounded
289
+ follow does not outlive its parent; it refuses --json
290
+ tumwater quarantine [--json] List the flake quarantine — the tests the review gate recorded
291
+ as failing then passing on the same tree
292
+ (.tumwater/state/quarantine.json), oldest first, each naming
293
+ its first-seen and last-seen age, flake count, and the BUGS.md
294
+ entry filed for it (or "not filed"); empty prints
295
+ "flake quarantine is empty"; --json prints the same rows as
296
+ { tests: [...] }; it is read-only — a test leaves the list only
297
+ when its filed bug leaves BUGS.md ## Open
298
+ tumwater archive [--json] Move the finished entries still under PLANS.md ## Done and
172
299
  BUGS.md ## Fixed to the top of PLANS-DONE.md and BUGS-FIXED.md
173
300
  and commit them on the base branch, waiting for a merge in
174
301
  progress; a starting team does the same, and a role's own
175
- finished entry moves when its change commits
302
+ finished entry moves when its change commits;
303
+ --json prints what moved and the commit as data
176
304
  tumwater bug "<symptom>" [--json]
177
305
  File a bug into BUGS.md ## Open as you (stamped
178
306
  with today's date) and wake the bugfix role; --json prints
@@ -182,10 +310,11 @@ Usage:
182
310
  non-blank line is the symptom, the rest is the body kept
183
311
  line for line; wakes the bugfix role
184
312
  tumwater bug --release <n> [--json]
185
- Lift the Refused or Waiting for the next failure note from the
186
- Nth entry in BUGS.md ## Open (as \`tumwater bug --list\`
187
- lists it), commit it on main, and wake the bugfix role; --json
188
- prints {file, title}
313
+ Lift the Refused, Waiting for the next failure, or a
314
+ Needs-review/Needs-replan note held past its threshold
315
+ (one per run) from the Nth entry in BUGS.md ## Open (as
316
+ \`tumwater bug --list\` lists it), commit it on main, and wake
317
+ the bugfix role; --json prints {file, title, lifted}
189
318
  tumwater bug --top <n> [--json]
190
319
  Move the Nth entry (as \`tumwater bug --list\` lists it) to
191
320
  the head of BUGS.md ## Open, so bugfix claims it next; commit
@@ -206,11 +335,16 @@ Usage:
206
335
  With neither text nor --file, open the Nth entry as --show
207
336
  prints it in $VISUAL or $EDITOR and write it back on save;
208
337
  an unchanged buffer writes nothing
209
- tumwater bug --list [--json] List the entries in BUGS.md ## Open, numbered (the read
338
+ tumwater bug --list [--ready] [--grep <text>] [--json]
339
+ List the entries in BUGS.md ## Open, numbered (the read
210
340
  half of --edit/--cancel), each with its eligibility mark;
211
341
  --json prints the {entries} array — position, title, body,
212
342
  hold, inProgress — as data; \`[working on it: …]\` marks an
213
- entry a role is working on
343
+ entry a role is working on; --ready keeps only the entries
344
+ no hold keeps from being picked (entries a role is working
345
+ on stay), under their unfiltered numbers; --grep keeps the
346
+ entries whose heading or body contains the text,
347
+ case-insensitively
214
348
  tumwater bug --list --done [-n <count>] [--grep <text>] [--json]
215
349
  List the newest entries, numbered, in BUGS.md ## Fixed, newest first
216
350
  (default 10); --json prints {entries, older}, each entry
@@ -233,9 +367,11 @@ Usage:
233
367
  the first non-blank line is the title, the rest is the body
234
368
  kept line for line; wakes the feature role
235
369
  tumwater plan --release <n> [--json]
236
- Lift the Refused note from the Nth entry in PLANS.md ## Planned
370
+ Lift the Refused, Waiting for the next failure, or a
371
+ Needs-review/Needs-replan note held past its threshold
372
+ (one per run) from the Nth entry in PLANS.md ## Planned
237
373
  (as \`tumwater plan --list\` lists it), commit it on main,
238
- and wake the feature role; --json prints {file, title}
374
+ and wake the feature role; --json prints {file, title, lifted}
239
375
  tumwater plan --top <n> [--json]
240
376
  Move the Nth entry (as \`tumwater plan --list\` lists it) to
241
377
  the head of PLANS.md ## Planned, so feature claims it next;
@@ -256,12 +392,17 @@ Usage:
256
392
  With neither text nor --file, open the Nth entry as --show
257
393
  prints it in $VISUAL or $EDITOR and write it back on save;
258
394
  an unchanged buffer writes nothing
259
- tumwater plan --list [--json] List the entries in PLANS.md ## Planned, numbered (the
395
+ tumwater plan --list [--ready] [--grep <text>] [--json]
396
+ List the entries in PLANS.md ## Planned, numbered (the
260
397
  read half of --edit/--cancel), each with its eligibility
261
398
  mark; --json prints the {entries} array — position, title,
262
399
  body, hold, inProgress — as data; \`[working on it: …]\`
263
400
  marks an entry a role is working on; a series' blocked
264
- parts show as one line naming their positions
401
+ parts show as one line naming their positions; --ready keeps
402
+ only the entries no hold keeps from being picked (entries a
403
+ role is working on stay), under their unfiltered numbers;
404
+ --grep keeps the entries whose heading or body contains the
405
+ text, case-insensitively
265
406
  tumwater plan --list --done [-n <count>] [--grep <text>] [--json]
266
407
  List the newest entries, numbered, in PLANS.md ## Done, newest first
267
408
  (default 10); --json prints {entries, older}, each entry
@@ -275,8 +416,11 @@ Usage:
275
416
  tumwater plan --show <n> --done [--json]
276
417
  Print the Nth entry of \`plan --list --done\` (newest first) in
277
418
  full; --json prints {position, title, body, completedOn}
278
- tumwater questions [--json] List open questions numbered (the read half of the
279
- question outbox); --json prints the {questions}
419
+ tumwater questions [--grep <text>] [--json]
420
+ List open questions numbered (the read half of the
421
+ question outbox); --grep keeps the questions whose
422
+ heading or body contains the text, case-insensitively,
423
+ numbered as without it; --json prints the {questions}
280
424
  array — position, title, body — as data
281
425
  tumwater questions --answered [-n <count>] [--grep <text>] [--json]
282
426
  List the newest answered questions, numbered, newest first
@@ -317,8 +461,8 @@ Usage:
317
461
  tumwater role <id> [--json] Show one role's instructions and resolved
318
462
  settings — its built-in instructions, the roles.<id>.instructions override, the resolved
319
463
  provider/model (naming the budget fallback pair when one is
320
- configured), that model's declared context window and whether a run gets the compact
321
- prompt, the min-run interval, enabled/paused state, and
464
+ configured), that model's declared context window, the
465
+ min-run interval, enabled/paused state, and
322
466
  the next run's assembled prompt (the oldest inbox message appears in it
323
467
  and is NOT consumed — one is dequeued per run); --json prints the collector's payload
324
468
  as machine-readable data
@@ -362,6 +506,15 @@ Usage:
362
506
  for the base id
363
507
  tumwater role <id> --clear-thinking
364
508
  Clear that role's thinking level
509
+ tumwater role <id> --backend <id>
510
+ Set that role's backend (pi|claude|opencode|codex — the
511
+ agent that runs the model); a model that cannot pair with
512
+ the backend is refused (e.g. a claude backend with a
513
+ provider/model id, or a pi backend with a bare model id),
514
+ written to roles.<id>.backend for the base id
515
+ tumwater role <id> --clear-backend
516
+ Clear that role's backend (back to the team/tier
517
+ default backend)
365
518
  tumwater role <id> --enable Enable the role, written to roles.<id>.enabled
366
519
  (the base id for an instance)
367
520
  tumwater role <id> --disable Disable it (refused for the director); clean up
@@ -372,6 +525,12 @@ Usage:
372
525
  written to roles.<id>.instances for the base id
373
526
  tumwater role <id> --clear-instances
374
527
  Clear that role's instance count (back to 1)
528
+ tumwater role <id> --review-after-merge
529
+ Review that role's commits after they merge, written
530
+ to review.afterMerge (the base id for an instance)
531
+ tumwater role <id> --clear-review-after-merge
532
+ Review it before merge again, removing it from
533
+ review.afterMerge
375
534
  tumwater prompt <text...> Send a message to the director's inbox
376
535
  tumwater prompt --file <path> Send a message read from a file ("-" reads stdin)
377
536
  tumwater prompt --role <id> <text...>
@@ -386,7 +545,11 @@ Usage:
386
545
  images: png, jpg, jpeg, gif, webp, bmp; each at most 5
387
546
  MiB — saved beside the inbox file for the role's next
388
547
  run)
389
- tumwater prompt --list [--json] Show inbox messages, numbered, grouped by role
548
+ tumwater prompt --list [--role <id>[,<id>...]] [--grep <text>] [--json]
549
+ Show inbox messages, numbered, grouped by role;
550
+ --role keeps only the listed roles' sections;
551
+ --grep <text> keeps only the messages containing the
552
+ text, case-insensitively, under the same numbers
390
553
  (--json prints the {prompts} array as
391
554
  machine-readable data)
392
555
  tumwater prompt --cancel <n> Remove the Nth inbox message as --list shows them; when
@@ -410,33 +573,44 @@ Usage:
410
573
  Open the Nth inbox message in $VISUAL/$EDITOR and save it
411
574
  as the text form would; an unchanged buffer writes
412
575
  nothing; --role <id> disambiguates like --edit
413
- tumwater reset-counters [--role <id>]
576
+ tumwater reset-counters [--role <id>[,<id>...]]
414
577
  Zero lifetime runs/commits/tokens/cost (fresh
415
578
  observation window; today's budget spend is kept — the
416
579
  daily cap cannot be reset past)
417
- tumwater wake [--role <id>] [--in <dur> | --cancel | --list [--json]]
580
+ tumwater wake [--role <id>[,<id>...]] [--in <dur> | --cancel | --list [--json]]
418
581
  Wake sleeping roles — the named roles (or all) run
419
582
  within one poll; --in schedules the wake for later;
420
- --cancel drops pending scheduled wakes;
583
+ --cancel drops pending scheduled wakes (the named roles' share);
421
584
  --list shows every pending scheduled wake, earliest first
422
585
  (--json for scripts)
423
- tumwater reclaim [--dry-run] Reclaim gitignored build outputs from every
586
+ tumwater reclaim [--dry-run [--json]]
587
+ Reclaim gitignored build outputs from every
424
588
  workspace; --dry-run lists each candidate with its idle age
425
- and ignored-path count and cleans nothing
426
- tumwater revert <sha> Undo one merged change on main, committing the inverse
589
+ and ignored-path count and cleans nothing (--json for scripts)
590
+ tumwater revert <sha>|<role> <n>|<role> --last [--dry-run] [--json]
591
+ Undo one merged change on main, committing the inverse
427
592
  under the primary-worktree lock; refuses off the base
428
- branch, on an unknown or unmerged ref, and on a conflict
429
- tumwater abort --role <id> Stop that role's run in progress (work discarded; the role
430
- keeps going)
593
+ branch, on an unknown or unmerged ref, and on a conflict;
594
+ --dry-run names the commit and the paths its inverse touches
595
+ and says whether it applies cleanly on main, writing nothing
596
+ (exit 1 when the revert would conflict or refuse); the run
597
+ forms revert the commit the run merged as, the sha
598
+ 'history <role> <n>' names;
599
+ --json prints the preview or the new head as data
600
+ tumwater abort --role <id>[,<id>...]
601
+ Stop each named role's run in progress (work discarded; the
602
+ role keeps going)
431
603
  tumwater restart Apply a pending self-redeploy now, waiving the restart
432
604
  cooldown (the dashboard's update-alert refresh button; a
433
605
  passing check on main, a successful compile, and in-flight
434
606
  runs finishing still apply)
435
- tumwater pause [--role <id>] [--for <dur>] [--reason <text>]
436
- Stop roles (or just the named role) starting new
437
- runs; --reason states why the whole team is paused (no
607
+ tumwater pause [--role <id>[,<id>...]] [--for <dur>] [--reason <text>]
608
+ Stop roles (or just the named roles) starting new
609
+ runs; --role takes a comma list, pausing each listed
610
+ role; --reason states why the whole team is paused (no
438
611
  per-role reason); --for auto-resumes (capped at 90d)
439
- tumwater resume [--role <id>] Lift a team or per-role pause
612
+ tumwater resume [--role <id>[,<id>...]]
613
+ Lift a team or per-role pause
440
614
  tumwater retire --role <id> Remove a disabled role's workspace, branch, and per-role
441
615
  state (merge ref, pause marker); --force overrides the
442
616
  safety rails; --json prints what was removed;
@@ -450,6 +624,8 @@ Usage:
450
624
  tumwater completion <bash|zsh|fish> Print a shell completion script (eval "$(tumwater completion zsh)" in your rc; fish: tumwater completion fish | source)
451
625
  tumwater completion --roles Print the role ids --role completes (this repo's; the catalog when tumwater.json is unreadable)
452
626
  tumwater completion --config-keys Print the keys config get/set/unset complete (this repo's role keys; the catalog's when tumwater.json is unreadable)
627
+ tumwater completion --config-value <key> Print what config set <key> <value> completes for a discrete-valued key (boolean/backend/model/thinking); nothing for a free-form value
628
+ tumwater completion --models Print the model selectors history --model completes (those the recent runs started on; nothing when the log is unreadable)
453
629
  tumwater help [<command>] Show all commands, or one command's usage
454
630
  tumwater version Print the version
455
631
 
@@ -461,7 +637,7 @@ sleep while there is nothing to do and wake when main moves. Everything is local
461
637
  * suggest. Case-insensitive closest-match over the commands helpStanzas(HELP) names, capped
462
638
  * at two edits — a typo's distance, not a different word's — so only a near miss gets a hint
463
639
  * and the suggestion can never fire as an auto-correction. Deriving the candidates from the
464
- * help text (not a hand-kept list) means a new command is suggestible the tick it gains a
640
+ * help text (not a hand-kept list) means a new command is suggestible the run it gains a
465
641
  * stanza; the distance mechanics are text/suggest.ts's suggestClosest, shared with the config-key
466
642
  * suggestion. */
467
643
  export function suggestCommand(input, help = HELP) {
@@ -491,7 +667,7 @@ export function helpStanzas(help = HELP) {
491
667
  }
492
668
  /** Commands that still dispatch but are not listed in help or completion: alias -> the command
493
669
  * whose topic they print. `run` is the older name of `start`. */
494
- export const HIDDEN_COMMAND_ALIASES = { run: "start", tick: "history" };
670
+ export const HIDDEN_COMMAND_ALIASES = { run: "start", tick: "history" }; // retired-name-ok: legacy name
495
671
  /** The usage text for one command — every stanza whose command matches, then a pointer back to
496
672
  * the full list — or null when nothing in the help names that command. */
497
673
  export function helpTopic(command, help = HELP) {