tumwater 0.1.2 → 0.2.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 (361) hide show
  1. package/README.md +74 -108
  2. package/dist/build-info.json +2 -2
  3. package/dist/src/agent/agent-args.js +24 -0
  4. package/dist/src/agent/agent-backend.js +2 -2
  5. package/dist/src/agent/backend-traits.js +60 -0
  6. package/dist/src/agent/claude/claude-account.js +61 -8
  7. package/dist/src/agent/claude/claude-args.js +12 -15
  8. package/dist/src/agent/claude/claude-backend.js +51 -41
  9. package/dist/src/agent/claude/claude-env.js +7 -3
  10. package/dist/src/agent/claude/claude-stream.js +7 -16
  11. package/dist/src/agent/image-input.js +107 -0
  12. package/dist/src/agent/notes-shim.js +41 -0
  13. package/dist/src/agent/opencode/opencode-args.js +61 -0
  14. package/dist/src/agent/opencode/opencode-backend.js +255 -0
  15. package/dist/src/agent/opencode/opencode-catalog.js +184 -0
  16. package/dist/src/agent/opencode/opencode-config.js +188 -0
  17. package/dist/src/agent/opencode/opencode-env.js +36 -0
  18. package/dist/src/agent/opencode/opencode-session-id.js +37 -0
  19. package/dist/src/agent/opencode/opencode-stream.js +278 -0
  20. package/dist/src/agent/role-notes-write.js +16 -32
  21. package/dist/src/agent/run-agent.js +95 -18
  22. package/dist/src/agent/session-ledger.js +57 -1
  23. package/dist/src/backlog/backlog-archive.js +296 -0
  24. package/dist/src/backlog/backlog-cli.js +573 -0
  25. package/dist/src/backlog/backlog-commit.js +31 -0
  26. package/dist/src/backlog/backlog-eligibility.js +357 -33
  27. package/dist/src/backlog/backlog-md.js +98 -18
  28. package/dist/src/backlog/backlog-render.js +62 -11
  29. package/dist/src/backlog/backlog-structure.js +261 -58
  30. package/dist/src/backlog/backlog-write.js +197 -319
  31. package/dist/src/backlog/backlog.js +113 -16
  32. package/dist/src/backlog/question-answer.js +339 -0
  33. package/dist/src/baseline/main-baseline.js +75 -88
  34. package/dist/src/baseline/main-red.js +38 -30
  35. package/dist/src/brief/brief-edit.js +43 -0
  36. package/dist/src/{brief.js → brief/brief.js} +66 -10
  37. package/dist/src/budget/budget.js +32 -15
  38. package/dist/src/budget/fallback-breaker.js +8 -7
  39. package/dist/src/build/build-check-detect.js +8 -7
  40. package/dist/src/build/build-check-events.js +68 -22
  41. package/dist/src/build/build-check-report.js +22 -23
  42. package/dist/src/build/build-check-scoped.js +51 -62
  43. package/dist/src/build/build-check.js +15 -14
  44. package/dist/src/build/build-info.js +2 -1
  45. package/dist/src/build/build-stage.js +23 -22
  46. package/dist/src/build/dep-install.js +22 -21
  47. package/dist/src/build/host-sleep.js +1 -1
  48. package/dist/src/change/change-data.js +25 -14
  49. package/dist/src/change/change-render.js +11 -10
  50. package/dist/src/cli/brief-command.js +58 -0
  51. package/dist/src/cli/cli-args.js +25 -5
  52. package/dist/src/cli/cli-command-args.js +46 -14
  53. package/dist/src/cli/cli-editor.js +64 -0
  54. package/dist/src/cli/cli-flag-specs.js +54 -16
  55. package/dist/src/cli/cli-marker-commands.js +13 -10
  56. package/dist/src/cli/cli-output.js +9 -0
  57. package/dist/src/cli/cli-query-commands.js +458 -49
  58. package/dist/src/cli/cli-repo-gate.js +1 -1
  59. package/dist/src/cli/cli-run.js +208 -59
  60. package/dist/src/cli/completion.js +207 -0
  61. package/dist/src/cli/config-commands.js +14 -11
  62. package/dist/src/cli/help.js +305 -110
  63. package/dist/src/cli/log-commands.js +127 -21
  64. package/dist/src/cli/notify-command.js +33 -18
  65. package/dist/src/cli/question-commands.js +29 -224
  66. package/dist/src/cli.js +121 -40
  67. package/dist/src/collections.js +66 -16
  68. package/dist/src/concurrency/check-permit.js +16 -17
  69. package/dist/src/concurrency/lock.js +6 -5
  70. package/dist/src/concurrency/provider-lease.js +69 -0
  71. package/dist/src/concurrency/semaphore.js +258 -36
  72. package/dist/src/config/config-aliases.js +106 -0
  73. package/dist/src/config/config-editable-keys.js +3 -3
  74. package/dist/src/config/config-fallbacks.js +379 -0
  75. package/dist/src/config/config-field-checks.js +19 -10
  76. package/dist/src/config/config-keys.js +160 -0
  77. package/dist/src/config/config-live.js +64 -12
  78. package/dist/src/config/config-schema.js +34 -22
  79. package/dist/src/config/config-validation.js +132 -48
  80. package/dist/src/config/config-views.js +119 -337
  81. package/dist/src/config/config-write.js +138 -177
  82. package/dist/src/config/config.js +60 -49
  83. package/dist/src/config/model-selector.js +28 -2
  84. package/dist/src/doctor/doctor-backlog.js +546 -49
  85. package/dist/src/doctor/doctor-checks.js +534 -56
  86. package/dist/src/doctor/doctor-holds.js +193 -53
  87. package/dist/src/doctor/doctor-install.js +30 -0
  88. package/dist/src/doctor/doctor-launch-services.js +2 -2
  89. package/dist/src/doctor/doctor-model-checks.js +549 -157
  90. package/dist/src/doctor/doctor-notify.js +27 -0
  91. package/dist/src/doctor/doctor-orphans.js +10 -9
  92. package/dist/src/doctor/doctor-render.js +36 -9
  93. package/dist/src/doctor/doctor.js +80 -22
  94. package/dist/src/doctor/image-probe.js +244 -0
  95. package/dist/src/doctor/probe.js +64 -0
  96. package/dist/src/events/event-format.js +226 -102
  97. package/dist/src/events/event-labels.js +116 -0
  98. package/dist/src/events/event-legacy.js +140 -0
  99. package/dist/src/events/event-read.js +58 -22
  100. package/dist/src/events/event-window.js +27 -7
  101. package/dist/src/events/events.js +18 -14
  102. package/dist/src/events/notify.js +137 -38
  103. package/dist/src/failure/failure-cluster.js +12 -9
  104. package/dist/src/failure/failure-data.js +96 -48
  105. package/dist/src/failure/failure-render.js +69 -58
  106. package/dist/src/failure/failure-state-change.js +33 -26
  107. package/dist/src/failure/time-spend.js +79 -59
  108. package/dist/src/files/file-queue.js +16 -4
  109. package/dist/src/files/files.js +18 -6
  110. package/dist/src/files/json-object.js +18 -3
  111. package/dist/src/files/tail.js +1 -1
  112. package/dist/src/gates/bootstrap-gates.js +5 -4
  113. package/dist/src/gates/budget-gates.js +250 -34
  114. package/dist/src/gates/disk-gate.js +18 -18
  115. package/dist/src/gates/gate-polls.js +117 -69
  116. package/dist/src/gates/maintenance-quota.js +29 -29
  117. package/dist/src/gates/pause-gates.js +11 -11
  118. package/dist/src/gates/readiness.js +2 -1
  119. package/dist/src/gates/role-cap-gates.js +16 -21
  120. package/dist/src/gates/startup-gate.js +75 -31
  121. package/dist/src/gates/streak-gate.js +18 -16
  122. package/dist/src/git/commit-message.js +12 -5
  123. package/dist/src/git/git-diff.js +16 -16
  124. package/dist/src/git/git-run.js +8 -8
  125. package/dist/src/git/git.js +86 -55
  126. package/dist/src/git/slots-state.js +14 -5
  127. package/dist/src/git/worktree-pool.js +25 -18
  128. package/dist/src/git/worktree-use.js +15 -14
  129. package/dist/src/git/worktree.js +18 -18
  130. package/dist/src/gui/gui-args.js +10 -14
  131. package/dist/src/gui/gui-backlog-commands.js +273 -0
  132. package/dist/src/gui/gui-command.js +1 -1
  133. package/dist/src/gui/gui-config-commands.js +440 -0
  134. package/dist/src/gui/gui-endpoint-commands.js +16 -669
  135. package/dist/src/gui/gui-endpoint-common.js +49 -0
  136. package/dist/src/gui/gui-endpoints.js +116 -56
  137. package/dist/src/gui/gui-operator-commands.js +145 -0
  138. package/dist/src/gui/gui-prompt-commands.js +234 -0
  139. package/dist/src/gui/gui-server.js +28 -8
  140. package/dist/src/gui/gui-team-commands.js +164 -0
  141. package/dist/src/gui/http-body.js +17 -1
  142. package/dist/src/history/history-data.js +194 -98
  143. package/dist/src/history/history-render.js +76 -0
  144. package/dist/src/history/history.js +37 -58
  145. package/dist/src/inbox/inbox-attachments.js +75 -14
  146. package/dist/src/inbox/inbox-cancel.js +7 -5
  147. package/dist/src/inbox/inbox-edit.js +1 -1
  148. package/dist/src/inbox/inbox-submit.js +44 -4
  149. package/dist/src/inbox/inbox-top.js +83 -0
  150. package/dist/src/inbox/inbox.js +8 -2
  151. package/dist/src/inbox/pending-prompt.js +1 -1
  152. package/dist/src/inbox/prompt-commands.js +170 -80
  153. package/dist/src/init/init-templates.js +16 -14
  154. package/dist/src/init/init.js +12 -11
  155. package/dist/src/loop/leftover.js +28 -27
  156. package/dist/src/loop/loop-fallback.js +2 -2
  157. package/dist/src/loop/loop-pi.js +106 -52
  158. package/dist/src/loop/loop-recovery.js +15 -15
  159. package/dist/src/loop/loop-state.js +139 -13
  160. package/dist/src/loop/loop-tick.js +194 -86
  161. package/dist/src/loop/loop.js +72 -36
  162. package/dist/src/loop/model-fallback.js +3 -2
  163. package/dist/src/loop/revision.js +16 -7
  164. package/dist/src/merge/backlog-conflicts.js +155 -0
  165. package/dist/src/{landing/landing-batch.js → merge/merge-batch.js} +90 -89
  166. package/dist/src/{landing/landing-check-failures.js → merge/merge-check-failures.js} +87 -41
  167. package/dist/src/{landing/landing-core.js → merge/merge-core.js} +119 -95
  168. package/dist/src/{landing/landing-diff.js → merge/merge-diff.js} +1 -1
  169. package/dist/src/merge/merge-drain.js +212 -0
  170. package/dist/src/{landing/landing-git.js → merge/merge-git.js} +94 -21
  171. package/dist/src/merge/merge-pipeline.js +99 -0
  172. package/dist/src/{landing/landing-questions.js → merge/merge-questions.js} +9 -6
  173. package/dist/src/merge/merge-queue-render.js +75 -0
  174. package/dist/src/{landing/landing-queue.js → merge/merge-queue.js} +95 -36
  175. package/dist/src/merge/merge-slot.js +340 -0
  176. package/dist/src/{landing/landing-stack.js → merge/merge-stack.js} +66 -62
  177. package/dist/src/{landing/landing-merge.js → merge/merge-to-main.js} +72 -62
  178. package/dist/src/merge/merge-verify.js +212 -0
  179. package/dist/src/notes-cli.js +97 -0
  180. package/dist/src/operator/operator-commands.js +154 -47
  181. package/dist/src/operator/operator-intent.js +87 -49
  182. package/dist/src/operator/operator-requests.js +52 -52
  183. package/dist/src/operator/retire.js +62 -27
  184. package/dist/src/operator/revert.js +71 -0
  185. package/dist/src/orchestrator/orchestrator-launch.js +74 -14
  186. package/dist/src/orchestrator/orchestrator-scheduling.js +129 -44
  187. package/dist/src/orchestrator/orchestrator.js +158 -100
  188. package/dist/src/orchestrator/retention.js +29 -12
  189. package/dist/src/orchestrator/startup-migration-steps.js +51 -0
  190. package/dist/src/orchestrator/startup-migrations.js +40 -0
  191. package/dist/src/paths.js +128 -37
  192. package/dist/src/pi/pi-args.js +26 -3
  193. package/dist/src/pi/pi-backend.js +15 -23
  194. package/dist/src/pi/pi-bin.js +18 -12
  195. package/dist/src/pi/pi-event-line.js +17 -1
  196. package/dist/src/pi/pi-failure.js +87 -0
  197. package/dist/src/pi/pi-models.js +126 -38
  198. package/dist/src/pi/pi-run-result.js +1 -1
  199. package/dist/src/pi/pi-settings.js +86 -0
  200. package/dist/src/pi/pi-stream.js +131 -107
  201. package/dist/src/pi/pi-watchdogs.js +47 -43
  202. package/dist/src/pi-extension/bounded-output.js +20 -5
  203. package/dist/src/pi-extension/context-budget.js +3 -1
  204. package/dist/src/pi-extension/context-shake.js +54 -21
  205. package/dist/src/pi-extension/context-window.js +37 -0
  206. package/dist/src/pi-extension/full-output.js +2 -2
  207. package/dist/src/pi-extension/strip-thinking.js +80 -0
  208. package/dist/src/pi-extension/trim-system-prompt.js +38 -0
  209. package/dist/src/process/launch-services.js +11 -10
  210. package/dist/src/process/process-table.js +1 -1
  211. package/dist/src/process/process.js +7 -7
  212. package/dist/src/process/run-marker.js +29 -6
  213. package/dist/src/process/supervisor.js +47 -25
  214. package/dist/src/prompt/dialect.js +30 -10
  215. package/dist/src/prompt/gate-prompts.js +170 -67
  216. package/dist/src/prompt/principles.js +1 -0
  217. package/dist/src/prompt/prompt-followup.js +35 -20
  218. package/dist/src/prompt/prompt.js +249 -91
  219. package/dist/src/redeploy/redeploy-policy.js +10 -10
  220. package/dist/src/redeploy/redeploy.js +6 -4
  221. package/dist/src/redeploy/redeployer.js +63 -55
  222. package/dist/src/redeploy/self-reload.js +1 -1
  223. package/dist/src/report/report-data.js +264 -255
  224. package/dist/src/report/report-fold.js +353 -0
  225. package/dist/src/report/report-render.js +270 -33
  226. package/dist/src/request-timeouts.js +1 -1
  227. package/dist/src/review/known-flakes.js +34 -14
  228. package/dist/src/review/protected-edits.js +33 -0
  229. package/dist/src/review/review-followup.js +16 -4
  230. package/dist/src/review/review-precheck.js +14 -13
  231. package/dist/src/review/review-verdict.js +14 -0
  232. package/dist/src/review/review.js +81 -39
  233. package/dist/src/review/secret-leaks.js +127 -0
  234. package/dist/src/review/suite-rerun.js +4 -3
  235. package/dist/src/roles/legacy-role-ids.js +21 -0
  236. package/dist/src/roles/legacy-role-migration.js +62 -0
  237. package/dist/src/roles/loop-ids.js +19 -2
  238. package/dist/src/roles/role-catalog.js +125 -135
  239. package/dist/src/roles/role-guidance.js +64 -31
  240. package/dist/src/roles/role-labels.js +10 -0
  241. package/dist/src/roles/role-render.js +194 -18
  242. package/dist/src/roles/role-view.js +216 -17
  243. package/dist/src/roles/roles.js +18 -15
  244. package/dist/src/scheduling/backoff.js +29 -19
  245. package/dist/src/scheduling/claims.js +25 -9
  246. package/dist/src/scheduling/once-round.js +11 -11
  247. package/dist/src/scheduling/quiet-hours.js +25 -32
  248. package/dist/src/scheduling/scheduling.js +43 -24
  249. package/dist/src/scheduling/{work-landed-cache.js → work-merged-cache.js} +14 -14
  250. package/dist/src/status/status-budget.js +115 -0
  251. package/dist/src/status/status-data.js +77 -184
  252. package/dist/src/status/status-inbox.js +47 -0
  253. package/dist/src/status/status-install.js +27 -0
  254. package/dist/src/status/status-polls.js +68 -33
  255. package/dist/src/status/status-roles.js +105 -0
  256. package/dist/src/{fleet → team}/error-storm.js +10 -10
  257. package/dist/src/{fleet → team}/failure-spread.js +8 -8
  258. package/dist/src/{fleet → team}/orchestrator-info.js +86 -18
  259. package/dist/src/{fleet → team}/reclaim.js +5 -4
  260. package/dist/src/{fleet/fleet-hold.js → team/team-hold.js} +55 -21
  261. package/dist/src/{fleet/fleet-polls.js → team/team-polls.js} +116 -65
  262. package/dist/src/{fleet/fleet-state.js → team/team-state.js} +62 -37
  263. package/dist/src/text/datetime.js +42 -2
  264. package/dist/src/text/format.js +10 -1
  265. package/dist/src/text/markdown.js +1 -1
  266. package/dist/src/text/phrases.js +35 -34
  267. package/dist/src/text/suggest.js +3 -2
  268. package/dist/src/text/text.js +2 -2
  269. package/dist/src/tick/qa-coverage.js +2 -1
  270. package/dist/src/tick/stage-check.js +147 -26
  271. package/dist/src/tick/telemetry-digest.js +10 -9
  272. package/dist/src/tick/tick-apply.js +101 -72
  273. package/dist/src/tick/tick-detail-data.js +32 -18
  274. package/dist/src/tick/tick-detail.js +62 -21
  275. package/dist/src/tick/tick-finalize.js +29 -22
  276. package/dist/src/tick/tick-outcome.js +2 -1
  277. package/dist/src/tick/tick-prompt.js +94 -26
  278. package/dist/src/tick/tick-resume.js +29 -13
  279. package/dist/src/tick/tick-stage.js +91 -47
  280. package/dist/src/tick/tick-timing.js +60 -59
  281. package/dist/src/tick/tick-usage.js +53 -23
  282. package/dist/src/tick/tick-verdict.js +76 -10
  283. package/dist/src/ui/badges.js +118 -67
  284. package/dist/src/ui/gui/gui-client-boot.js +209 -30
  285. package/dist/src/ui/gui/gui-client-composer.js +102 -23
  286. package/dist/src/ui/gui/gui-client-drawer.js +330 -75
  287. package/dist/src/ui/gui/gui-client-history.js +96 -38
  288. package/dist/src/ui/gui/gui-client-labels.js +24 -0
  289. package/dist/src/ui/gui/gui-client-loops.js +94 -52
  290. package/dist/src/ui/gui/gui-client-markdown.js +1 -0
  291. package/dist/src/ui/gui/gui-client-model.js +63 -43
  292. package/dist/src/ui/gui/gui-client-operator.js +129 -39
  293. package/dist/src/ui/gui/gui-client-pending.js +36 -32
  294. package/dist/src/ui/gui/gui-client-report.js +339 -46
  295. package/dist/src/ui/gui/gui-client-settings.js +148 -14
  296. package/dist/src/ui/gui/gui-client-sound.js +2 -1
  297. package/dist/src/ui/gui/{gui-client-fleet.js → gui-client-team.js} +196 -72
  298. package/dist/src/ui/gui/gui-client.js +26 -20
  299. package/dist/src/ui/gui/gui-page.js +19 -19
  300. package/dist/src/ui/gui/gui-styles.js +12 -4
  301. package/dist/src/ui/progress-data.js +5 -3
  302. package/dist/src/ui/status-model.js +184 -122
  303. package/dist/src/ui/status-payload.js +119 -32
  304. package/dist/src/ui/status-render.js +122 -52
  305. package/dist/src/ui/team-alerts.js +341 -0
  306. package/dist/src/ui/tick-progress-model.js +14 -14
  307. package/dist/src/ui/tone.js +11 -8
  308. package/dist/src/ui/transcript-tail.js +1 -0
  309. package/dist/src/ui/transcript.js +23 -16
  310. package/dist/src/ui/tui/tui-app.js +1 -0
  311. package/dist/src/ui/tui/tui-backlog.js +85 -11
  312. package/dist/src/ui/tui/tui-editor-answer.js +97 -0
  313. package/dist/src/ui/tui/tui-editor-attach.js +107 -0
  314. package/dist/src/ui/tui/tui-editor-brief.js +107 -0
  315. package/dist/src/ui/tui/tui-editor-budget.js +155 -0
  316. package/dist/src/ui/tui/tui-editor-ctx.js +1 -0
  317. package/dist/src/ui/tui/tui-editor-entry.js +230 -0
  318. package/dist/src/ui/tui/tui-editor-interval.js +122 -0
  319. package/dist/src/ui/tui/tui-editor-notes.js +114 -0
  320. package/dist/src/ui/tui/tui-editor-pause.js +266 -0
  321. package/dist/src/ui/tui/tui-editor-prompt.js +95 -0
  322. package/dist/src/ui/tui/tui-editor-queued.js +98 -0
  323. package/dist/src/ui/tui/tui-editor-quiet.js +106 -0
  324. package/dist/src/ui/tui/tui-editor-retire.js +83 -0
  325. package/dist/src/ui/tui/tui-editor-search.js +73 -0
  326. package/dist/src/ui/tui/tui-editor-session.js +97 -0
  327. package/dist/src/ui/tui/tui-editors.js +152 -0
  328. package/dist/src/ui/tui/tui-frame.js +67 -55
  329. package/dist/src/ui/tui/tui-history.js +12 -7
  330. package/dist/src/ui/tui/tui-input.js +49 -44
  331. package/dist/src/ui/tui/tui-keymap.js +1 -0
  332. package/dist/src/ui/tui/tui-keys.js +91 -1704
  333. package/dist/src/ui/tui/tui-pane-activity.js +99 -0
  334. package/dist/src/ui/tui/tui-pane-backlog.js +224 -0
  335. package/dist/src/ui/tui/tui-pane-brief.js +30 -0
  336. package/dist/src/ui/tui/tui-pane-ctx.js +11 -0
  337. package/dist/src/ui/tui/tui-pane-health.js +124 -0
  338. package/dist/src/ui/tui/tui-pane-history.js +316 -0
  339. package/dist/src/ui/tui/tui-pane-pending.js +74 -0
  340. package/dist/src/ui/tui/tui-pane-queued.js +143 -0
  341. package/dist/src/ui/tui/tui-pane-report.js +122 -0
  342. package/dist/src/ui/tui/tui-pane-session.js +101 -0
  343. package/dist/src/ui/tui/tui-pane-transcript.js +150 -0
  344. package/dist/src/ui/tui/tui-pane.js +66 -28
  345. package/dist/src/ui/tui/tui-panes.js +294 -0
  346. package/dist/src/ui/tui/tui.js +45 -25
  347. package/dist/src/verdict/fix-claim.js +141 -38
  348. package/dist/src/verdict/no-change.js +19 -0
  349. package/dist/src/verdict/refusal.js +92 -8
  350. package/dist/src/verdict/reply-contract.js +17 -5
  351. package/dist/src/version.js +3 -2
  352. package/package.json +4 -2
  353. package/dist/src/agent/mcp/role-notes-server.js +0 -160
  354. package/dist/src/landing/backlog-conflicts.js +0 -116
  355. package/dist/src/landing/landing-drain.js +0 -204
  356. package/dist/src/landing/landing-pipeline.js +0 -96
  357. package/dist/src/landing/landing-queue-render.js +0 -31
  358. package/dist/src/landing/landing-slot.js +0 -246
  359. package/dist/src/landing/landing-vetting.js +0 -196
  360. package/dist/src/pi-extension/role-notes.js +0 -40
  361. package/dist/src/ui/fleet-alerts.js +0 -174
@@ -4,44 +4,54 @@
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
- export const HELP = `tumwater — autonomous development harness built on pi
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
10
+ export const HELP = `tumwater — an autonomous development team, built on pi
8
11
 
9
12
  Usage:
10
13
  tumwater init <prompt...> Initialize this repo (--file <prompt.md>, --adopt: brief in
11
14
  TUMWATER.md, --branch <name> seeds a new repo only,
12
15
  --template <id> seeds a starter brief+backlog (--list-templates
13
16
  lists them), --dry-run: write nothing)
14
- tumwater run [--branch <name>] [--once] [--for <duration>] [--role <id>] [--gui]
15
- Run all enabled loops (headless; Ctrl+C stops);
16
- --once runs one full round of ticks, drains the
17
- landings it produced, and exits (for cron/CI);
18
- --once --role <id> scopes that round to one loop;
19
- --for <duration> runs for that window then drains
17
+ tumwater start [--branch <name>] [--once] [--for <duration>] [--role <id>] [--gui] [--tui]
18
+ Start the team: every enabled role runs in turn (headless;
19
+ Ctrl+C finishes current work, then stops);
20
+ --once does one round of runs, finishes the
21
+ merges it produced, and exits (for cron/CI);
22
+ exits 3 when a run ended in error, review failed,
23
+ a merge conflicted or was blocked, or main's check is failing;
24
+ --once --role <id> limits that round to one role;
25
+ --for <duration> runs for that window then finishes current work, prints a per-role summary
26
+ (one window across self-redeploys),
20
27
  and exits like Ctrl+C would (for an overnight
21
28
  trial, a demo, a CI step);
22
29
  --gui also serves the browser dashboard at
23
30
  http://127.0.0.1:7180 (the \`tumwater gui\`
24
- defaults — see that command for --port and --token)
25
- tumwater tui Dashboard + prompt input (observes a running \`tumwater run\`)
31
+ defaults — see that command for --port and --token);
32
+ --tui also hosts the TUI in this terminal
33
+ (the \`tumwater tui\` view — quitting it stops the
34
+ team like Ctrl+C)
35
+ tumwater tui Dashboard + inbox input (watches a running \`tumwater start\`)
26
36
  tumwater gui [--port N] [--all-interfaces] [--token <secret>]
27
37
  Same dashboard in the browser (default port 7180,
28
38
  localhost only; --all-interfaces serves the whole
29
39
  network — without --token there is no auth, anyone
30
- reaching it can prompt the director)
40
+ reaching it can message the director)
31
41
  tumwater status [--json] One-shot status table (--json prints machine-readable
32
- fleet state — the GUI's /api/status payload minus the
42
+ team state — the GUI's /api/status payload minus the
33
43
  serving process's serverBuildSha)
34
44
  tumwater report [--days N] [--role <id>] [--json]
35
- Markdown usage report — tokens/ticks/commits per day (default
36
- 14 days); totals also include landing runs (reviewer + conflict
37
- resolution); --role <id> scopes the report to one loop's ticks,
38
- tokens, cost, and commits (landing runs and backlog tallies
45
+ Markdown usage report — tokens/runs/commits per day (default
46
+ 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
39
49
  omitted); --json prints machine-readable usage data — the
40
50
  collector's own payload, not the Markdown render
41
51
  tumwater report --failures [--days N] [--since <duration>] [--role <id>] [--json]
42
- Markdown failure digest — tick outcomes, deltas,
43
- clustered errors, and fleet state changes (default
44
- 14 days); --role <id> scopes the digest to one loop's
52
+ Markdown failure digest — run outcomes, deltas,
53
+ clustered errors, and team state changes (default
54
+ 14 days); --role <id> scopes the digest to one role's
45
55
  rows; --since windows the digest over a trailing
46
56
  span (capped at 7d)
47
57
  tumwater report --failures --since <duration> [--role <id>] [--json]
@@ -49,16 +59,21 @@ Usage:
49
59
  against the equal-length window before it
50
60
  tumwater report --since <duration> [--role <id>] [--json]
51
61
  Totals over a trailing window (capped at 7d) —
52
- tokens/ticks/commits/cost since a point in time; totals
53
- also include landing runs (reviewer + conflict
54
- resolution); --role <id> scopes the totals to one loop
55
- (landing runs and backlog tallies omitted); not
62
+ tokens/runs/commits/cost since a point in time; totals
63
+ also include merge runs (reviewer + conflict
64
+ resolution); --role <id> scopes the totals to one role
65
+ (merge runs and backlog tallies omitted); not
56
66
  combinable with --days
57
- tumwater doctor [--json] Pre-flight check: node, git, repo, config, fallback
58
- model, pi, locks, build, orphans, mach ports
67
+ tumwater doctor [--json] [--reprobe] [--problems]
68
+ Pre-flight check: node, git, repo, config, fallback
69
+ model, pi, locks, update, orphans, macOS port leak
59
70
  (read-only; exit 0/1; --json prints the report object —
60
71
  header, the checks array with level, name, and detail,
61
- and verdict)
72
+ and verdict; probes image-input models — --reprobe
73
+ re-probes every one, bypassing the 7-day cache; --problems prints only the warn
74
+ and fail rows (and how many ok rows it hid), the same
75
+ verdict and exit code; with --json the checks array holds
76
+ only those rows)
62
77
  tumwater config [get <key> | set <key> <value> | unset <key>]
63
78
  Show the effective config (defaults + tumwater.json) as
64
79
  JSON; get one key's resolved value as JSON; set one
@@ -74,72 +89,107 @@ Usage:
74
89
  roles still merges the built-in catalog per entry, so
75
90
  disable a role with roles.<id>.enabled false, not by
76
91
  omitting it
77
- tumwater logs [-f/--follow] [-n N] [--since <duration>] [--grep <text>] [--json]
78
- Show (and follow) harness events; --since shows the
92
+ tumwater logs [-f/--follow] [-n N] [--since <duration>] [--grep <text>] [--type <event type>] [--count] [--json]
93
+ Show (and follow) tumwater events; --since shows the
79
94
  events of the past window (capped at 7d); --grep shows
80
95
  only events whose type or rendered line matches,
81
96
  case-insensitively (-n bounds the scanned window, not
82
- the printed rows); --json prints each event as one
97
+ the printed rows); --type shows only events of that
98
+ exact event type, and an older event name matches its current one (it
99
+ composes with --since); --count
100
+ prints one \`N \u00d7 <type>\` line per present event type
101
+ (most-frequent first) over the selected window instead
102
+ of the rows; --json
103
+ prints each event as one
83
104
  JSON object per line (NDJSON) — the raw event objects
84
105
  as stored in the log, instead of the rendered text
106
+ (with --count, one JSON object mapping type \u2192 count)
85
107
  tumwater logs --role <id> [-f/--follow] [-n N] [--prompt]
86
- Show (and follow) that loop's pi transcript
108
+ Show (and follow) that role's pi transcript
87
109
  (--prompt also shows each run's exact prompt text)
88
110
  tumwater notify --test Run the configured notify hook once with a synthetic event
89
111
  so the command can be checked before a real page
90
112
  tumwater history [--role <id>] [-n N] [--since <duration>] [--grep <text>]
91
- [--result <changes|none|problems>] [--json]
92
- One row per completed tick, newest first — time, loop,
93
- tick number, result, duration, tokens/cost, and the
113
+ [--result <merged|none|refused|problems>] [--summary] [--json]
114
+ One row per completed run, newest first — time, role,
115
+ run number, result, duration, tokens/cost, and the
94
116
  summary (or error), each row one line; --since <duration>
95
- shows the window's ticks instead of the last N (capped at
117
+ shows the window's runs instead of the last N (capped at
96
118
  7d, like logs --since); --grep <text> keeps only rows whose
97
119
  line matches, case-insensitively (like logs --grep);
98
- --result <class> narrows to one outcome class — changes
99
- (changed/queued), none (no_change/skipped/user_aborted), or
120
+ --result <class> narrows to one outcome class — merged
121
+ (merged or waiting to merge), none (no_change/skipped/user_aborted),
122
+ refused (a run that deliberately declined its entry), or
100
123
  problems (everything else) — composed with --role, --since,
101
124
  -n, and --grep; --json prints the rows as
102
125
  machine-readable history data — ts, tokens, and costUsd
103
- kept raw, the GUI's /api/history payload
104
- tumwater tick <role> [<n>] [--last] [--json]
105
- One completed tick's full event trail — a summary header
106
- (result or in-flight, duration, tokens/cost, the pinned
107
- commit sha) then every event of that tick's block in time
108
- order; a still-running tick shows its events so far, marked
109
- in flight; --last shows the newest completed tick's trail
110
- instead of numbering one; --json prints the collector's
111
- payload as machine-readable data
112
- tumwater diff [--json] One line per loop holding pending work — the ahead-of-main
126
+ kept raw, the GUI's /api/history payload; --summary prints one line per role
127
+ counting its runs by outcome class and its run time, with the time of its newest change (and a total line)
128
+ instead of the rows; with --json, ${SUMMARY_JSON_KEYS}
129
+ tumwater history <role> [<n>] [--last] [--stat] [--json]
130
+ One run's full event trail — a summary header (result, or
131
+ in flight, with duration, tokens and cost, and the commit)
132
+ then every event of that run in time order; a run still in
133
+ flight shows its events so far; a run waiting to merge
134
+ shows its merge verdict once the merge finishes; --last
135
+ 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
113
139
  commit count and uncommitted-file count, no patch; roles
114
140
  with no worktree or nothing pending are skipped, and a
115
141
  missing baseline prints the per-role view's degradation
116
142
  line; --json prints the {mainBranch, roles} roster
117
- tumwater diff --role <id> [--json]
118
- Show the change that loop holds: its branch's unlanded
143
+ tumwater diff --role <id> [--stat] [--json]
144
+ Show the change that role holds: its branch's unmerged
119
145
  commits (one line each, plus the ahead-of-main patch) and
120
146
  its worktree's uncommitted edits (the file list, plus the
121
- patch — staged and unstaged alike); a loop with no worktree
122
- yet prints \`no worktree for <id>\`; --json prints the
147
+ patch — staged and unstaged alike); a role with no workspace
148
+ yet prints \`no worktree for <id>\`; --stat prints each patch's per-file
149
+ \`git diff --stat\` summary instead; --json prints the
123
150
  collector's payload as machine-readable data
124
- tumwater queue [--json] List the durable land queue in execution order (oldest
125
- first): one line per waiting landing — position, loop, tick
126
- number, short pinned sha, age, and summary; an empty queue
127
- prints \`land queue empty\`, and any torn/foreign queue file
151
+ tumwater queue [--json] List the durable merge queue in execution order (oldest
152
+ first): one line per waiting merge — position, role, run
153
+ number, short pinned sha, age, and summary — plus a bracketed
154
+ \`[merging 2m · reviewing]\` / \`[approved, waiting to merge]\`
155
+ label while a running team works on it; an empty queue
156
+ prints \`merge queue empty\`, and any torn/foreign queue file
128
157
  the reader skipped is counted on a trailing line; --json
129
158
  prints the collector's own {entries, unreadable} document
130
159
  (raw sha and numeric enqueuedAt, not the render's age)
131
- tumwater backlog [--json] Show planned features, open bugs, and open questions (the
160
+ tumwater backlog [--ready] [--json]
161
+ Show planned features, open bugs, and open questions (the
132
162
  dashboards' backlog view); --json prints machine-readable
133
163
  backlog data — the three entry arrays as {title, body}, the
134
- same data the Markdown view renders
164
+ same data the Markdown view renders; a series with two or more
165
+ blocked parts prints as one heading (--json still lists every
166
+ entry); an entry a role is
167
+ working on carries \`[working on it: feature #2]\` (--json:
168
+ an \`inProgress\` key parallel to the arrays); --ready keeps only the
169
+ 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
172
+ BUGS.md ## Fixed to the top of PLANS-DONE.md and BUGS-FIXED.md
173
+ and commit them on the base branch, waiting for a merge in
174
+ progress; a starting team does the same, and a role's own
175
+ finished entry moves when its change commits
135
176
  tumwater bug "<symptom>" [--json]
136
- File a bug into BUGS.md ## Open as the operator (stamped
137
- with today's date) and wake the bugfix loop; --json prints
177
+ File a bug into BUGS.md ## Open as you (stamped
178
+ with today's date) and wake the bugfix role; --json prints
138
179
  the {file, title, stamp} payload as data
139
180
  tumwater bug --file <path> [--json]
140
181
  File a bug from a markdown file ("-" reads stdin): the first
141
182
  non-blank line is the symptom, the rest is the body kept
142
- line for line; wakes the bugfix loop
183
+ line for line; wakes the bugfix role
184
+ 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}
189
+ tumwater bug --top <n> [--json]
190
+ Move the Nth entry (as \`tumwater bug --list\` lists it) to
191
+ the head of BUGS.md ## Open, so bugfix claims it next; commit
192
+ it on main; no wake; --json prints {file, title}
143
193
  tumwater bug --cancel <n> [--json]
144
194
  Remove the Nth entry in BUGS.md ## Open (as \`tumwater
145
195
  bug --list\` lists it); no wake; --json prints {file, title}
@@ -152,19 +202,44 @@ Usage:
152
202
  stdin): the first non-blank line is the title (symptom), the rest
153
203
  the body kept line for line; position and original stamp
154
204
  kept; no wake; --json prints {file, title}
205
+ tumwater bug --edit <n> [--json]
206
+ With neither text nor --file, open the Nth entry as --show
207
+ prints it in $VISUAL or $EDITOR and write it back on save;
208
+ an unchanged buffer writes nothing
155
209
  tumwater bug --list [--json] List the entries in BUGS.md ## Open, numbered (the read
156
210
  half of --edit/--cancel), each with its eligibility mark;
157
211
  --json prints the {entries} array — position, title, body,
158
- hold — as data
212
+ hold, inProgress — as data; \`[working on it: …]\` marks an
213
+ entry a role is working on
214
+ tumwater bug --list --done [-n <count>] [--grep <text>] [--json]
215
+ List the newest entries, numbered, in BUGS.md ## Fixed, newest first
216
+ (default 10); --json prints {entries, older}, each entry
217
+ with position, title, body, completedOn
218
+ --grep keeps the entries whose heading or body contains the
219
+ text, case-insensitively, numbered as without it
220
+ tumwater bug --show <n> [--json] Print the Nth entry as the markdown file --edit <n> --file
221
+ reads (title, blank line, body with indentation kept);
222
+ --json prints {position, title, body, hold}
223
+ tumwater bug --show <n> --done [--json]
224
+ Print the Nth entry of \`bug --list --done\` (newest first) in
225
+ full; --json prints {position, title, body, completedOn}
159
226
  tumwater plan "<title>" [body...] [--json]
160
- File a plan request into PLANS.md ## Planned as the operator
161
- (stamped with today's date; the feature loop fleshes the stub
162
- out on pickup) and wake the feature loop; --json prints the
227
+ File a plan request into PLANS.md ## Planned as you
228
+ (stamped with today's date; the feature role fleshes the stub
229
+ out on pickup) and wake the feature role; --json prints the
163
230
  {file, title, stamp} payload as data
164
231
  tumwater plan --file <path> [--json]
165
232
  File a plan request from a markdown file ("-" reads stdin):
166
233
  the first non-blank line is the title, the rest is the body
167
- kept line for line; wakes the feature loop
234
+ kept line for line; wakes the feature role
235
+ tumwater plan --release <n> [--json]
236
+ Lift the Refused note from the Nth entry in PLANS.md ## Planned
237
+ (as \`tumwater plan --list\` lists it), commit it on main,
238
+ and wake the feature role; --json prints {file, title}
239
+ tumwater plan --top <n> [--json]
240
+ Move the Nth entry (as \`tumwater plan --list\` lists it) to
241
+ the head of PLANS.md ## Planned, so feature claims it next;
242
+ commit it on main; no wake; --json prints {file, title}
168
243
  tumwater plan --cancel <n> [--json]
169
244
  Remove the Nth entry in PLANS.md ## Planned (as \`tumwater
170
245
  plan --list\` lists it); no wake; --json prints {file, title}
@@ -177,95 +252,210 @@ Usage:
177
252
  stdin): the first non-blank line is the title, the rest
178
253
  the body kept line for line; position and original stamp
179
254
  kept; no wake; --json prints {file, title}
255
+ tumwater plan --edit <n> [--json]
256
+ With neither text nor --file, open the Nth entry as --show
257
+ prints it in $VISUAL or $EDITOR and write it back on save;
258
+ an unchanged buffer writes nothing
180
259
  tumwater plan --list [--json] List the entries in PLANS.md ## Planned, numbered (the
181
260
  read half of --edit/--cancel), each with its eligibility
182
261
  mark; --json prints the {entries} array — position, title,
183
- body, hold — as data
262
+ body, hold, inProgress — as data; \`[working on it: …]\`
263
+ marks an entry a role is working on; a series' blocked
264
+ parts show as one line naming their positions
265
+ tumwater plan --list --done [-n <count>] [--grep <text>] [--json]
266
+ List the newest entries, numbered, in PLANS.md ## Done, newest first
267
+ (default 10); --json prints {entries, older}, each entry
268
+ with position, title, body, completedOn
269
+ --grep keeps the entries whose heading or body contains the
270
+ text, case-insensitively, numbered as without it
271
+ tumwater plan --show <n> [--json]
272
+ Print the Nth entry as the markdown file --edit <n> --file
273
+ reads (title, blank line, body with indentation kept);
274
+ --json prints {position, title, body, hold}
275
+ tumwater plan --show <n> --done [--json]
276
+ Print the Nth entry of \`plan --list --done\` (newest first) in
277
+ full; --json prints {position, title, body, completedOn}
184
278
  tumwater questions [--json] List open questions numbered (the read half of the
185
279
  question outbox); --json prints the {questions}
186
280
  array — position, title, body — as data
281
+ tumwater questions --answered [-n <count>] [--grep <text>] [--json]
282
+ List the newest answered questions, numbered, newest first
283
+ (default 10), each with its answer line; --json prints {questions,
284
+ older}, each with position, title, body, answeredOn
285
+ --grep keeps the questions whose heading or body contains the
286
+ text, case-insensitively, numbered as without it
287
+ tumwater questions --show <n> --answered [--json]
288
+ Print the Nth entry of "questions --answered" (newest
289
+ first) in full, context and recorded answer; --json
290
+ prints {position, title, body, answeredOn}
291
+ tumwater questions --show <n> [--json]
292
+ Print the Nth open question in full (heading, blank line,
293
+ body), the numbering "questions" lists and "questions
294
+ answer <n>" takes; --json prints {position, title, body,
295
+ since, ageDays}
187
296
  tumwater questions answer [--json] <n> "<decision>"
188
297
  Answer the Nth open question: stamps today's date on the
189
298
  entry and moves it to ## Answered with your decision.
190
299
  --json prints the result as data and must precede <n>:
191
300
  a --json after the decision is recorded as part of it;
192
- loops read the answer at their next tick
301
+ roles read the answer at their next run
193
302
  tumwater questions answer [--json] <n> --file <path>
194
303
  Read the decision from the file (- for stdin) with its
195
304
  lines kept; a ## or ### heading line outside a code fence,
196
305
  or an unclosed fence, is refused
197
- tumwater role <id> [--json] Show one loop's standing prompt and resolved settings — its
198
- find text, the roles.<id>.instructions override, the resolved
306
+ tumwater questions answer [--json] <n>
307
+ With no decision, open the question in $VISUAL/$EDITOR;
308
+ only the text above the marker line is recorded
309
+ tumwater brief [--json] Show the project's brief and the file that holds it
310
+ tumwater brief --file <path> [--json]
311
+ Replace the brief with the file's text (- for
312
+ stdin), refused when empty, over the length cap, or
313
+ containing a tumwater:prompt marker; commits that one
314
+ file on main; no wake
315
+ tumwater brief --edit [--json] Open the brief in $VISUAL/$EDITOR and save it as
316
+ --file would; an unchanged buffer writes nothing
317
+ tumwater role <id> [--json] Show one role's instructions and resolved
318
+ settings — its built-in instructions, the roles.<id>.instructions override, the resolved
199
319
  provider/model (naming the budget fallback pair when one is
200
- configured), the min-tick interval, enabled/paused state, and
201
- the next tick's assembled prompt (the oldest queued prompt appears in it
202
- and is NOT consumed — one is dequeued per tick); --json prints the collector's payload
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
322
+ the next run's assembled prompt (the oldest inbox message appears in it
323
+ and is NOT consumed — one is dequeued per run); --json prints the collector's payload
203
324
  as machine-readable data
204
- tumwater role <id> --clear-notes Clear that loop's notebook
325
+ tumwater role <id> --clear-notes Clear that role's notes
205
326
  tumwater role <id> --notes-file <path>
206
- Replace that loop's notebook from a file ("-" reads stdin;
207
- 4 KB cap); a tick running at that moment may still
208
- overwrite it through its own role_notes call
209
- tumwater prompt <text...> Queue a prompt for the director loop
210
- tumwater prompt --file <path> Queue a prompt read from a file ("-" reads stdin)
327
+ Replace that role's notes from a file ("-" reads stdin;
328
+ 4 KB cap); a run in progress at that moment may still
329
+ overwrite it through its own tumwater-notes call
330
+ tumwater role <id> --clear-instructions
331
+ Clear that role's instructions override
332
+ tumwater role <id> --instructions-file <path>
333
+ Replace that role's instructions override from a file
334
+ ("-" reads stdin; 4 KB cap), written to roles.<id>.instructions
335
+ tumwater role <id> --clear-quiet-hours
336
+ Clear that role's own quiet-hours window
337
+ tumwater role <id> --quiet-hours <window>
338
+ Set that role's own daily local-time quiet-hours
339
+ window (e.g. "23:00-07:00"; empty clears it),
340
+ written to quietHoursPerRole.<id> for the base id
341
+ tumwater role <id> --cap <usd> Set that role's daily cap in USD (0 disables it),
342
+ written to maxDailyCostUsdPerRole.<id> for the base id
343
+ tumwater role <id> --clear-cap Clear that role's daily cap
344
+ tumwater role <id> --min-run-interval <seconds>
345
+ Set that role's own minimum-run interval (0 allows
346
+ back-to-back runs), written to roles.<id>.minRunIntervalSeconds
347
+ for the base id; clearing falls back to the team-wide interval
348
+ tumwater role <id> --clear-min-run-interval
349
+ Clear that role's own minimum-run interval
350
+ tumwater role <id> --provider <id>
351
+ Set that role's model provider (e.g. openai), written to
352
+ roles.<id>.provider for the base id
353
+ tumwater role <id> --clear-provider
354
+ Clear that role's model provider
355
+ tumwater role <id> --model <id> Set that role's model (a model id or a tier name like
356
+ strong), written to roles.<id>.model for the base id
357
+ tumwater role <id> --clear-model
358
+ Clear that role's model
359
+ tumwater role <id> --thinking <level>
360
+ Set that role's pi thinking level (off|minimal|low|
361
+ medium|high|xhigh|max), written to roles.<id>.thinking
362
+ for the base id
363
+ tumwater role <id> --clear-thinking
364
+ Clear that role's thinking level
365
+ tumwater role <id> --enable Enable the role, written to roles.<id>.enabled
366
+ (the base id for an instance)
367
+ tumwater role <id> --disable Disable it (refused for the director); clean up
368
+ leftovers with tumwater retire --role <id>
369
+ tumwater role <id> --instances <n>
370
+ Set how many parallel runners this role may have
371
+ (an integer from 1 to 8; only feature and bugfix split),
372
+ written to roles.<id>.instances for the base id
373
+ tumwater role <id> --clear-instances
374
+ Clear that role's instance count (back to 1)
375
+ tumwater prompt <text...> Send a message to the director's inbox
376
+ tumwater prompt --file <path> Send a message read from a file ("-" reads stdin)
211
377
  tumwater prompt --role <id> <text...>
212
- Queue a prompt for that loop's next tick (wakes it)
378
+ Send a message to that role's inbox for its next run (wakes it)
213
379
  tumwater prompt --at <duration> <text...>
214
- Queue a prompt that stays hidden until the duration has
380
+ Send a message that stays hidden until the duration has
215
381
  passed (45s, 90m, 1h30m, 1d; capped at 90d — listed and
216
- cancellable while it waits, delivered to the tick only
382
+ cancellable while it waits, delivered to the run only
217
383
  once due)
218
384
  tumwater prompt --attach <path> <text...>
219
- Queue a prompt with an image attached (repeat up to 4
385
+ Send a message with an image attached (repeat up to 4
220
386
  images: png, jpg, jpeg, gif, webp, bmp; each at most 5
221
- MiB — saved beside the queue file for the loop's next
222
- tick)
223
- tumwater prompt --list [--json] Show queued prompts, numbered, grouped by loop
387
+ MiB — saved beside the inbox file for the role's next
388
+ run)
389
+ tumwater prompt --list [--json] Show inbox messages, numbered, grouped by role
224
390
  (--json prints the {prompts} array as
225
391
  machine-readable data)
226
- tumwater prompt --cancel <n> Remove the Nth queued prompt as --list shows them; when
227
- several loops show that N, name one with --role <id>
392
+ tumwater prompt --cancel <n> Remove the Nth inbox message as --list shows them; when
393
+ several roles show that N, name one with --role <id>
394
+ tumwater prompt --top <n> Move the Nth inbox message as --list shows them to the
395
+ head of its role's inbox, so it dequeues next; a pending
396
+ --at deferral still holds until its time; --role <id>
397
+ disambiguates like --cancel
228
398
  tumwater prompt --edit <n> <text...> [--attach <path>]
229
- Replace the Nth queued prompt's text in place (position,
230
- enqueue age, and a pending --at deferral are kept; as
399
+ Replace the Nth inbox message's text in place (position,
400
+ age in the inbox, and a pending --at deferral are kept; as
231
401
  shown by --list); --attach (repeat up to 4) appends images
232
- after any the prompt already carries; when several loops
402
+ after any the prompt already carries; when several roles
233
403
  show that N, name one with --role <id>
234
404
  tumwater prompt --edit <n> --file <path> [--attach <path>]
235
- Replace the Nth queued prompt's text with the file's
405
+ Replace the Nth inbox message's text with the file's
236
406
  contents ("-" reads stdin), kept line for line; position,
237
407
  age, and a pending --at deferral are kept, and --role <id>
238
408
  disambiguates like --edit
409
+ tumwater prompt --edit <n> [--attach <path>]
410
+ Open the Nth inbox message in $VISUAL/$EDITOR and save it
411
+ as the text form would; an unchanged buffer writes
412
+ nothing; --role <id> disambiguates like --edit
239
413
  tumwater reset-counters [--role <id>]
240
- Zero lifetime ticks/commits/tokens/cost (fresh
414
+ Zero lifetime runs/commits/tokens/cost (fresh
241
415
  observation window; today's budget spend is kept — the
242
416
  daily cap cannot be reset past)
243
417
  tumwater wake [--role <id>] [--in <dur> | --cancel | --list [--json]]
244
- Wake a backed-off fleet — the named roles (or all) tick
418
+ Wake sleeping roles — the named roles (or all) run
245
419
  within one poll; --in schedules the wake for later;
246
420
  --cancel drops pending scheduled wakes;
247
421
  --list shows every pending scheduled wake, earliest first
248
422
  (--json for scripts)
249
- tumwater reclaim [--dry-run] Reclaim gitignored build outputs from every harness
250
- worktree; --dry-run lists each candidate with its idle age
423
+ tumwater reclaim [--dry-run] Reclaim gitignored build outputs from every
424
+ workspace; --dry-run lists each candidate with its idle age
251
425
  and ignored-path count and cleans nothing
252
- tumwater abort --role <id> Abort that loop's in-flight tick (work discarded; the loop
253
- keeps running)
426
+ tumwater revert <sha> Undo one merged change on main, committing the inverse
427
+ 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)
431
+ tumwater restart Apply a pending self-redeploy now, waiving the restart
432
+ cooldown (the dashboard's update-alert refresh button; a
433
+ passing check on main, a successful compile, and in-flight
434
+ runs finishing still apply)
254
435
  tumwater pause [--role <id>] [--for <dur>] [--reason <text>]
255
- Stop role loops (or just the named loop) starting new
256
- ticks; --reason states why the whole FLEET is paused (no
436
+ Stop roles (or just the named role) starting new
437
+ runs; --reason states why the whole team is paused (no
257
438
  per-role reason); --for auto-resumes (capped at 90d)
258
- tumwater resume [--role <id>] Lift a fleet or per-role pause
259
- tumwater retire --role <id> Remove a disabled loop's worktree, branch, and per-role
260
- state (landing ref, pause marker); --force overrides the
261
- safety rails; --json prints what was removed
262
- tumwater stop Stop a running fleet (drains in-flight ticks, like Ctrl+C)
439
+ tumwater resume [--role <id>] Lift a team or per-role pause
440
+ tumwater retire --role <id> Remove a disabled role's workspace, branch, and per-role
441
+ state (merge ref, pause marker); --force overrides the
442
+ safety rails; --json prints what was removed;
443
+ --dry-run lists what would be removed and any objections,
444
+ changing nothing; an id no longer configured (feature-4
445
+ after lowering instances, a removed custom role) is
446
+ accepted while its branch or merge ref remains
447
+ tumwater stop [--in <duration> | --cancel]
448
+ Stop a running team (finishes current work, like Ctrl+C);
449
+ --in schedules the stop, --cancel drops it
450
+ tumwater completion <bash|zsh|fish> Print a shell completion script (eval "$(tumwater completion zsh)" in your rc; fish: tumwater completion fish | source)
451
+ tumwater completion --roles Print the role ids --role completes (this repo's; the catalog when tumwater.json is unreadable)
452
+ 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)
263
453
  tumwater help [<command>] Show all commands, or one command's usage
264
454
  tumwater version Print the version
265
455
 
266
- The harness runs inside a git repo. Each role loop owns a persistent worktree and branch
267
- under .tumwater/, does one task per tick with pi, commits, and merges to main. Loops back
268
- off while the project is quiet and wake when main moves. Everything is local: no remotes.
456
+ tumwater runs inside a git repo. Each role owns a persistent workspace and branch
457
+ under .tumwater/, does one task per run with pi, commits, and merges to main. Roles
458
+ sleep while there is nothing to do and wake when main moves. Everything is local: no remotes.
269
459
  `;
270
460
  /** The listed command closest to a mistyped one, or null when nothing is close enough to
271
461
  * suggest. Case-insensitive closest-match over the commands helpStanzas(HELP) names, capped
@@ -299,9 +489,14 @@ export function helpStanzas(help = HELP) {
299
489
  }
300
490
  return stanzas;
301
491
  }
492
+ /** Commands that still dispatch but are not listed in help or completion: alias -> the command
493
+ * whose topic they print. `run` is the older name of `start`. */
494
+ export const HIDDEN_COMMAND_ALIASES = { run: "start", tick: "history" };
302
495
  /** The usage text for one command — every stanza whose command matches, then a pointer back to
303
496
  * the full list — or null when nothing in the help names that command. */
304
497
  export function helpTopic(command, help = HELP) {
498
+ if (Object.hasOwn(HIDDEN_COMMAND_ALIASES, command))
499
+ command = HIDDEN_COMMAND_ALIASES[command];
305
500
  const matches = helpStanzas(help).filter((s) => s.command === command);
306
501
  if (matches.length === 0)
307
502
  return null;
@@ -309,13 +504,13 @@ export function helpTopic(command, help = HELP) {
309
504
  }
310
505
  /** The free-form text commands and the flags that take a separate value token, for
311
506
  * helpTopicForArgs: a valued flag's value is plumbing (`prompt --role qa --help`, `bug
312
- * --cancel 2 --help`), never prose. bug/plan's valued flags are `--cancel`, `--edit`
313
- * and `--file`. */
507
+ * --cancel 2 --help`), never prose. bug/plan's valued flags are `--cancel`, `--edit`,
508
+ * `--file`, `--release` and `--top`. */
314
509
  const FREEFORM_VALUED_FLAGS = {
315
- prompt: ["--role", "--file", "--at", "--cancel", "--edit", "--attach"],
510
+ prompt: ["--role", "--file", "--at", "--cancel", "--edit", "--attach", "--top"],
316
511
  init: ["--branch", "--template", "--file"],
317
- bug: ["--cancel", "--edit", "--file"],
318
- plan: ["--cancel", "--edit", "--file"],
512
+ bug: ["--cancel", "--edit", "--file", "--release", "--top"],
513
+ plan: ["--cancel", "--edit", "--file", "--release", "--top"],
319
514
  };
320
515
  /** The `--help`/`-h` request cli.ts answers before dispatch: the topic text for `command`
321
516
  * when the invocation asks for help and names a topic, otherwise null — not a help request,