tumwater 0.2.0 → 0.3.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 (446) 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 +42 -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 +4 -3
  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 +402 -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 +246 -55
  41. package/dist/src/backlog/backlog-cli-view.js +280 -0
  42. package/dist/src/backlog/backlog-cli.js +85 -274
  43. package/dist/src/backlog/backlog-commit.js +4 -5
  44. package/dist/src/backlog/backlog-eligibility.js +175 -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 +254 -0
  48. package/dist/src/backlog/backlog-release.js +117 -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-culprit.js +94 -0
  56. package/dist/src/baseline/main-guardrails.js +209 -0
  57. package/dist/src/baseline/main-red.js +139 -32
  58. package/dist/src/baseline/main-revert.js +133 -0
  59. package/dist/src/baseline/main-watch.js +184 -0
  60. package/dist/src/brief/brief-edit.js +9 -11
  61. package/dist/src/brief/brief.js +31 -51
  62. package/dist/src/budget/budget.js +30 -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 +1 -2
  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 +118 -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 +150 -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 +308 -590
  82. package/dist/src/cli/cli-repo-gate.js +11 -1
  83. package/dist/src/cli/cli-role-command.js +420 -0
  84. package/dist/src/cli/cli-start-summary.js +160 -0
  85. package/dist/src/cli/{cli-run.js → cli-start.js} +165 -237
  86. package/dist/src/cli/completion.js +149 -22
  87. package/dist/src/cli/config-commands.js +41 -18
  88. package/dist/src/cli/follow-view.js +75 -0
  89. package/dist/src/cli/help.js +189 -73
  90. package/dist/src/cli/log-commands.js +148 -82
  91. package/dist/src/cli/question-commands.js +205 -10
  92. package/dist/src/cli.js +106 -43
  93. package/dist/src/collections.js +26 -10
  94. package/dist/src/concurrency/check-permit.js +20 -3
  95. package/dist/src/concurrency/lock.js +17 -13
  96. package/dist/src/concurrency/provider-lease.js +44 -8
  97. package/dist/src/concurrency/semaphore.js +102 -26
  98. package/dist/src/config/config-aliases.js +0 -1
  99. package/dist/src/config/config-editable-keys.js +13 -1
  100. package/dist/src/config/config-fallbacks.js +93 -56
  101. package/dist/src/config/config-field-checks.js +40 -10
  102. package/dist/src/config/config-keys.js +30 -8
  103. package/dist/src/config/config-live.js +63 -24
  104. package/dist/src/config/config-request.js +137 -0
  105. package/dist/src/config/config-schema.js +31 -24
  106. package/dist/src/config/config-selector-checks.js +123 -0
  107. package/dist/src/config/config-validation-agents.js +80 -0
  108. package/dist/src/config/config-validation-model.js +116 -0
  109. package/dist/src/config/config-validation.js +141 -199
  110. package/dist/src/config/config-views.js +127 -53
  111. package/dist/src/config/config-write-core.js +135 -0
  112. package/dist/src/config/config-write.js +131 -264
  113. package/dist/src/config/config.js +48 -38
  114. package/dist/src/config/model-selector.js +34 -34
  115. package/dist/src/doctor/doctor-backlog-bugs.js +287 -0
  116. package/dist/src/doctor/doctor-backlog-plans.js +263 -0
  117. package/dist/src/doctor/doctor-backlog.js +100 -496
  118. package/dist/src/doctor/doctor-check-names.js +81 -0
  119. package/dist/src/doctor/doctor-checks.js +52 -579
  120. package/dist/src/doctor/doctor-claude-checks.js +145 -0
  121. package/dist/src/doctor/doctor-codex-checks.js +279 -0
  122. package/dist/src/doctor/doctor-contention-checks.js +380 -0
  123. package/dist/src/doctor/doctor-holds.js +82 -66
  124. package/dist/src/doctor/doctor-install.js +2 -1
  125. package/dist/src/doctor/doctor-model-checks.js +236 -402
  126. package/dist/src/doctor/doctor-notify.js +3 -4
  127. package/dist/src/doctor/doctor-opencode-checks.js +162 -0
  128. package/dist/src/doctor/doctor-orphans.js +182 -63
  129. package/dist/src/doctor/doctor-project-checks.js +303 -0
  130. package/dist/src/doctor/doctor.js +121 -77
  131. package/dist/src/doctor/image-probe.js +21 -8
  132. package/dist/src/doctor/outcome.js +3 -2
  133. package/dist/src/doctor/probe.js +7 -11
  134. package/dist/src/events/event-format.js +181 -86
  135. package/dist/src/events/event-labels.js +12 -5
  136. package/dist/src/events/event-legacy.js +39 -15
  137. package/dist/src/events/event-read.js +39 -39
  138. package/dist/src/events/event-tally.js +16 -0
  139. package/dist/src/events/event-window.js +60 -24
  140. package/dist/src/events/events.js +30 -13
  141. package/dist/src/events/notify.js +7 -7
  142. package/dist/src/failure/failure-cluster.js +12 -12
  143. package/dist/src/failure/failure-data.js +56 -56
  144. package/dist/src/failure/failure-render.js +31 -23
  145. package/dist/src/failure/failure-state-change.js +17 -12
  146. package/dist/src/failure/time-spend.js +99 -35
  147. package/dist/src/files/files.js +111 -35
  148. package/dist/src/files/json-files.js +3 -3
  149. package/dist/src/files/json-object.js +28 -7
  150. package/dist/src/files/stat-cache.js +2 -2
  151. package/dist/src/files/tail.js +1 -1
  152. package/dist/src/gates/bootstrap-gates.js +4 -5
  153. package/dist/src/gates/budget-gates.js +177 -84
  154. package/dist/src/gates/disk-gate.js +1 -1
  155. package/dist/src/gates/gate-polls.js +108 -58
  156. package/dist/src/gates/maintenance-quota.js +10 -13
  157. package/dist/src/gates/pause-gates.js +28 -10
  158. package/dist/src/gates/readiness.js +7 -3
  159. package/dist/src/gates/role-cap-gates.js +8 -8
  160. package/dist/src/gates/startup-gate.js +94 -32
  161. package/dist/src/gates/streak-gate.js +54 -30
  162. package/dist/src/git/commit-message.js +77 -46
  163. package/dist/src/git/git-diff.js +16 -10
  164. package/dist/src/git/git-run.js +79 -38
  165. package/dist/src/git/git.js +36 -34
  166. package/dist/src/git/slot-salvage.js +253 -0
  167. package/dist/src/git/slots-state.js +6 -6
  168. package/dist/src/git/worktree-pool.js +132 -38
  169. package/dist/src/git/worktree-use.js +4 -11
  170. package/dist/src/git/worktree.js +94 -37
  171. package/dist/src/gui/gui-admin-endpoints.js +96 -0
  172. package/dist/src/gui/gui-args.js +79 -8
  173. package/dist/src/gui/gui-backlog-commands.js +42 -18
  174. package/dist/src/gui/gui-backlog-endpoints.js +155 -0
  175. package/dist/src/gui/gui-command.js +8 -13
  176. package/dist/src/gui/gui-config-commands.js +94 -72
  177. package/dist/src/gui/gui-endpoint-commands.js +4 -3
  178. package/dist/src/gui/gui-endpoint-common.js +4 -4
  179. package/dist/src/gui/gui-endpoints.js +11 -380
  180. package/dist/src/gui/gui-history-endpoints.js +301 -0
  181. package/dist/src/gui/gui-operator-commands.js +108 -13
  182. package/dist/src/gui/gui-prompt-commands.js +11 -14
  183. package/dist/src/gui/gui-report-endpoints.js +90 -0
  184. package/dist/src/gui/gui-server.js +11 -4
  185. package/dist/src/gui/gui-team-commands.js +7 -7
  186. package/dist/src/gui/http-body.js +1 -1
  187. package/dist/src/history/history-data.js +122 -234
  188. package/dist/src/history/history-queued.js +147 -0
  189. package/dist/src/history/history-render.js +42 -22
  190. package/dist/src/history/history.js +193 -49
  191. package/dist/src/inbox/inbox-attachments.js +29 -30
  192. package/dist/src/inbox/inbox-cancel.js +10 -11
  193. package/dist/src/inbox/inbox-edit.js +9 -9
  194. package/dist/src/inbox/inbox-submit.js +18 -18
  195. package/dist/src/inbox/inbox-top.js +25 -9
  196. package/dist/src/inbox/inbox.js +42 -43
  197. package/dist/src/inbox/pending-prompt.js +26 -26
  198. package/dist/src/inbox/prompt-commands.js +62 -49
  199. package/dist/src/inbox/prompt-not-before.js +2 -2
  200. package/dist/src/init/init-templates.js +1 -2
  201. package/dist/src/init/init.js +28 -23
  202. package/dist/src/merge/backlog-conflicts.js +215 -35
  203. package/dist/src/merge/merge-batch.js +14 -8
  204. package/dist/src/merge/merge-cancel.js +53 -0
  205. package/dist/src/merge/merge-check-failures.js +44 -22
  206. package/dist/src/merge/merge-core.js +81 -32
  207. package/dist/src/merge/merge-diff.js +5 -4
  208. package/dist/src/merge/merge-drain.js +150 -11
  209. package/dist/src/merge/merge-git.js +177 -38
  210. package/dist/src/merge/merge-pipeline.js +15 -3
  211. package/dist/src/merge/merge-post-review.js +90 -0
  212. package/dist/src/merge/merge-queue-render.js +49 -11
  213. package/dist/src/merge/merge-queue.js +31 -15
  214. package/dist/src/merge/merge-requeue.js +102 -0
  215. package/dist/src/merge/merge-slot.js +61 -16
  216. package/dist/src/merge/merge-stack.js +33 -11
  217. package/dist/src/merge/merge-to-main.js +86 -27
  218. package/dist/src/merge/merge-top.js +69 -0
  219. package/dist/src/merge/merge-verify.js +12 -10
  220. package/dist/src/notes-cli.js +30 -15
  221. package/dist/src/operator/operator-commands.js +192 -81
  222. package/dist/src/operator/operator-intent.js +69 -42
  223. package/dist/src/operator/operator-requests.js +35 -40
  224. package/dist/src/operator/retire.js +5 -6
  225. package/dist/src/operator/revert.js +142 -34
  226. package/dist/src/orchestrator/orchestrator-launch.js +60 -52
  227. package/dist/src/orchestrator/orchestrator-poll.js +320 -0
  228. package/dist/src/orchestrator/orchestrator-scheduling.js +68 -369
  229. package/dist/src/orchestrator/orchestrator.js +128 -369
  230. package/dist/src/orchestrator/retention.js +42 -8
  231. package/dist/src/orchestrator/scheduling-admit.js +116 -0
  232. package/dist/src/orchestrator/scheduling-scope.js +201 -0
  233. package/dist/src/orchestrator/scheduling-skip.js +185 -0
  234. package/dist/src/orchestrator/startup-migration-steps.js +8 -7
  235. package/dist/src/orchestrator/startup-migrations.js +11 -7
  236. package/dist/src/paths.js +116 -49
  237. package/dist/src/pi/command-shape.js +12 -1
  238. package/dist/src/pi/pi-args.js +6 -4
  239. package/dist/src/pi/pi-backend.js +6 -6
  240. package/dist/src/pi/pi-bin.js +54 -63
  241. package/dist/src/pi/pi-listed-models.js +53 -0
  242. package/dist/src/pi/pi-models.js +63 -30
  243. package/dist/src/pi/pi-run-result.js +1 -1
  244. package/dist/src/pi/pi-settings.js +1 -1
  245. package/dist/src/pi/pi-stream.js +6 -6
  246. package/dist/src/pi/pi-watchdogs.js +18 -19
  247. package/dist/src/pi-extension/bounded-output.js +5 -3
  248. package/dist/src/pi-extension/context-budget.js +2 -2
  249. package/dist/src/pi-extension/context-shake.js +1 -1
  250. package/dist/src/pi-extension/context-window.js +0 -1
  251. package/dist/src/pi-extension/full-output.js +3 -10
  252. package/dist/src/pi-extension/strip-thinking.js +0 -1
  253. package/dist/src/pi-extension/trim-system-prompt.js +3 -4
  254. package/dist/src/pi-extension/write-guard.js +37 -0
  255. package/dist/src/process/launch-services.js +1 -2
  256. package/dist/src/process/node-bin.js +16 -0
  257. package/dist/src/process/process-group.js +8 -18
  258. package/dist/src/process/process.js +41 -2
  259. package/dist/src/process/run-marker.js +18 -6
  260. package/dist/src/process/supervisor.js +22 -21
  261. package/dist/src/prompt/dialect.js +17 -2
  262. package/dist/src/prompt/gate-notes.js +203 -0
  263. package/dist/src/prompt/gate-prompts.js +121 -211
  264. package/dist/src/prompt/notes-backlog.js +181 -0
  265. package/dist/src/prompt/principles.js +1 -2
  266. package/dist/src/prompt/prompt-followup.js +19 -14
  267. package/dist/src/prompt/prompt.js +129 -204
  268. package/dist/src/redeploy/redeploy-policy.js +24 -19
  269. package/dist/src/redeploy/redeploy-probes.js +1 -1
  270. package/dist/src/redeploy/redeploy.js +2 -3
  271. package/dist/src/redeploy/redeployer.js +20 -20
  272. package/dist/src/redeploy/self-reload.js +2 -1
  273. package/dist/src/report/report-data.js +161 -77
  274. package/dist/src/report/report-fold.js +129 -52
  275. package/dist/src/report/report-main-red.js +55 -0
  276. package/dist/src/report/report-render.js +133 -64
  277. package/dist/src/report/report-types.js +1 -0
  278. package/dist/src/report/report.js +26 -9
  279. package/dist/src/request-timeouts.js +2 -2
  280. package/dist/src/review/known-flakes.js +100 -1
  281. package/dist/src/review/post-merge-review.js +106 -0
  282. package/dist/src/review/protected-edits.js +4 -5
  283. package/dist/src/review/review-followup.js +8 -8
  284. package/dist/src/review/review-precheck.js +66 -23
  285. package/dist/src/review/review-run.js +395 -0
  286. package/dist/src/review/review-verdict.js +2 -2
  287. package/dist/src/review/review.js +155 -360
  288. package/dist/src/review/secret-leaks.js +36 -16
  289. package/dist/src/review/suite-rerun.js +0 -1
  290. package/dist/src/roles/legacy-role-migration.js +80 -7
  291. package/dist/src/roles/role-catalog.js +69 -12
  292. package/dist/src/roles/role-guidance.js +55 -20
  293. package/dist/src/roles/role-labels.js +1 -2
  294. package/dist/src/roles/role-render.js +67 -50
  295. package/dist/src/roles/role-view.js +59 -47
  296. package/dist/src/roles/roles.js +31 -31
  297. package/dist/src/roles/runner-ids.js +97 -0
  298. package/dist/src/run/acceptance-greps.js +119 -0
  299. package/dist/src/run/feedback-filings.js +51 -0
  300. package/dist/src/{tick → run}/qa-coverage.js +9 -27
  301. package/dist/src/{tick/tick-apply.js → run/run-apply.js} +95 -94
  302. package/dist/src/run/run-detail-data.js +179 -0
  303. package/dist/src/run/run-detail-render.js +98 -0
  304. package/dist/src/run/run-detail.js +168 -0
  305. package/dist/src/{tick/tick-finalize.js → run/run-finalize.js} +72 -60
  306. package/dist/src/{tick/tick-outcome.js → run/run-outcome.js} +6 -7
  307. package/dist/src/{tick/tick-prompt.js → run/run-prompt.js} +108 -73
  308. package/dist/src/{tick/tick-resume.js → run/run-resume.js} +55 -26
  309. package/dist/src/{tick/tick-stage.js → run/run-stage.js} +108 -50
  310. package/dist/src/{tick/tick-timing.js → run/run-timing.js} +43 -41
  311. package/dist/src/{tick/tick-usage.js → run/run-usage.js} +45 -37
  312. package/dist/src/{tick/tick-verdict.js → run/run-verdict.js} +91 -56
  313. package/dist/src/run/selfcheck-digest.js +40 -0
  314. package/dist/src/run/stage-backlog-checks.js +249 -0
  315. package/dist/src/run/stage-check.js +172 -0
  316. package/dist/src/run/stage-path-checks.js +730 -0
  317. package/dist/src/{loop → runner}/leftover.js +80 -25
  318. package/dist/src/{loop → runner}/model-fallback.js +12 -12
  319. package/dist/src/runner/revision.js +202 -0
  320. package/dist/src/{loop/loop-fallback.js → runner/runner-fallback.js} +8 -8
  321. package/dist/src/runner/runner-outcome.js +107 -0
  322. package/dist/src/{loop/loop-pi.js → runner/runner-pi.js} +140 -131
  323. package/dist/src/{loop/loop-recovery.js → runner/runner-recovery.js} +21 -15
  324. package/dist/src/{loop/loop-tick.js → runner/runner-run.js} +218 -240
  325. package/dist/src/{loop/loop-state.js → runner/runner-state-load.js} +61 -114
  326. package/dist/src/runner/runner-state.js +102 -0
  327. package/dist/src/{loop/loop.js → runner/runner.js} +123 -120
  328. package/dist/src/scheduling/backoff.js +38 -38
  329. package/dist/src/scheduling/claims.js +35 -22
  330. package/dist/src/scheduling/once-round.js +22 -22
  331. package/dist/src/scheduling/quiet-hours.js +5 -6
  332. package/dist/src/scheduling/scheduling.js +74 -64
  333. package/dist/src/scheduling/work-merged-cache.js +2 -2
  334. package/dist/src/status/status-budget.js +55 -47
  335. package/dist/src/status/status-data.js +43 -16
  336. package/dist/src/status/status-inbox.js +2 -2
  337. package/dist/src/status/status-install.js +0 -1
  338. package/dist/src/status/status-polls.js +28 -28
  339. package/dist/src/status/status-roles.js +39 -13
  340. package/dist/src/team/error-storm.js +8 -8
  341. package/dist/src/team/failure-spread.js +2 -2
  342. package/dist/src/team/orchestrator-info.js +15 -9
  343. package/dist/src/team/reclaim.js +5 -6
  344. package/dist/src/team/team-hold.js +7 -7
  345. package/dist/src/team/team-polls.js +91 -50
  346. package/dist/src/team/team-state.js +8 -2
  347. package/dist/src/text/datetime.js +63 -17
  348. package/dist/src/text/format.js +48 -11
  349. package/dist/src/text/markdown.js +8 -5
  350. package/dist/src/text/phrases.js +57 -23
  351. package/dist/src/text/suggest.js +1 -1
  352. package/dist/src/text/text.js +67 -13
  353. package/dist/src/ui/badges.js +65 -37
  354. package/dist/src/ui/gui/gui-client-backlog.js +292 -0
  355. package/dist/src/ui/gui/gui-client-boot.js +32 -26
  356. package/dist/src/ui/gui/gui-client-composer.js +8 -9
  357. package/dist/src/ui/gui/gui-client-drawer-config.js +212 -0
  358. package/dist/src/ui/gui/gui-client-drawer.js +126 -285
  359. package/dist/src/ui/gui/gui-client-feed.js +271 -0
  360. package/dist/src/ui/gui/gui-client-history.js +434 -67
  361. package/dist/src/ui/gui/gui-client-labels.js +1 -2
  362. package/dist/src/ui/gui/gui-client-markdown.js +1 -2
  363. package/dist/src/ui/gui/gui-client-model.js +27 -36
  364. package/dist/src/ui/gui/gui-client-operator.js +55 -51
  365. package/dist/src/ui/gui/gui-client-pending.js +227 -23
  366. package/dist/src/ui/gui/gui-client-report-chart.js +464 -0
  367. package/dist/src/ui/gui/gui-client-report.js +87 -427
  368. package/dist/src/ui/gui/{gui-client-loops.js → gui-client-roles.js} +43 -44
  369. package/dist/src/ui/gui/gui-client-settings.js +56 -4
  370. package/dist/src/ui/gui/gui-client-team.js +25 -465
  371. package/dist/src/ui/gui/gui-client.js +27 -25
  372. package/dist/src/ui/gui/gui-icons.js +0 -2
  373. package/dist/src/ui/gui/gui-page.js +9 -7
  374. package/dist/src/ui/gui/gui-styles.js +34 -34
  375. package/dist/src/ui/progress-data.js +9 -11
  376. package/dist/src/ui/{tick-progress-model.js → run-progress-model.js} +31 -31
  377. package/dist/src/ui/status-model.js +133 -125
  378. package/dist/src/ui/status-payload.js +136 -49
  379. package/dist/src/ui/status-render.js +101 -82
  380. package/dist/src/ui/team-alerts.js +248 -57
  381. package/dist/src/ui/tone.js +5 -6
  382. package/dist/src/ui/transcript-run.js +58 -0
  383. package/dist/src/ui/transcript-tail.js +28 -20
  384. package/dist/src/ui/transcript.js +63 -23
  385. package/dist/src/ui/tui/tui-app.js +0 -1
  386. package/dist/src/ui/tui/tui-backlog.js +51 -14
  387. package/dist/src/ui/tui/tui-editor-answer.js +27 -31
  388. package/dist/src/ui/tui/tui-editor-attach.js +3 -5
  389. package/dist/src/ui/tui/tui-editor-backends.js +132 -0
  390. package/dist/src/ui/tui/tui-editor-brief.js +10 -12
  391. package/dist/src/ui/tui/tui-editor-budget.js +35 -31
  392. package/dist/src/ui/tui/tui-editor-claude-reserve.js +24 -0
  393. package/dist/src/ui/tui/tui-editor-concurrency.js +24 -0
  394. package/dist/src/ui/tui/tui-editor-config.js +86 -0
  395. package/dist/src/ui/tui/tui-editor-entry.js +36 -47
  396. package/dist/src/ui/tui/tui-editor-fallback.js +31 -0
  397. package/dist/src/ui/tui/tui-editor-instances.js +37 -0
  398. package/dist/src/ui/tui/tui-editor-instructions.js +136 -0
  399. package/dist/src/ui/tui/tui-editor-interval.js +11 -9
  400. package/dist/src/ui/tui/tui-editor-model.js +29 -0
  401. package/dist/src/ui/tui/tui-editor-notes.js +3 -5
  402. package/dist/src/ui/tui/tui-editor-notify.js +25 -0
  403. package/dist/src/ui/tui/tui-editor-pause.js +48 -59
  404. package/dist/src/ui/tui/tui-editor-prompt.js +11 -16
  405. package/dist/src/ui/tui/tui-editor-provider-caps.js +27 -0
  406. package/dist/src/ui/tui/tui-editor-queued.js +5 -9
  407. package/dist/src/ui/tui/tui-editor-quiet.js +99 -35
  408. package/dist/src/ui/tui/tui-editor-retire.js +4 -6
  409. package/dist/src/ui/tui/tui-editor-role-key.js +76 -0
  410. package/dist/src/ui/tui/tui-editor-role-model.js +28 -0
  411. package/dist/src/ui/tui/tui-editor-search.js +45 -33
  412. package/dist/src/ui/tui/tui-editor-session.js +60 -34
  413. package/dist/src/ui/tui/tui-editor-slots.js +23 -0
  414. package/dist/src/ui/tui/tui-editors.js +35 -2
  415. package/dist/src/ui/tui/tui-frame.js +56 -11
  416. package/dist/src/ui/tui/tui-history.js +8 -9
  417. package/dist/src/ui/tui/tui-input.js +13 -11
  418. package/dist/src/ui/tui/tui-keymap.js +0 -1
  419. package/dist/src/ui/tui/tui-keys.js +24 -9
  420. package/dist/src/ui/tui/tui-pane-activity.js +14 -11
  421. package/dist/src/ui/tui/tui-pane-backlog.js +171 -126
  422. package/dist/src/ui/tui/tui-pane-brief.js +0 -1
  423. package/dist/src/ui/tui/tui-pane-ctx.js +2 -2
  424. package/dist/src/ui/tui/tui-pane-health.js +58 -8
  425. package/dist/src/ui/tui/tui-pane-history.js +402 -82
  426. package/dist/src/ui/tui/tui-pane-pending.js +308 -13
  427. package/dist/src/ui/tui/tui-pane-queued.js +71 -55
  428. package/dist/src/ui/tui/tui-pane-report.js +46 -14
  429. package/dist/src/ui/tui/tui-pane-session.js +25 -6
  430. package/dist/src/ui/tui/tui-pane-transcript.js +111 -37
  431. package/dist/src/ui/tui/tui-pane.js +80 -23
  432. package/dist/src/ui/tui/tui-panes.js +100 -30
  433. package/dist/src/ui/tui/tui.js +14 -14
  434. package/dist/src/verdict/fix-claim.js +82 -32
  435. package/dist/src/verdict/no-change.js +4 -4
  436. package/dist/src/verdict/refusal.js +40 -16
  437. package/dist/src/verdict/reply-contract.js +42 -31
  438. package/dist/src/version.js +0 -1
  439. package/package.json +2 -1
  440. package/dist/src/loop/revision.js +0 -70
  441. package/dist/src/roles/loop-ids.js +0 -77
  442. package/dist/src/tick/stage-check.js +0 -419
  443. package/dist/src/tick/telemetry-digest.js +0 -25
  444. package/dist/src/tick/tick-detail-data.js +0 -108
  445. package/dist/src/tick/tick-detail.js +0 -163
  446. package/dist/src/ui/gui/gui-client-sound.js +0 -53
@@ -1,6 +1,6 @@
1
1
  /** The declarative flag-vocabulary layer shared by every command's argument gate: the
2
2
  * FlagSpec shape, the per-flag specs (ROLE_FLAG, durationFlagSpec, REASON_FLAG, sinceFlagSpec,
3
- * N_FLAG, JSON_FLAG, grepFlagSpec, RUN_FLAG_SPECS), and the unknown-argument gate
3
+ * N_FLAG, JSON_FLAG, grepFlagSpec, START_FLAG_SPECS), and the unknown-argument gate
4
4
  * (rejectUnknownArgs, with rejectEqualsForm). Split from cli/cli-args.ts, whose imperative
5
5
  * single-flag parsers (flagValue, parseCountFlag, parseDurationFlag, parseRoleFlag, ...)
6
6
  * stay there — one module per layer, so the vocabulary a command accepts and the parsers
@@ -11,7 +11,8 @@
11
11
  import { fail } from "./cli-output.js";
12
12
  import { failOverDurationCap, parseCountFlag, parseDurationFlag, parsePortFlag, rejectRepeatFlag } from "./cli-args.js";
13
13
  import { PAUSE_FOR_MAX_MS } from "../operator/operator-intent.js";
14
- import { typoSuffix } from "../text/suggest.js";
14
+ import { allRoleIds } from "../roles/roles.js";
15
+ import { didYouMean, suggestClosest, typoSuffix } from "../text/suggest.js";
15
16
  import { gotSuffix } from "../text/text.js";
16
17
  /** One command's accepted flag list as error-message text (`--file <path>, --branch <name>, …`),
17
18
  * derived from the specs — the one home of the rendering, so the lists the error messages
@@ -42,10 +43,18 @@ export function rejectUnknownDoubleDash(command, args, specs) {
42
43
  * (rejectUnknownDoubleDash) print, so the message cannot drift between the two gates. The
43
44
  * valid-flags list is followed by text/suggest.ts's did-you-mean hint when the token is a near
44
45
  * miss of an accepted spelling (`--rol` → `--role`), the same annotation every other unknown-X
45
- * error carries; a token far from every flag gets only the list. */
46
+ * error carries; a token far from every flag gets only the list. A bare token that names (or
47
+ * nearly names) a role id, on a command taking ROLE_FLAG, instead gets `did you mean \`--role
48
+ * <id>\`?` (`tumwater wake feature`); `role` is exempt because it peels its own positional id,
49
+ * so a stray second token there is not a missing flag. Custom (config-defined) roles get no
50
+ * hint: this parse-time gate has no config, so only allRoleIds() are matched. */
46
51
  function failUnknownArgument(command, arg, specs) {
47
52
  const spellings = specs.flatMap((s) => s.names);
48
- fail(`unknown argument: ${arg} (valid flags for tumwater ${command}: ${validFlagsList(specs)})${typoSuffix(arg, spellings)}`);
53
+ const roleId = specs.includes(ROLE_FLAG) && !arg.startsWith("-") && command !== "role"
54
+ ? suggestClosest(arg, allRoleIds())
55
+ : null;
56
+ const suffix = roleId !== null ? didYouMean(`--role ${roleId}`) : typoSuffix(arg, spellings);
57
+ fail(`unknown argument: ${arg} (valid flags for tumwater ${command}: ${validFlagsList(specs)})${suffix}`);
49
58
  }
50
59
  /** A `--flag=value` token's flag name ("--role" from "--role=feature"), or null when the
51
60
  * token is not in equals form. "--=x" and bare "--" carry no flag name and stay null. */
@@ -77,7 +86,7 @@ export function rejectEqualsForm(arg, specs) {
77
86
  * gate below, so the three wordings cannot drift (the drift-guard test imports it). */
78
87
  export const ROLE_VALUE_ERROR = "--role needs a role id (e.g. `--role feature`)";
79
88
  /** The missing-or-flag-shaped-value error parseBranchFlag (cli/cli-args.ts) shares with
80
- * RUN_FLAG_SPECS' --branch entry, for the same no-drift reason. */
89
+ * START_FLAG_SPECS' --branch entry, for the same no-drift reason. */
81
90
  export const BRANCH_VALUE_ERROR = "--branch needs a branch name (e.g. `--branch release/2.0`)";
82
91
  /** The `--role <id>` flag spec, shared by every role-targeting command (logs, reset-counters,
83
92
  * wake, abort, pause, resume): one definition of the flag's spelling and value shape so the
@@ -89,6 +98,16 @@ export const ROLE_FLAG = {
89
98
  valueName: "<id>",
90
99
  missingValue: ROLE_VALUE_ERROR,
91
100
  };
101
+ /** The missing-value error for `logs --transcript` (LOGS_TRANSCRIPT_FLAG's trailing gate). */
102
+ export const LOGS_TRANSCRIPT_VALUE_ERROR = "--transcript needs a role id (e.g. `--transcript feature`)";
103
+ /** The `--transcript <id>` flag spec of `logs`: the role whose agent transcript to print. A
104
+ * separate constant from ROLE_FLAG because its missing-value text names `--transcript`. */
105
+ export const LOGS_TRANSCRIPT_FLAG = {
106
+ names: ["--transcript"],
107
+ value: true,
108
+ valueName: "<id>",
109
+ missingValue: LOGS_TRANSCRIPT_VALUE_ERROR,
110
+ };
92
111
  /** The `--for <duration>` flag spec factory, accepted by `pause` (the timed pause) and
93
112
  * `run` (the windowed run): one definition of the flag's spelling and value shape, beside
94
113
  * ROLE_FLAG, so the gate's accepted vocabulary and parseDurationFlag's error messages cannot
@@ -183,6 +202,19 @@ export function sinceFlagSpec(label) {
183
202
  },
184
203
  };
185
204
  }
205
+ /** The `--until <duration>` flag spec of `logs`, `history` and `report`: ends the `--since`
206
+ * window that long ago. `label` names the command with the flag (e.g. "logs --until"). */
207
+ export function untilFlagSpec(label) {
208
+ return {
209
+ names: ["--until"],
210
+ value: true,
211
+ valueName: "<duration>",
212
+ missingValue: `${label} needs a value`,
213
+ validate: (value) => {
214
+ parseDurationFlag(label, value);
215
+ },
216
+ };
217
+ }
186
218
  /** The `-n <count>` flag spec, shared by the two tail views that take a row count (logs,
187
219
  * history): one definition of the flag's spelling and value shape, beside sinceFlagSpec, so the
188
220
  * gate's accepted vocabulary and parseCountFlag's error messages cannot drift apart. validate
@@ -196,12 +228,27 @@ export const N_FLAG = {
196
228
  },
197
229
  };
198
230
  /** The `--json` flag spec, shared by every command with a machine-readable form (status,
199
- * doctor, logs, history, tick, diff, backlog, role, report, prompt --list): one definition of
231
+ * doctor, logs, history, diff, backlog, role, report, prompt --list): one definition of
200
232
  * the flag's spelling, beside ROLE_FLAG and sinceFlagSpec, so the gate's accepted vocabulary
201
233
  * cannot drift apart. It takes no value and carries no per-command wording — unlike its
202
234
  * siblings it needs neither a factory nor a missing-value error — so the constant is the
203
235
  * whole spec, and the render-vs-JSON switch stays in each command body beside its render. */
204
236
  export const JSON_FLAG = { names: ["--json"] };
237
+ /** The `-f/--follow` flag spec, shared by every command with a follow view (logs, history,
238
+ * status, queue, report, backlog and diff — each snapshot command's `-f/--follow` twin): one
239
+ * definition of the flag's spelling, beside ROLE_FLAG and JSON_FLAG, so the gate's accepted
240
+ * vocabulary cannot drift apart. It takes no value, like JSON_FLAG; each body renders its
241
+ * own live view, and detects the flag through hasFollowFlag, so the spelling lives in exactly
242
+ * one place. */
243
+ export const FOLLOW_FLAG = { names: ["-f", "--follow"] };
244
+ /** Whether an arg array carries the `-f/--follow` flag — the detection every follow-capable
245
+ * command body spelled out as an `includes("-f") || includes("--follow")` one-liner over
246
+ * its own arg array (`args` for status, queue, report and diff; `rest` for logs, history and
247
+ * backlog). Now derived from FOLLOW_FLAG's own spelling, so the detection cannot drift from
248
+ * the gate's accepted vocabulary. */
249
+ export function hasFollowFlag(args) {
250
+ return FOLLOW_FLAG.names.some((name) => args.includes(name));
251
+ }
205
252
  /** The `--ready` flag spec, accepted by `backlog`: keep only the entries no hold keeps from
206
253
  * being picked. Value-less, like STAT_FLAG. */
207
254
  export const READY_FLAG = { names: ["--ready"] };
@@ -211,10 +258,35 @@ export const REPROBE_FLAG = { names: ["--reprobe"] };
211
258
  /** The `--problems` flag spec, accepted by `doctor`: print only the warn and fail rows. Value-less,
212
259
  * like REPROBE_FLAG. */
213
260
  export const PROBLEMS_FLAG = { names: ["--problems"] };
261
+ /** The `--kill-orphans` flag spec, accepted by `doctor`: first kill the orphaned processes the
262
+ * orphans check lists, each with its descendants. Value-less, like PROBLEMS_FLAG. */
263
+ export const KILL_ORPHANS_FLAG = { names: ["--kill-orphans"] };
214
264
  /** The `--stat` flag spec, accepted by `diff --role`: print each patch as its `git diff --stat`
215
265
  * summary. Value-less, like JSON_FLAG. */
216
266
  export const STAT_FLAG = { names: ["--stat"] };
217
- /** The `--summary` flag spec, accepted by `history`: tally each loop's tick outcomes instead of
267
+ /** The `--overlaps` flag spec, accepted by `diff`: list the files two or more roles' pending
268
+ * changes touch. Value-less, like STAT_FLAG. */
269
+ export const OVERLAPS_FLAG = { names: ["--overlaps"] };
270
+ /** The missing-value wording for DIFF_PATH_FLAG. */
271
+ const DIFF_PATH_VALUE_ERROR = "diff --path needs a path (e.g. `--path src/cli.ts`)";
272
+ /** The `--path` flag spec, accepted by `diff --role`: keep only the part of each role's view
273
+ * under one repo-relative file or directory. Valued, unlike OVERLAPS_FLAG. */
274
+ export const DIFF_PATH_FLAG = {
275
+ names: ["--path"],
276
+ value: true,
277
+ valueName: "<path>",
278
+ missingValue: DIFF_PATH_VALUE_ERROR,
279
+ };
280
+ /** The `--patch` flag spec, accepted by `history <role> <n>`: append the run's commit patch.
281
+ * Value-less, like STAT_FLAG. */
282
+ export const PATCH_FLAG = { names: ["--patch"] };
283
+ /** The `--transcript` flag spec, accepted by `history <role> <n>`: append that run's agent
284
+ * transcript to its trail. Value-less, like STAT_FLAG. */
285
+ export const TRANSCRIPT_FLAG = { names: ["--transcript"] };
286
+ /** The `--prompt` flag spec: value-less, used by `logs` (the transcript view) and by the
287
+ * `history <role>` trail (with `--transcript`). */
288
+ export const PROMPT_FLAG = { names: ["--prompt"] };
289
+ /** The `--summary` flag spec, accepted by `history`: tally each role's run outcomes instead of
218
290
  * printing the rows. Value-less, like STAT_FLAG. */
219
291
  export const SUMMARY_FLAG = { names: ["--summary"] };
220
292
  /** The `--count` flag spec, accepted by `logs`: tally the selected window's event types
@@ -227,10 +299,10 @@ export const FORCE_FLAG = { names: ["--force"] };
227
299
  /** The `--dry-run` flag spec: preview a reclaim pass or a retire without changing anything. Beside
228
300
  * FORCE_FLAG so its spelling lives with the other boolean flags the gate admits. */
229
301
  export const DRY_RUN_FLAG = { names: ["--dry-run"] };
230
- /** The `--last` flag spec for `tumwater tick <role> --last`: one definition of the flag's
231
- * spelling, beside JSON_FLAG, so tick's gate and cmdTick's arity guards cannot disagree on
302
+ /** The `--last` flag spec for `tumwater history <role> --last`: one definition of the flag's
303
+ * spelling, beside JSON_FLAG, so history's gate and cmdRunDetail's arity guards cannot disagree on
232
304
  * what the command admits. Like --json it takes no value and needs no wording — the
233
- * command body owns the meaning (resolve the newest completed tick instead of numbering
305
+ * command body owns the meaning (resolve the newest completed run instead of numbering
234
306
  * one) and the arity rules it implies. */
235
307
  export const LAST_FLAG = { names: ["--last"] };
236
308
  /** The `--grep <text>` flag spec shared by the two filtering views (logs, history): one
@@ -256,61 +328,94 @@ export function typeFlagSpec(missingValue) {
256
328
  export function resultFlagSpec(missingValue) {
257
329
  return { names: ["--result"], value: true, valueName: "<class>", missingValue };
258
330
  }
259
- /** `tumwater run`'s flag vocabulary: `--branch <name>` (the target branch, parsed by
260
- * parseBranchFlag), `--once` (one full round of ticks, then exit), `--role <id>`
261
- * (scope a --once round to one loop, parsed by parseRoleFlag), and `--gui` (also serve the
262
- * browser dashboard on its defaults; port/token selection stays on `tumwater gui`). Exported
331
+ /** `history --model <selector>[,...]`: keeps the runs that started on the listed models;
332
+ * `missingValue` is the same string the command body fails with. */
333
+ export function modelFlagSpec(missingValue) {
334
+ return { names: ["--model"], value: true, valueName: "<selector>", missingValue };
335
+ }
336
+ /** `history --by <role|model>`: how `--summary` groups its lines; `missingValue` is the same
337
+ * string the command body fails with. */
338
+ export function byFlagSpec(missingValue) {
339
+ return { names: ["--by"], value: true, valueName: "<role|model>", missingValue };
340
+ }
341
+ /** `tumwater gui`'s `--port <n>` flag: the dashboard port, shape-checked by parsePortFlag so
342
+ * `gui --port abc` and `start --gui --port abc` are named before the ready-repo gate can mask
343
+ * them. Shared by `gui` and `start --gui` (START_FLAG_SPECS) so the shape check and the
344
+ * valid-flags error rendering cannot drift between the two commands. */
345
+ const PORT_FLAG = {
346
+ names: ["--port"],
347
+ value: true,
348
+ valueName: "<n>",
349
+ validate: (value) => {
350
+ parsePortFlag(value);
351
+ },
352
+ };
353
+ /** The one refusal for a trailing `gui --token` with no value, phrased for what the
354
+ * flag actually needs — the spec's missingValue (so the gate's early report says it)
355
+ * and cmdGui's own re-check share this one wording. Declared above START_FLAG_SPECS
356
+ * (whose TOKEN_FLAG references it at module load), not between the two spec arrays. */
357
+ export const TOKEN_VALUE_ERROR = "--token requires a non-empty secret (e.g. `--token s3cret`)";
358
+ /** `tumwater gui`'s `--all-interfaces` flag: serve the dashboard on every network
359
+ * interface instead of loopback, exposing it to the LAN. Value-less. Shared by `gui` and
360
+ * `start --gui` (START_FLAG_SPECS) so the accepted vocabulary cannot drift between the
361
+ * two commands. */
362
+ const ALL_INTERFACES_FLAG = { names: ["--all-interfaces"] };
363
+ /** `tumwater gui`'s `--token <secret>` flag: the dashboard auth token, the gate behind
364
+ * which the dashboard sits when the operator protects it. Shared by `gui` and
365
+ * `start --gui` (START_FLAG_SPECS); its missing-value wording is TOKEN_VALUE_ERROR, the
366
+ * same error cmdGui and cmdStart's tokenValueProblem re-check fail with. */
367
+ const TOKEN_FLAG = {
368
+ names: ["--token"],
369
+ value: true,
370
+ valueName: "<secret>",
371
+ missingValue: TOKEN_VALUE_ERROR,
372
+ };
373
+ /** `tumwater start`'s flag vocabulary: `--branch <name>` (the target branch, parsed by
374
+ * parseBranchFlag), `--once` (one full round of runs, then exit), `--json` (with `--once`, print
375
+ * the round's outcomes as one JSON document), `--role <id>`
376
+ * (scope a --once round to one role, parsed by parseRoleFlag), `--gui` (also serve the browser
377
+ * dashboard), and `--port <n>`, `--all-interfaces` and `--token <secret>` (forwarded onto the
378
+ * dashboard child, shared with `tumwater gui`). Exported
263
379
  * so the caller's rejectUnknownArgs check and its tests share one definition of what `start`
264
380
  * (and its hidden alias `run`) accepts — before this vocabulary existed, run parsed --branch
265
381
  * and silently ignored every other flag, so a typo'd option ran the daemon with default
266
382
  * behavior. */
267
- export const RUN_FLAG_SPECS = [
383
+ export const START_FLAG_SPECS = [
268
384
  { names: ["--branch"], value: true, valueName: "<name>", missingValue: BRANCH_VALUE_ERROR },
269
385
  { names: ["--once"] },
386
+ JSON_FLAG,
270
387
  // `run --gui` is the one-command form of the dashboard: it boots the team and serves the
271
- // browser dashboard at its defaults, loopback on port 7180. The dashboard's own --port,
272
- // --all-interfaces, and --token stay on `tumwater gui`; widening them here would mean two
273
- // flag vocabularies to keep in step. `run --gui --once` is refused in cmdRun beside the
274
- // timer it arms.
388
+ // browser dashboard on its defaults, loopback on port 7180. `--port <n>` (shared with `tumwater
389
+ // gui` via PORT_FLAG) picks another port, and `--all-interfaces`/`--token <secret>` (shared
390
+ // with `tumwater gui` via ALL_INTERFACES_FLAG/TOKEN_FLAG) forward onto the dashboard child
391
+ // exactly as a direct `tumwater gui` would serve them. `run --gui --once` and any of the
392
+ // three dashboard-only flags without `--gui` are refused in cmdStart beside the timer it arms.
275
393
  { names: ["--gui"] },
394
+ PORT_FLAG,
395
+ ALL_INTERFACES_FLAG,
396
+ TOKEN_FLAG,
276
397
  // `run --tui` is the one-command form of the observer TUI: it boots the team and hosts the
277
398
  // same in-terminal TUI `tumwater tui` attaches from another terminal. Its flag vocabulary
278
- // stays at run's (`tumwater tui` takes no flags); `run --tui --once` is refused in cmdRun
399
+ // stays at run's (`tumwater tui` takes no flags); `run --tui --once` is refused in cmdStart
279
400
  // beside the `--gui` rival.
280
401
  { names: ["--tui"] },
281
402
  // `run --for <duration>` (the windowed run): the same spec `pause --for` passes, so the
282
403
  // gate's accepted vocabulary and parseDurationFlag's error wording cannot drift; the
283
404
  // 90-day cap is the spec's own validate (shared with pause), and the --once rival rule
284
- // stays in cmdRun beside the timer it arms.
405
+ // stays in cmdStart beside the timer it arms.
285
406
  durationFlagSpec("start --for"),
286
407
  ROLE_FLAG,
287
408
  ];
288
- /** The one refusal for a trailing `gui --token` with no value, phrased for what the
289
- * flag actually needs — the spec's missingValue (so the gate's early report says it)
290
- * and cmdGui's own re-check share this one wording. */
291
- export const TOKEN_VALUE_ERROR = "--token requires a non-empty secret (e.g. `--token s3cret`)";
292
- /** `tumwater gui`'s flag vocabulary: `--port <n>` (the dashboard port, shape-checked by
293
- * parsePortFlag so `gui --port abc` is named before the ready-repo gate can mask it),
294
- * `--all-interfaces`, and `--token <secret>` (the dashboard auth token). Exported so
295
- * cli.ts's rejectUnknownArgs check and its tests share one definition of what `gui`
296
- * accepts, like every other command's spec in this module; cmdGui re-runs parsePortFlag
297
- * and the token emptiness check on the accepted args, so the gate and the body cannot
298
- * drift apart. */
299
- export const GUI_FLAG_SPECS = [
300
- {
301
- names: ["--port"],
302
- value: true,
303
- valueName: "<n>",
304
- validate: (value) => {
305
- parsePortFlag(value);
306
- },
307
- },
308
- { names: ["--all-interfaces"] },
309
- { names: ["--token"], value: true, valueName: "<secret>", missingValue: TOKEN_VALUE_ERROR },
310
- ];
409
+ /** `tumwater gui`'s flag vocabulary: `--port <n>` (the dashboard port), `--all-interfaces`,
410
+ * and `--token <secret>` (the dashboard auth token), each shared with `start --gui` via the
411
+ * same module const so the accepted vocabulary cannot drift between the two commands.
412
+ * Exported so cli.ts's rejectUnknownArgs check and its tests share one definition of what
413
+ * `gui` accepts, like every other command's spec in this module; cmdGui re-runs parsePortFlag
414
+ * and the token value check on the accepted args, so the gate and the body cannot drift apart. */
415
+ export const GUI_FLAG_SPECS = [PORT_FLAG, ALL_INTERFACES_FLAG, TOKEN_FLAG];
311
416
  /** Fail when any argument was not consumed by this command's known flags — a misspelled flag
312
417
  * (e.g. `--rol` instead of `--role`) would otherwise be silently ignored and the command runs with
313
- * default behavior, which is worse than an error: `reset-counters --rol x` zeroed every loop
418
+ * default behavior, which is worse than an error: `reset-counters --rol x` zeroed every role
314
419
  * instead of one, and `gui --portt 8080` served on the default port. Valueless flags claim one
315
420
  * token; valued flags claim two — and a valued flag left without its value fails right here, with
316
421
  * the spec's missingValue wording: cli.ts runs this gate before the ready-repo gate and the command
@@ -0,0 +1,51 @@
1
+ /** `tumwater init`'s implementation (src/init/init.ts does the work; this prints the report).
2
+ * Split out of cli/cli-start.ts, whose name is for start alone: every command it dispatches
3
+ * delegates to its own module (operator/operator-commands.ts, config-commands.ts, log-commands.ts,
4
+ * doctor.ts, …), and init is no exception. cli.ts stays the pure dispatcher. */
5
+ import { say } from "./cli-output.js";
6
+ import { parseInitArgs } from "./cli-command-args.js";
7
+ import { initProject } from "../init/init.js";
8
+ import { templateCatalog } from "../init/init-templates.js";
9
+ /** `tumwater init`: seed a project directory from the operator's brief (src/init/init.ts does the
10
+ * work; this prints the report). --dry-run prints the would-be actions without writing
11
+ * anything; an already-initialized repo is reported as a no-op, never an error. */
12
+ export async function cmdInit(root, args) {
13
+ const { prompt, branch, template, listTemplates, adopt, dryRun } = parseInitArgs(args);
14
+ if (listTemplates) {
15
+ for (const { id, description } of templateCatalog())
16
+ say(`${id} — ${description}`);
17
+ return;
18
+ }
19
+ const result = await initProject(root, prompt, branch ?? undefined, {
20
+ adopt,
21
+ dryRun,
22
+ template: template ?? undefined,
23
+ });
24
+ if (result.template !== "blank")
25
+ say(`template: ${result.template}`);
26
+ if (result.adopted) {
27
+ say(`${result.dryRun ? "would adopt" : "adopting"} an existing repo: the project brief goes in TUMWATER.md and README.md is left untouched`);
28
+ }
29
+ if (result.dryRun) {
30
+ if (result.repoInitialized && result.branch) {
31
+ say(`dry run — would initialize a new git repository on branch ${result.branch}`);
32
+ }
33
+ const list = (names) => (names.length > 0 ? names.join(", ") : "nothing");
34
+ say(`dry run — would create: ${list(result.created)}`);
35
+ say(`would leave alone: ${list(result.leftAlone)}`);
36
+ say("nothing written; re-run without --dry-run to apply");
37
+ return;
38
+ }
39
+ if (result.created.length === 0) {
40
+ say("already initialized; nothing to do");
41
+ return;
42
+ }
43
+ if (result.repoInitialized && result.branch) {
44
+ say(`initialized a new git repository on branch ${result.branch}`);
45
+ }
46
+ say(`created ${result.created.join(", ")}${result.committed ? " (committed)" : ""}`);
47
+ if (result.bootstrap !== null) {
48
+ say(`fresh project — maintenance roles wait until ${result.bootstrap} plans are done; remove "bootstrap" from tumwater.json to end that early`);
49
+ }
50
+ say("next: `tumwater start` in one terminal, `tumwater tui` in another");
51
+ }
@@ -25,9 +25,9 @@ export async function runMarkerCommand(root, command, args) {
25
25
  // `pause` alone accepts `--for <duration>` (the timed pause) and `--reason <text>` (the
26
26
  // operator pause's why); `wake` alone accepts `--in <duration>` (the scheduled wake) and
27
27
  // `--cancel` (drop the pending scheduled wakes), `--list` (show them), and `--json`
28
- // (with --list); `reclaim` alone accepts `--dry-run`; the other marker commands keep the
29
- // plain --role vocabulary, so a stray --for, --reason, --in, --cancel, or --dry-run fails
30
- // fast instead of being silently ignored.
28
+ // (with --list); `reclaim` alone accepts `--dry-run` (and `--json` with it); the other
29
+ // marker commands keep the plain --role vocabulary, so a stray --for, --reason, --in,
30
+ // --cancel, or --dry-run fails fast instead of being silently ignored.
31
31
  const perCommandFlags = {
32
32
  "reset-counters": [ROLE_FLAG],
33
33
  wake: [ROLE_FLAG, WAKE_IN_FLAG, WAKE_CANCEL_FLAG, WAKE_LIST_FLAG, JSON_FLAG],
@@ -38,7 +38,7 @@ export async function runMarkerCommand(root, command, args) {
38
38
  REASON_FLAG,
39
39
  ],
40
40
  resume: [ROLE_FLAG],
41
- reclaim: [DRY_RUN_FLAG],
41
+ reclaim: [DRY_RUN_FLAG, JSON_FLAG],
42
42
  restart: [],
43
43
  };
44
44
  rejectUnknownArgs(command, args, perCommandFlags[command] ?? [ROLE_FLAG]);