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
@@ -1,8 +1,9 @@
1
+ // vocabulary: plain
1
2
  /** The browser-side dashboard app inlined as the GUI page's only <script>. It polls /api/status
2
- * every second and renders, in the order an operator needs them: the masthead's fleet status
3
- * (running, build, main check) and fleet controls (budget, pause); alerts for whatever needs a
3
+ * every second and renders, in the order an operator needs them: the masthead's team status
4
+ * (running, build, main check) and team controls (budget, pause); alerts for whatever needs a
4
5
  * human (a failing loop, a red main, a spent budget, an old build, open questions, a pause);
5
- * the composer that steers the director or one loop; and the fleet view — today's progress,
6
+ * the composer that steers the director or one loop; and the team view — today's progress,
6
7
  * the loops grouped by what they are doing, the backlog, and the notable activity. The
7
8
  * view-model, the drawer, the History/Usage/Failures/Pending views, the operator controls, the
8
9
  * composer, the Markdown renderer, and the routing/poll boot live in their own modules and
@@ -13,8 +14,9 @@
13
14
  import { GUI_CLIENT_BOOT_JS } from "./gui-client-boot.js";
14
15
  import { GUI_CLIENT_COMPOSER_JS } from "./gui-client-composer.js";
15
16
  import { GUI_CLIENT_DRAWER_JS } from "./gui-client-drawer.js";
16
- import { GUI_CLIENT_FLEET_JS } from "./gui-client-fleet.js";
17
+ import { GUI_CLIENT_TEAM_JS } from "./gui-client-team.js";
17
18
  import { GUI_CLIENT_HISTORY_JS } from "./gui-client-history.js";
19
+ import { GUI_CLIENT_LABELS_JS } from "./gui-client-labels.js";
18
20
  import { GUI_CLIENT_LOOPS_JS } from "./gui-client-loops.js";
19
21
  import { GUI_CLIENT_MARKDOWN_JS } from "./gui-client-markdown.js";
20
22
  import { GUI_CLIENT_MODEL_JS } from "./gui-client-model.js";
@@ -101,13 +103,13 @@ const CORE_JS = String.raw ` const esc = (s) => String(s).replace(/[&<>"']/g, (
101
103
  }
102
104
  // post-action:start
103
105
  // Fire one POST and report its outcome in the flash bar, then close any open popover and
104
- // repaint: on success the message — a string, or the derived form the fleet callers build
106
+ // repaint: on success the message — a string, or the derived form the team callers build
105
107
  // from the endpoint's answer (which can be null when it sent no JSON) — on failure
106
108
  // "error: <reason>" with the popover left open and the standing 1s status poll repainting
107
- // from the server's state. The one POST-and-toast step every fleet and operator control
109
+ // from the server's state. The one POST-and-toast step every team and operator control
108
110
  // shares. Single-homed here, in the core before every splice: a second declaration in a
109
111
  // later splice would shadow this one (function declarations hoist; the last in one scope
110
- // wins), which is how the budget editor once called the fleet shape with a string message.
112
+ // wins), which is how the budget editor once called the team shape with a string message.
111
113
  async function postAction(path, body, okMsg) {
112
114
  let d;
113
115
  try {
@@ -134,15 +136,15 @@ const FORMAT_JS = String.raw ` // format:start
134
136
  // A cap: whole dollars stay bare ($15), fractional ones keep their cents — format.ts's usdCap.
135
137
  const fmtCap = (n) => "$" + n.toFixed(2).replace(/\.00$/, "");
136
138
  // The number-agreeing word form when the count prints elsewhere in the markup — phrases.ts's
137
- // agree, shared by plural below and gui-client-fleet.ts's stats tiles, whose noun sits in
139
+ // agree, shared by plural below and gui-client-team.ts's stats tiles, whose noun sits in
138
140
  // <small>.
139
141
  const agree = (n, one, many) => (n === 1 ? one : many);
140
142
  const plural = (n, one, many) => n + " " + agree(n, one, many || one + "s");
141
- // The landed-commit work/maintenance split the sidebar's "Landed today" tile and the report's
142
- // "Commits landed" tile both print. report-data.ts leaves the counts optional, so a missing
143
+ // The merged-commit work/maintenance split the sidebar's "Merged today" tile and the report's
144
+ // "Commits merged" tile both print. report-data.ts leaves the counts optional, so a missing
143
145
  // count reads 0 here rather than "undefined".
144
146
  const workSplit = (t) => (t.workCommits ?? 0) + " work / " + (t.maintenanceCommits ?? 0) + " maintenance";
145
- // The unlanded-commit list both change views paint — each commit's sha and subject on its
147
+ // The unmerged-commit list both change views paint — each commit's sha and subject on its
146
148
  // own clamped line. The Pending roster's Ahead cell and the loop drawer's Pending change
147
149
  // section had the byte-identical map; a missing or non-array list paints nothing.
148
150
  const commitRowsHtml = (commits) =>
@@ -194,20 +196,20 @@ const FORMAT_JS = String.raw ` // format:start
194
196
  // last-tick-fmt:end
195
197
  // next-run-fmt:start
196
198
  // When an idle loop may tick again — status-render.ts's nextRunCell: "-" for a loop in flight
197
- // or parked awaiting a slot (it has no next run to speak of) and for a stopped fleet; "now"
199
+ // or parked awaiting a slot (it has no next run to speak of) and for a stopped team; "now"
198
200
  // when due; otherwise the remaining time, prefixed "backoff " while backing off. A yield-scaled
199
201
  // clock rides as a " ×N" suffix: a quiet role's effective gap is longer than the countdown.
200
- const fmtNextRun = (l, fleetRunning) => {
202
+ const fmtNextRun = (l, teamRunning) => {
201
203
  // A torn loop object — a payload missing its phase field — reads as the empty (inactive)
202
204
  // phase rather than throwing: the browser copy is untyped, and its sibling phaseInfo/
203
205
  // loopRank already coerce the same way, so one bad row must not blank the whole table.
204
206
  const phase = String(l.phase || "");
205
- const active = isActivePhase(phase) || phase.startsWith("awaiting slot") || phase.startsWith("director working");
206
- if (!fleetRunning || active) return "-";
207
+ const active = isActivePhase(phase) || phase.startsWith("waiting to start") || phase.startsWith("waiting for ") || phase.startsWith("director working");
208
+ if (!teamRunning || active) return "-";
207
209
  const sec = Math.round((l.nextRunAt - Date.now()) / 1000);
208
210
  const suffix = l.yieldMultiplier > 1 ? " ×" + l.yieldMultiplier : "";
209
211
  if (sec <= 0) return "now" + suffix;
210
- return (l.backoffSeconds > 0 ? "backoff " : "") + humanSeconds(sec) + suffix;
212
+ return (l.backoffSeconds > 0 ? "sleeping " : "") + humanSeconds(sec) + suffix;
211
213
  };
212
214
  // next-run-fmt:end
213
215
  // A relative age for lists; the first minute reads "just now" so rows do not churn every
@@ -227,6 +229,10 @@ const FORMAT_JS = String.raw ` // format:start
227
229
  if (min < 120) return min + "m";
228
230
  return (ms / 3600000).toFixed(1) + "h";
229
231
  };
232
+ // A run's wall-clock span cell: fmtSpan when a row carries a duration, a dash when it does not
233
+ // (a tick whose start sits outside the window). Shared by the History table and summary rows
234
+ // (and any future duration cell) so the null rule and its em-dash cannot drift between them.
235
+ const durCell = (ms) => (ms === null || ms === undefined ? "—" : esc(fmtSpan(Number(ms))));
230
236
  // Server text sometimes carries ISO instants (a restart cooldown's deadline); show them in
231
237
  // the viewer's local time.
232
238
  const localizeInstants = (s) => String(s).replace(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z/g, (iso) => fmtClock(Date.parse(iso)));
@@ -248,7 +254,7 @@ const DOM_JS = String.raw ` const ICONS = ${JSON.stringify(ICON_PATHS)};
248
254
  if (t) fn(t, ev);
249
255
  });
250
256
  }
251
- // The Element a delegated click landed on, narrowed by closest(selector): null when the
257
+ // The Element a delegated click merged on, narrowed by closest(selector): null when the
252
258
  // click's target is not an Element (a text node, say) or nothing matches. One home for the
253
259
  // instanceof-Element guard every per-element delegated handler on the page needs before it
254
260
  // can read ev.target (the same pitfall onClick guards for document-level handlers), so the
@@ -259,7 +265,7 @@ const DOM_JS = String.raw ` const ICONS = ${JSON.stringify(ICON_PATHS)};
259
265
  }
260
266
  // click-delegate:end
261
267
  const pill = (info) => "<span class='pill t-" + info.tone + "'><span class='dot" + (info.live ? " live" : "") + "'></span>" + esc(info.label) + "</span>";
262
- // Repaint a panel only when its markup changed: an idle fleet's payload is identical poll
268
+ // Repaint a panel only when its markup changed: an idle team's payload is identical poll
263
269
  // after poll, and rewriting identical HTML re-parses it, churns layout, and drops the
264
270
  // reader's text selection for nothing. Returns true when it repainted.
265
271
  const lastPaint = {};
@@ -341,7 +347,7 @@ const DOM_JS = String.raw ` const ICONS = ${JSON.stringify(ICON_PATHS)};
341
347
  let lastStatus = null;
342
348
  let serverBuildSha = null;
343
349
  let offline = false;
344
- let activeView = "fleet";
350
+ let activeView = "team";
345
351
  `;
346
- export const GUI_CLIENT_JS = [CORE_JS, FORMAT_JS, GUI_CLIENT_MODEL_JS, DOM_JS, GUI_CLIENT_MARKDOWN_JS, GUI_CLIENT_SOUND_JS, GUI_CLIENT_OPERATOR_JS, GUI_CLIENT_LOOPS_JS, GUI_CLIENT_FLEET_JS, GUI_CLIENT_COMPOSER_JS,
352
+ export const GUI_CLIENT_JS = [CORE_JS, FORMAT_JS, GUI_CLIENT_LABELS_JS, GUI_CLIENT_MODEL_JS, DOM_JS, GUI_CLIENT_MARKDOWN_JS, GUI_CLIENT_SOUND_JS, GUI_CLIENT_OPERATOR_JS, GUI_CLIENT_LOOPS_JS, GUI_CLIENT_TEAM_JS, GUI_CLIENT_COMPOSER_JS,
347
353
  GUI_CLIENT_DRAWER_JS, GUI_CLIENT_HISTORY_JS, GUI_CLIENT_PENDING_JS, GUI_CLIENT_REPORT_JS, GUI_CLIENT_SETTINGS_JS, GUI_CLIENT_BOOT_JS].join("\n");
@@ -1,10 +1,10 @@
1
1
  /** The dashboard page shell served at `/` by `tumwater gui`: the markup of the zero-dependency
2
2
  * single-file app, with its stylesheet (gui-styles.ts) and browser logic (gui-client.ts)
3
- * inlined. The shell is a sidebar beside a main column. The sidebar is the fleet's frame on
4
- * every view: which project this is and whether its fleet is up (build, main check), the
5
- * views — Fleet's carrying a badge while something needs a human — and the fleet-wide
3
+ * inlined. The shell is a sidebar beside a main column. The sidebar is the team's frame on
4
+ * every view: which project this is and whether its team is up (build, main check), the
5
+ * views — Team's carrying a badge while something needs a human — and the team-wide
6
6
  * controls: today's spend against the cap, and pause. The main column shows one view at a
7
- * time: Fleet (alerts for whatever needs a human, the composer that steers the director or
7
+ * time: Team (alerts for whatever needs a human, the composer that steers the director or
8
8
  * one loop, today's progress, every loop grouped by what it is doing, the backlog, and the
9
9
  * notable activity), History, Usage, Failures, Pending, or Settings. A drawer opens any
10
10
  * loop's detail and live transcript, or any backlog entry in full. Kept apart from
@@ -26,9 +26,9 @@ export const GUI_PAGE = `<!doctype html>
26
26
  <body>
27
27
  <a class="skip" href="#main">Skip to content</a>
28
28
  <div class="shell">
29
- <aside class="sidebar" aria-label="Fleet">
29
+ <aside class="sidebar" aria-label="Team">
30
30
  <div class="side-top">
31
- <a class="brand" href="#fleet" aria-label="tumwater fleet">${LOGO_SVG}<span>tumwater</span></a>
31
+ <a class="brand" href="#team" aria-label="tumwater team">${LOGO_SVG}<span>tumwater</span></a>
32
32
  <div class="side-top-actions">
33
33
  <span id="soundwrap"></span>
34
34
  <button type="button" class="icon-btn" id="themetoggle" title="Switch between light and dark" aria-label="Switch between light and dark">${iconSvg("sun", "theme-sun")}${iconSvg("moon", "theme-moon")}</button>
@@ -40,7 +40,7 @@ export const GUI_PAGE = `<!doctype html>
40
40
  <div class="side-status" id="statuschips" aria-live="polite"></div>
41
41
  </div>
42
42
  <nav class="side-nav" id="viewnav" aria-label="Views">
43
- <a href="#fleet" id="tab-fleet" class="tab active" aria-current="page">${iconSvg("grid")}<span>Fleet</span><span class="badge t-red" id="navbadge" hidden></span></a>
43
+ <a href="#team" id="tab-team" class="tab active" aria-current="page">${iconSvg("grid")}<span>Team</span><span class="badge t-red" id="navbadge" hidden></span></a>
44
44
  <a href="#history" id="tab-history" class="tab">${iconSvg("list")}<span>History</span></a>
45
45
  <a href="#usage" id="tab-usage" class="tab">${iconSvg("bars")}<span>Usage</span></a>
46
46
  <a href="#failures" id="tab-failures" class="tab">${iconSvg("alert")}<span>Failures</span></a>
@@ -50,24 +50,24 @@ export const GUI_PAGE = `<!doctype html>
50
50
  <div class="side-controls">
51
51
  <div class="menu-anchor up" id="budgetwrap"></div>
52
52
  <div class="menu-anchor up" id="pausewrap"></div>
53
+ <div class="menu-anchor up" id="stopwrap"></div>
53
54
  </div>
54
55
  </aside>
55
56
  <main id="main" class="main">
56
- <section id="fleet-view" class="view" aria-labelledby="fleet-title">
57
+ <section id="team-view" class="view" aria-labelledby="team-title">
57
58
  <div class="view-head">
58
- <div><h1 id="fleet-title">Fleet</h1><p id="fleetsub">&nbsp;</p></div>
59
+ <div><h1 id="team-title">Team</h1><p id="teamsub">&nbsp;</p></div>
59
60
  </div>
60
61
  <div id="alerts" class="alerts" aria-live="polite"></div>
61
62
  <form id="promptform" class="composer" autocomplete="off">
62
63
  <div class="composer-row">
63
64
  <label class="composer-target"><span class="sr-only">Send to</span><select id="prompttarget" class="field"><option value="director">Director</option></select></label>
64
- <textarea id="prompt" rows="1" placeholder="Tell the fleet what to do next…" aria-label="Prompt"></textarea>
65
+ <textarea id="prompt" rows="1" placeholder="Tell the team what to do next…" aria-label="Prompt"></textarea>
65
66
  <button type="submit" class="btn btn-primary" id="promptsend" title="Send (Enter)">${iconSvg("send")}<span>Send</span></button>
66
67
  </div>
67
68
  <div id="promptimages" class="chips" hidden></div>
69
+ <div id="promptimagenote" class="composer-note" hidden></div>
68
70
  <div class="composer-foot">
69
- <label class="sr-only" for="promptdefer">Defer until</label>
70
- <input class="field" id="promptdefer" type="text" placeholder="defer (45m)" autocomplete="off">
71
71
  <span id="prompthint"></span>
72
72
  <span class="composer-meta"><span id="promptcount"></span><a href="#" id="queuelink" hidden></a></span>
73
73
  </div>
@@ -75,16 +75,16 @@ export const GUI_PAGE = `<!doctype html>
75
75
  <div id="stats" class="stats"></div>
76
76
  <section class="card" aria-labelledby="loops-title">
77
77
  <header class="card-head">
78
- <h2 id="loops-title">Loops</h2>
78
+ <h2 id="loops-title">Roles</h2>
79
79
  <div class="spacer"></div>
80
- <button type="button" class="btn btn-sm" id="resetall" title="Zero every loop's ticks, commits, tokens, and cost — scheduling is untouched">${iconSvg("refresh")}<span>Reset counters</span></button>
81
- <div class="menu-anchor" id="wakelaterwrap"><button type="button" class="btn btn-sm" id="wakelater" aria-haspopup="menu" title="Wake every loop later">${iconSvg("clock")}<span>Wake later</span></button></div>
82
- <button type="button" class="btn btn-sm" id="wakeall" title="Wake every loop now, skipping any sleep or backoff">${iconSvg("bolt")}<span>Wake all</span></button>
80
+ <button type="button" class="btn btn-sm" id="resetall" title="Zero every role's runs, commits, tokens, and cost — scheduling is untouched">${iconSvg("refresh")}<span>Reset counters</span></button>
81
+ <div class="menu-anchor" id="wakelaterwrap"><button type="button" class="btn btn-sm" id="wakelater" aria-haspopup="menu" title="Wake every role later">${iconSvg("clock")}<span>Wake later</span></button></div>
82
+ <button type="button" class="btn btn-sm" id="wakeall" title="Wake every role now, skipping any sleep">${iconSvg("bolt")}<span>Wake all</span></button>
83
83
  </header>
84
84
  <div class="table-wrap">
85
85
  <table class="table loops" id="loopstable">
86
- <thead><tr><th class="c-loop">Loop</th><th class="c-status">Status</th><th class="c-activity">Now, or the last result</th><th class="c-today num">Spent today</th><th class="c-actions"><span class="sr-only">Actions</span></th></tr></thead>
87
- <tbody id="loops"></tbody>
86
+ <thead><tr><th class="c-loop">Role</th><th class="c-status">Status</th><th class="c-activity">Now, or the last result</th><th class="c-today num">Spent today</th><th class="c-actions"><span class="sr-only">Actions</span></th></tr></thead>
87
+ <tbody id="rolerows"></tbody>
88
88
  </table>
89
89
  </div>
90
90
  </section>
@@ -104,7 +104,7 @@ export const GUI_PAGE = `<!doctype html>
104
104
  <div class="seg" id="feedfilter" role="tablist" aria-label="Activity filter">
105
105
  <button type="button" data-filter="notable" class="active">Notable</button><button type="button" data-filter="all">All events</button>
106
106
  </div>
107
- <label><span class="sr-only">Loop</span><select class="field" id="feedrole"><option value="">All loops</option></select></label>
107
+ <label><span class="sr-only">Role</span><select class="field" id="feedrole"><option value="">All roles</option></select></label>
108
108
  <label><span class="sr-only">Search</span><input class="field" id="feedgrep" type="search" placeholder="Search activity…" autocomplete="off"></label>
109
109
  </header>
110
110
  <ol id="feed" class="feed"></ol>
@@ -2,7 +2,7 @@
2
2
  * A small neutral design system of tumwater's own: the platform's UI and monospace fonts, a
3
3
  * neutral gray scale, flat surfaces with hairline borders, and one accent — teal, for water —
4
4
  * for the primary action, links, focus, and progress. Status reads through a fixed set of
5
- * tones (blue working, violet reviewing, orange landing, green landed, amber held, red broken,
5
+ * tones (blue working, violet reviewing, orange merge, green merged, amber held, red broken,
6
6
  * gray idle) that every chip, pill, and alert shares. Every color is a token on :root,
7
7
  * redefined for dark mode both for the OS preference (unless the viewer chose light) and for
8
8
  * an explicit `data-theme="dark"`, so the page follows the system until the theme toggle
@@ -113,7 +113,7 @@ export const GUI_STYLES = String.raw `
113
113
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
114
114
  .spacer { flex: 1; }
115
115
 
116
- /* ---- shell: the sidebar (project, fleet status, views, fleet controls) beside the main
116
+ /* ---- shell: the sidebar (project, team status, views, team controls) beside the main
117
117
  column ---- */
118
118
  .shell { display: grid; grid-template-columns: 248px minmax(0, 1fr); min-height: 100vh; }
119
119
  .sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; gap: 18px; padding: 16px 12px;
@@ -262,6 +262,7 @@ export const GUI_STYLES = String.raw `
262
262
  .composer .btn-primary { height: 34px; }
263
263
  .composer.dragover { border-color: var(--primary); background: var(--accent-bg); }
264
264
  #promptimages { padding: 6px 4px 0; }
265
+ #promptimagenote { padding: 0 4px 6px; font-size: 12px; color: var(--text-3); }
265
266
  #promptimages .chip { font-size: 12px; }
266
267
  #promptimages .chip .dim { color: var(--text-3); }
267
268
  #promptimages .chip button { border: 0; background: none; color: var(--text-3); cursor: pointer; font-size: 14px;
@@ -285,7 +286,7 @@ export const GUI_STYLES = String.raw `
285
286
  .stat-value { display: block; margin-top: 4px; font-size: 24px; line-height: 1.2; font-weight: 650; letter-spacing: -0.02em;
286
287
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
287
288
  .stat-value small { font-size: 13.5px; font-weight: 500; letter-spacing: 0; color: var(--text-3); }
288
- .stat-sub { display: block; margin-top: 2px; font-size: 12.5px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
289
+ .stat-sub { display: block; margin-top: 2px; font-size: 12.5px; line-height: 1.4; min-height: calc(2 * 1.4em); color: var(--text-3); }
289
290
  .meter { display: block; height: 5px; margin-top: 9px; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
290
291
  .meter > span { display: block; height: 100%; border-radius: inherit; background: var(--primary); }
291
292
  .meter.t-red > span, .meter.t-amber > span { background: var(--t); }
@@ -357,6 +358,9 @@ export const GUI_STYLES = String.raw `
357
358
  .list-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 16px; border-bottom: 1px solid var(--line-soft); }
358
359
  .list-item:last-child { border-bottom: 0; }
359
360
  .list-item:hover { background: var(--surface-2); }
361
+ .list-divider { padding: 6px 16px; background: var(--surface-2); }
362
+ .list-divider:hover { background: var(--surface-2); }
363
+ .list-series .li-title { font-weight: 600; }
360
364
  .list-item.active { background: var(--accent-bg); }
361
365
  .li-icon { color: var(--t, var(--text-4)); padding-top: 2px; }
362
366
  .li-open { flex: 1; min-width: 0; display: block; padding: 0; border: 0; background: none; text-align: left; cursor: pointer; }
@@ -378,6 +382,10 @@ export const GUI_STYLES = String.raw `
378
382
  .feed-item.k-routine .feed-msg { color: var(--text-3); }
379
383
  .feed-loop { font-family: var(--font-mono); font-size: 12.5px; font-weight: 600; color: var(--text); margin-right: 4px; }
380
384
  .feed-time { font-size: 12px; color: var(--text-4); white-space: nowrap; font-variant-numeric: tabular-nums; padding-top: 1px; }
385
+ .feed-tally { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 16px 6px; border-bottom: 1px solid var(--line-soft); }
386
+ .feed-tally .chip { height: 22px; padding: 0 9px; font-size: 12px; font-weight: 500; }
387
+ .feed-tally button.chip { cursor: pointer; }
388
+ .feed-tally .chip.active { border-color: var(--accent); background: var(--accent-bg); color: var(--text); }
381
389
 
382
390
  /* ---- drawer: a loop's detail and live transcript, or one backlog entry ---- */
383
391
  .drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: 50; width: min(660px, 100vw); display: flex;
@@ -494,7 +502,7 @@ export const GUI_STYLES = String.raw `
494
502
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
495
503
  table.loops .c-today { display: none; }
496
504
  .kv { grid-template-columns: repeat(2, minmax(0, 1fr)); }
497
- .history .c-usage, .history .c-dur { display: none; }
505
+ .history .c-usage, .history .c-dur, .history .c-model { display: none; }
498
506
  }
499
507
  @media (max-width: 680px) {
500
508
  .stats.six { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@@ -1,6 +1,8 @@
1
+ // vocabulary: plain
1
2
  import path from "node:path";
2
3
  import { applyToolExecutionEvent, parsePiEventLine, toolCallCommand, } from "../pi/pi-event-line.js";
3
4
  import { bufferedCommandStallMs, commandBuffersOutput } from "../pi/command-shape.js";
5
+ import { streamsToolOutput } from "../agent/backend-traits.js";
4
6
  import { describeToolCall } from "../text/phrases.js";
5
7
  import { squash } from "../text/text.js";
6
8
  import { defaultConfig, liveConfig } from "../config/config.js";
@@ -190,7 +192,7 @@ export function stalledToolLabel(open, now = Date.now(), stallMs = defaultConfig
190
192
  // claude never sends content-bearing tool updates, so silence is expected for every call
191
193
  // and only the wall-clock duration can show a hang (plans/agent-backends.md "Watchdogs and
192
194
  // progress"); pi keeps the per-command classification.
193
- if (agent === "claude" || commandBuffersOutput(call.command || call.label)) {
195
+ if (!streamsToolOutput(agent) || commandBuffersOutput(call.command || call.label)) {
194
196
  if (now - call.lastActivityAt >= bufferedCommandStallMs(stallMs))
195
197
  return call.label;
196
198
  continue;
@@ -204,7 +206,7 @@ export function stalledToolLabel(open, now = Date.now(), stallMs = defaultConfig
204
206
  * `tumwater_run` marker or a `session` event switches which accumulator following lines fold
205
207
  * into. A marker carries the run's kind, so a `session` preceded by one keeps that kind even
206
208
  * when author and gate runs share a worktree (part 1/5 of the worktree pool); only a session
207
- * no kind-bearing marker preceded falls back to the legacy `cwd` test (the lander worktree
209
+ * no kind-bearing marker preceded falls back to the legacy `cwd` test (the merge slot worktree
208
210
  * path = gate), which is how logs written before the marker carried a kind still demux. A
209
211
  * marker also starts that kind's accumulator fresh before the session lands, so a previous
210
212
  * run's turns/context can never show in the new run's cell. Everything else folds into the
@@ -227,7 +229,7 @@ function feedDemuxed(tail, line, gateCwd) {
227
229
  if (event.type === "tumwater_run") {
228
230
  const kind = event.kind === "gate" || event.kind === "author" ? event.kind : undefined;
229
231
  if (kind) {
230
- // Every run writes this marker before pi spawns, and the landing cell reads the
232
+ // Every run writes this marker before pi spawns, and the merge cell reads the
231
233
  // accumulator as soon as the marker's stage says `reviewing` — a poll that can land
232
234
  // before the session event. Resetting here means a previous run's turns/context (the
233
235
  // last review, or another run the gate spent) can never show in the new run's cell.