tumwater 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. package/README.md +27 -13
  2. package/dist/build-info.json +2 -2
  3. package/dist/src/agent/agent-args.js +8 -9
  4. package/dist/src/agent/agent-backend.js +8 -6
  5. package/dist/src/agent/backend-traits.js +55 -25
  6. package/dist/src/agent/claude/claude-account.js +71 -204
  7. package/dist/src/agent/claude/claude-args.js +9 -6
  8. package/dist/src/agent/claude/claude-backend.js +10 -10
  9. package/dist/src/agent/claude/claude-env.js +1 -1
  10. package/dist/src/agent/claude/claude-stream.js +6 -4
  11. package/dist/src/agent/claude/claude-write-guard.js +49 -0
  12. package/dist/src/agent/claude/write-guard-hook.js +13 -0
  13. package/dist/src/agent/codex/codex-account.js +119 -0
  14. package/dist/src/agent/codex/codex-args.js +181 -0
  15. package/dist/src/agent/codex/codex-backend.js +279 -0
  16. package/dist/src/agent/codex/codex-catalog.js +97 -0
  17. package/dist/src/agent/codex/codex-env.js +18 -0
  18. package/dist/src/agent/codex/codex-hook-trust.js +246 -0
  19. package/dist/src/agent/codex/codex-patch-paths.js +36 -0
  20. package/dist/src/agent/codex/codex-rollout.js +179 -0
  21. package/dist/src/agent/codex/codex-stream.js +404 -0
  22. package/dist/src/agent/codex/codex-write-guard.js +86 -0
  23. package/dist/src/agent/codex/write-guard-hook.js +12 -0
  24. package/dist/src/agent/image-input.js +29 -24
  25. package/dist/src/agent/notes-shim.js +11 -12
  26. package/dist/src/agent/opencode/opencode-args.js +0 -1
  27. package/dist/src/agent/opencode/opencode-backend.js +12 -9
  28. package/dist/src/agent/opencode/opencode-catalog.js +55 -29
  29. package/dist/src/agent/opencode/opencode-config.js +19 -14
  30. package/dist/src/agent/opencode/opencode-env.js +0 -1
  31. package/dist/src/agent/opencode/opencode-session-id.js +1 -2
  32. package/dist/src/agent/opencode/opencode-stream.js +1 -1
  33. package/dist/src/agent/opencode/write-guard-plugin/index.js +48 -0
  34. package/dist/src/agent/role-notes-write.js +5 -6
  35. package/dist/src/agent/run-agent.js +465 -448
  36. package/dist/src/agent/run-settle.js +214 -0
  37. package/dist/src/agent/session-ledger.js +86 -16
  38. package/dist/src/agent/subscription-account.js +220 -0
  39. package/dist/src/agent/write-guard.js +148 -0
  40. package/dist/src/backlog/backlog-archive.js +281 -55
  41. package/dist/src/backlog/backlog-cli-view.js +255 -0
  42. package/dist/src/backlog/backlog-cli.js +91 -335
  43. package/dist/src/backlog/backlog-commit.js +20 -13
  44. package/dist/src/backlog/backlog-eligibility.js +193 -242
  45. package/dist/src/backlog/backlog-index.js +149 -0
  46. package/dist/src/backlog/backlog-md.js +54 -6
  47. package/dist/src/backlog/backlog-parts.js +264 -0
  48. package/dist/src/backlog/backlog-release.js +134 -0
  49. package/dist/src/backlog/backlog-render.js +27 -0
  50. package/dist/src/backlog/backlog-structure.js +99 -156
  51. package/dist/src/backlog/backlog-write.js +40 -127
  52. package/dist/src/backlog/backlog.js +21 -6
  53. package/dist/src/backlog/question-answer.js +21 -15
  54. package/dist/src/baseline/main-baseline.js +89 -20
  55. package/dist/src/baseline/main-guardrails.js +136 -0
  56. package/dist/src/baseline/main-red.js +153 -36
  57. package/dist/src/baseline/main-watch.js +232 -0
  58. package/dist/src/brief/brief-edit.js +12 -12
  59. package/dist/src/brief/brief.js +31 -51
  60. package/dist/src/budget/budget-fallback-view.js +288 -0
  61. package/dist/src/budget/budget-wiring.js +158 -0
  62. package/dist/src/budget/budget.js +31 -20
  63. package/dist/src/budget/fallback-breaker.js +26 -27
  64. package/dist/src/build/build-check-detect.js +23 -15
  65. package/dist/src/build/build-check-events.js +25 -6
  66. package/dist/src/build/build-check-report.js +49 -9
  67. package/dist/src/build/build-check-scoped.js +18 -11
  68. package/dist/src/build/build-check.js +2 -1
  69. package/dist/src/build/build-info.js +2 -3
  70. package/dist/src/build/build-stage.js +9 -14
  71. package/dist/src/build/dep-install.js +65 -3
  72. package/dist/src/change/change-data.js +123 -31
  73. package/dist/src/change/change-render.js +46 -5
  74. package/dist/src/cli/brief-command.js +3 -4
  75. package/dist/src/cli/cli-args.js +181 -33
  76. package/dist/src/cli/cli-command-args.js +46 -18
  77. package/dist/src/cli/cli-editor.js +2 -1
  78. package/dist/src/cli/cli-flag-specs.js +183 -45
  79. package/dist/src/cli/cli-init.js +51 -0
  80. package/dist/src/cli/cli-marker-commands.js +4 -4
  81. package/dist/src/cli/cli-query-commands.js +291 -598
  82. package/dist/src/cli/cli-repo-gate.js +11 -1
  83. package/dist/src/cli/cli-review-commands.js +113 -0
  84. package/dist/src/cli/cli-role-command.js +525 -0
  85. package/dist/src/cli/cli-start-summary.js +167 -0
  86. package/dist/src/cli/{cli-run.js → cli-start.js} +193 -237
  87. package/dist/src/cli/completion.js +169 -22
  88. package/dist/src/cli/config-commands.js +58 -26
  89. package/dist/src/cli/follow-view.js +75 -0
  90. package/dist/src/cli/help.js +258 -82
  91. package/dist/src/cli/log-commands.js +164 -85
  92. package/dist/src/cli/question-commands.js +211 -10
  93. package/dist/src/cli.js +173 -45
  94. package/dist/src/collections.js +56 -13
  95. package/dist/src/concurrency/check-permit.js +20 -3
  96. package/dist/src/concurrency/lock.js +17 -13
  97. package/dist/src/concurrency/provider-lease.js +44 -8
  98. package/dist/src/concurrency/semaphore.js +102 -26
  99. package/dist/src/config/config-aliases.js +0 -1
  100. package/dist/src/config/config-editable-keys.js +16 -1
  101. package/dist/src/config/config-fallbacks.js +94 -56
  102. package/dist/src/config/config-field-checks.js +40 -10
  103. package/dist/src/config/config-keys.js +30 -8
  104. package/dist/src/config/config-live.js +63 -24
  105. package/dist/src/config/config-request.js +137 -0
  106. package/dist/src/config/config-schema.js +31 -24
  107. package/dist/src/config/config-selector-checks.js +123 -0
  108. package/dist/src/config/config-validation-agents.js +80 -0
  109. package/dist/src/config/config-validation-model.js +116 -0
  110. package/dist/src/config/config-validation.js +169 -222
  111. package/dist/src/config/config-views.js +136 -54
  112. package/dist/src/config/config-write-core.js +135 -0
  113. package/dist/src/config/config-write.js +164 -265
  114. package/dist/src/config/config.js +53 -38
  115. package/dist/src/config/model-selector.js +34 -34
  116. package/dist/src/doctor/doctor-backlog-bugs.js +330 -0
  117. package/dist/src/doctor/doctor-backlog-plans.js +398 -0
  118. package/dist/src/doctor/doctor-backlog.js +249 -512
  119. package/dist/src/doctor/doctor-check-names.js +85 -0
  120. package/dist/src/doctor/doctor-checks.js +61 -593
  121. package/dist/src/doctor/doctor-claude-checks.js +142 -0
  122. package/dist/src/doctor/doctor-codex-checks.js +276 -0
  123. package/dist/src/doctor/doctor-contention-checks.js +506 -0
  124. package/dist/src/doctor/doctor-fallback-checks.js +130 -0
  125. package/dist/src/doctor/doctor-holds.js +80 -66
  126. package/dist/src/doctor/doctor-install.js +2 -1
  127. package/dist/src/doctor/doctor-model-checks.js +216 -537
  128. package/dist/src/doctor/doctor-notify.js +9 -5
  129. package/dist/src/doctor/doctor-opencode-checks.js +164 -0
  130. package/dist/src/doctor/doctor-orphans.js +182 -63
  131. package/dist/src/doctor/doctor-pi-checks.js +62 -0
  132. package/dist/src/doctor/doctor-project-checks.js +397 -0
  133. package/dist/src/doctor/doctor.js +126 -77
  134. package/dist/src/doctor/image-probe.js +21 -8
  135. package/dist/src/doctor/outcome.js +3 -2
  136. package/dist/src/doctor/probe.js +21 -12
  137. package/dist/src/events/event-format.js +185 -89
  138. package/dist/src/events/event-labels.js +11 -5
  139. package/dist/src/events/event-legacy.js +39 -15
  140. package/dist/src/events/event-read.js +52 -39
  141. package/dist/src/events/event-tally.js +16 -0
  142. package/dist/src/events/event-window.js +80 -26
  143. package/dist/src/events/events.js +30 -13
  144. package/dist/src/events/notify.js +7 -7
  145. package/dist/src/failure/failure-cluster.js +12 -12
  146. package/dist/src/failure/failure-data.js +65 -60
  147. package/dist/src/failure/failure-render.js +29 -21
  148. package/dist/src/failure/failure-state-change.js +17 -12
  149. package/dist/src/failure/time-spend.js +35 -35
  150. package/dist/src/files/file-queue.js +17 -0
  151. package/dist/src/files/files.js +111 -35
  152. package/dist/src/files/json-files.js +3 -3
  153. package/dist/src/files/json-object.js +28 -7
  154. package/dist/src/files/stat-cache.js +2 -2
  155. package/dist/src/files/tail.js +1 -1
  156. package/dist/src/gates/bootstrap-gates.js +4 -5
  157. package/dist/src/gates/budget-gates.js +88 -225
  158. package/dist/src/gates/disk-gate.js +1 -1
  159. package/dist/src/gates/gate-polls.js +101 -143
  160. package/dist/src/gates/maintenance-quota.js +37 -30
  161. package/dist/src/gates/pause-gates.js +28 -10
  162. package/dist/src/gates/readiness.js +7 -3
  163. package/dist/src/gates/role-cap-gates.js +8 -8
  164. package/dist/src/gates/startup-gate.js +94 -32
  165. package/dist/src/gates/streak-gate.js +54 -30
  166. package/dist/src/git/commit-message.js +89 -46
  167. package/dist/src/git/git-diff.js +16 -10
  168. package/dist/src/git/git-run.js +79 -38
  169. package/dist/src/git/git.js +54 -34
  170. package/dist/src/git/slot-salvage.js +253 -0
  171. package/dist/src/git/slots-state.js +6 -6
  172. package/dist/src/git/worktree-pool.js +132 -38
  173. package/dist/src/git/worktree-use.js +4 -11
  174. package/dist/src/git/worktree.js +94 -37
  175. package/dist/src/gui/gui-admin-endpoints.js +96 -0
  176. package/dist/src/gui/gui-args.js +79 -8
  177. package/dist/src/gui/gui-backlog-commands.js +43 -19
  178. package/dist/src/gui/gui-backlog-endpoints.js +156 -0
  179. package/dist/src/gui/gui-command.js +26 -13
  180. package/dist/src/gui/gui-config-commands.js +168 -80
  181. package/dist/src/gui/gui-endpoint-commands.js +5 -4
  182. package/dist/src/gui/gui-endpoint-common.js +4 -4
  183. package/dist/src/gui/gui-endpoints.js +11 -380
  184. package/dist/src/gui/gui-history-endpoints.js +301 -0
  185. package/dist/src/gui/gui-operator-commands.js +235 -13
  186. package/dist/src/gui/gui-prompt-commands.js +26 -20
  187. package/dist/src/gui/gui-report-endpoints.js +97 -0
  188. package/dist/src/gui/gui-server.js +26 -5
  189. package/dist/src/gui/gui-team-commands.js +7 -7
  190. package/dist/src/gui/http-body.js +1 -1
  191. package/dist/src/history/history-data.js +122 -234
  192. package/dist/src/history/history-queued.js +155 -0
  193. package/dist/src/history/history-render.js +42 -22
  194. package/dist/src/history/history.js +190 -49
  195. package/dist/src/inbox/inbox-attachments.js +29 -30
  196. package/dist/src/inbox/inbox-cancel.js +10 -11
  197. package/dist/src/inbox/inbox-edit.js +9 -9
  198. package/dist/src/inbox/inbox-submit.js +18 -18
  199. package/dist/src/inbox/inbox-top.js +28 -17
  200. package/dist/src/inbox/inbox.js +42 -43
  201. package/dist/src/inbox/pending-prompt.js +26 -26
  202. package/dist/src/inbox/prompt-commands.js +62 -49
  203. package/dist/src/inbox/prompt-not-before.js +2 -2
  204. package/dist/src/init/init-templates.js +1 -2
  205. package/dist/src/init/init.js +28 -23
  206. package/dist/src/merge/backlog-conflicts.js +215 -35
  207. package/dist/src/merge/merge-batch.js +14 -8
  208. package/dist/src/merge/merge-cancel.js +53 -0
  209. package/dist/src/merge/merge-check-failures.js +44 -22
  210. package/dist/src/merge/merge-core.js +58 -32
  211. package/dist/src/merge/merge-diff.js +5 -4
  212. package/dist/src/merge/merge-drain.js +45 -19
  213. package/dist/src/merge/merge-git.js +177 -38
  214. package/dist/src/merge/merge-pipeline.js +15 -3
  215. package/dist/src/merge/merge-post-review.js +214 -0
  216. package/dist/src/merge/merge-queue-render.js +48 -11
  217. package/dist/src/merge/merge-queue.js +52 -15
  218. package/dist/src/merge/merge-requeue.js +103 -0
  219. package/dist/src/merge/merge-slot.js +61 -16
  220. package/dist/src/merge/merge-stack.js +27 -11
  221. package/dist/src/merge/merge-to-main.js +77 -26
  222. package/dist/src/merge/merge-top.js +83 -0
  223. package/dist/src/merge/merge-verify.js +75 -18
  224. package/dist/src/notes-cli.js +35 -15
  225. package/dist/src/operator/operator-commands.js +192 -81
  226. package/dist/src/operator/operator-intent.js +69 -42
  227. package/dist/src/operator/operator-requests.js +35 -40
  228. package/dist/src/operator/retire.js +5 -6
  229. package/dist/src/operator/revert.js +142 -34
  230. package/dist/src/orchestrator/orchestrator-launch.js +60 -52
  231. package/dist/src/orchestrator/orchestrator-poll.js +352 -0
  232. package/dist/src/orchestrator/orchestrator-scheduling.js +71 -370
  233. package/dist/src/orchestrator/orchestrator.js +129 -369
  234. package/dist/src/orchestrator/retention.js +42 -8
  235. package/dist/src/orchestrator/scheduling-admit.js +116 -0
  236. package/dist/src/orchestrator/scheduling-scope.js +245 -0
  237. package/dist/src/orchestrator/scheduling-skip.js +195 -0
  238. package/dist/src/orchestrator/startup-migration-steps.js +8 -7
  239. package/dist/src/orchestrator/startup-migrations.js +11 -7
  240. package/dist/src/paths.js +126 -49
  241. package/dist/src/pi/command-shape.js +12 -1
  242. package/dist/src/pi/pi-args.js +6 -4
  243. package/dist/src/pi/pi-backend.js +6 -6
  244. package/dist/src/pi/pi-bin.js +54 -63
  245. package/dist/src/pi/pi-listed-models.js +53 -0
  246. package/dist/src/pi/pi-models.js +63 -30
  247. package/dist/src/pi/pi-run-result.js +1 -1
  248. package/dist/src/pi/pi-settings.js +1 -1
  249. package/dist/src/pi/pi-stream.js +6 -6
  250. package/dist/src/pi/pi-watchdogs.js +18 -19
  251. package/dist/src/pi-extension/bounded-output.js +5 -3
  252. package/dist/src/pi-extension/context-budget.js +2 -2
  253. package/dist/src/pi-extension/context-shake.js +1 -1
  254. package/dist/src/pi-extension/context-window.js +0 -1
  255. package/dist/src/pi-extension/full-output.js +3 -10
  256. package/dist/src/pi-extension/strip-thinking.js +0 -1
  257. package/dist/src/pi-extension/trim-system-prompt.js +3 -4
  258. package/dist/src/pi-extension/write-guard.js +37 -0
  259. package/dist/src/process/launch-services.js +1 -2
  260. package/dist/src/process/node-bin.js +16 -0
  261. package/dist/src/process/process-group.js +8 -18
  262. package/dist/src/process/process.js +41 -2
  263. package/dist/src/process/run-marker.js +26 -6
  264. package/dist/src/process/supervisor.js +22 -21
  265. package/dist/src/prompt/dialect.js +17 -2
  266. package/dist/src/prompt/gate-notes.js +203 -0
  267. package/dist/src/prompt/gate-prompts.js +150 -217
  268. package/dist/src/prompt/notes-backlog.js +184 -0
  269. package/dist/src/prompt/principles.js +1 -2
  270. package/dist/src/prompt/prompt-followup.js +19 -14
  271. package/dist/src/prompt/prompt.js +131 -204
  272. package/dist/src/redeploy/redeploy-policy.js +24 -19
  273. package/dist/src/redeploy/redeploy-probes.js +1 -1
  274. package/dist/src/redeploy/redeploy.js +2 -3
  275. package/dist/src/redeploy/redeployer.js +20 -20
  276. package/dist/src/redeploy/self-reload.js +2 -1
  277. package/dist/src/report/report-data.js +188 -124
  278. package/dist/src/report/report-fold.js +130 -54
  279. package/dist/src/report/report-main-red.js +55 -0
  280. package/dist/src/report/report-render.js +136 -65
  281. package/dist/src/report/report-types.js +1 -0
  282. package/dist/src/report/report.js +23 -9
  283. package/dist/src/request-timeouts.js +2 -2
  284. package/dist/src/review/diff-rules.js +53 -0
  285. package/dist/src/review/known-flakes.js +112 -1
  286. package/dist/src/review/post-merge-review-accept.js +51 -0
  287. package/dist/src/review/post-merge-review-render.js +112 -0
  288. package/dist/src/review/post-merge-review.js +239 -0
  289. package/dist/src/review/protected-edits.js +24 -10
  290. package/dist/src/review/quarantine-render.js +65 -0
  291. package/dist/src/review/review-followup.js +8 -8
  292. package/dist/src/review/review-precheck.js +66 -23
  293. package/dist/src/review/review-run.js +395 -0
  294. package/dist/src/review/review-verdict.js +2 -2
  295. package/dist/src/review/review.js +180 -401
  296. package/dist/src/review/secret-leaks.js +36 -16
  297. package/dist/src/review/suite-rerun.js +0 -1
  298. package/dist/src/roles/legacy-role-migration.js +80 -7
  299. package/dist/src/roles/role-catalog.js +127 -12
  300. package/dist/src/roles/role-guidance.js +65 -20
  301. package/dist/src/roles/role-labels.js +7 -5
  302. package/dist/src/roles/role-render.js +108 -56
  303. package/dist/src/roles/role-view.js +95 -56
  304. package/dist/src/roles/roles.js +33 -33
  305. package/dist/src/roles/runner-ids.js +97 -0
  306. package/dist/src/run/acceptance-greps.js +119 -0
  307. package/dist/src/run/ci-parity.js +121 -0
  308. package/dist/src/run/feedback-filings.js +51 -0
  309. package/dist/src/run/qa-coverage.js +125 -0
  310. package/dist/src/{tick/tick-apply.js → run/run-apply.js} +95 -94
  311. package/dist/src/run/run-detail-data.js +175 -0
  312. package/dist/src/run/run-detail-render.js +91 -0
  313. package/dist/src/run/run-detail.js +168 -0
  314. package/dist/src/{tick/tick-finalize.js → run/run-finalize.js} +73 -60
  315. package/dist/src/{tick/tick-outcome.js → run/run-outcome.js} +6 -7
  316. package/dist/src/{tick/tick-prompt.js → run/run-prompt.js} +122 -73
  317. package/dist/src/{tick/tick-resume.js → run/run-resume.js} +55 -26
  318. package/dist/src/{tick/tick-stage.js → run/run-stage.js} +170 -83
  319. package/dist/src/{tick/tick-timing.js → run/run-timing.js} +43 -41
  320. package/dist/src/{tick/tick-usage.js → run/run-usage.js} +45 -37
  321. package/dist/src/{tick/tick-verdict.js → run/run-verdict.js} +105 -57
  322. package/dist/src/run/selfcheck-digest.js +40 -0
  323. package/dist/src/run/stage-backlog-checks.js +249 -0
  324. package/dist/src/run/stage-check.js +178 -0
  325. package/dist/src/run/stage-checks-shared.js +65 -0
  326. package/dist/src/run/stage-name-checks.js +204 -0
  327. package/dist/src/run/stage-path-checks.js +231 -0
  328. package/dist/src/run/stage-prose-checks.js +261 -0
  329. package/dist/src/runner/leftover.js +216 -0
  330. package/dist/src/{loop → runner}/model-fallback.js +12 -12
  331. package/dist/src/runner/revision.js +191 -0
  332. package/dist/src/{loop/loop-fallback.js → runner/runner-fallback.js} +8 -8
  333. package/dist/src/runner/runner-outcome.js +109 -0
  334. package/dist/src/{loop/loop-pi.js → runner/runner-pi.js} +140 -131
  335. package/dist/src/{loop/loop-recovery.js → runner/runner-recovery.js} +39 -18
  336. package/dist/src/{loop/loop-tick.js → runner/runner-run.js} +236 -245
  337. package/dist/src/{loop/loop-state.js → runner/runner-state-load.js} +61 -114
  338. package/dist/src/runner/runner-state.js +103 -0
  339. package/dist/src/{loop/loop.js → runner/runner.js} +123 -120
  340. package/dist/src/scheduling/backoff.js +38 -38
  341. package/dist/src/scheduling/claim-entries.js +49 -0
  342. package/dist/src/scheduling/claims.js +35 -22
  343. package/dist/src/scheduling/once-round.js +22 -22
  344. package/dist/src/scheduling/quiet-hours.js +5 -6
  345. package/dist/src/scheduling/scheduling.js +74 -64
  346. package/dist/src/scheduling/work-merged-cache.js +2 -2
  347. package/dist/src/status/status-budget.js +55 -47
  348. package/dist/src/status/status-data.js +49 -17
  349. package/dist/src/status/status-inbox.js +2 -2
  350. package/dist/src/status/status-install.js +0 -1
  351. package/dist/src/status/status-polls.js +43 -28
  352. package/dist/src/status/status-roles.js +50 -13
  353. package/dist/src/team/error-storm.js +8 -8
  354. package/dist/src/team/failure-spread.js +2 -2
  355. package/dist/src/team/orchestrator-info.js +15 -9
  356. package/dist/src/team/reclaim.js +7 -8
  357. package/dist/src/team/team-hold.js +7 -7
  358. package/dist/src/team/team-polls.js +91 -50
  359. package/dist/src/team/team-state.js +8 -2
  360. package/dist/src/text/datetime.js +65 -18
  361. package/dist/src/text/format.js +48 -11
  362. package/dist/src/text/markdown.js +8 -5
  363. package/dist/src/text/phrases.js +60 -23
  364. package/dist/src/text/suggest.js +1 -1
  365. package/dist/src/text/text.js +78 -13
  366. package/dist/src/ui/badges.js +99 -38
  367. package/dist/src/ui/gui/gui-client-backlog.js +314 -0
  368. package/dist/src/ui/gui/gui-client-boot.js +89 -61
  369. package/dist/src/ui/gui/gui-client-composer.js +8 -9
  370. package/dist/src/ui/gui/gui-client-drawer-config.js +254 -0
  371. package/dist/src/ui/gui/gui-client-drawer.js +155 -289
  372. package/dist/src/ui/gui/gui-client-feed.js +271 -0
  373. package/dist/src/ui/gui/gui-client-history.js +437 -68
  374. package/dist/src/ui/gui/gui-client-labels.js +6 -3
  375. package/dist/src/ui/gui/gui-client-markdown.js +1 -2
  376. package/dist/src/ui/gui/gui-client-model.js +27 -36
  377. package/dist/src/ui/gui/gui-client-operator.js +60 -52
  378. package/dist/src/ui/gui/gui-client-pending.js +405 -24
  379. package/dist/src/ui/gui/gui-client-report-chart.js +492 -0
  380. package/dist/src/ui/gui/gui-client-report.js +105 -430
  381. package/dist/src/ui/gui/{gui-client-loops.js → gui-client-roles.js} +43 -44
  382. package/dist/src/ui/gui/gui-client-settings.js +163 -5
  383. package/dist/src/ui/gui/gui-client-team.js +36 -465
  384. package/dist/src/ui/gui/gui-client.js +38 -26
  385. package/dist/src/ui/gui/gui-icons.js +0 -2
  386. package/dist/src/ui/gui/gui-page.js +10 -7
  387. package/dist/src/ui/gui/gui-styles.js +38 -34
  388. package/dist/src/ui/progress-data.js +9 -11
  389. package/dist/src/ui/{tick-progress-model.js → run-progress-model.js} +33 -32
  390. package/dist/src/ui/status-model.js +133 -125
  391. package/dist/src/ui/status-payload.js +364 -49
  392. package/dist/src/ui/status-render.js +109 -82
  393. package/dist/src/ui/team-alerts.js +728 -62
  394. package/dist/src/ui/tone.js +12 -6
  395. package/dist/src/ui/transcript-run.js +58 -0
  396. package/dist/src/ui/transcript-tail.js +28 -20
  397. package/dist/src/ui/transcript.js +63 -23
  398. package/dist/src/ui/tui/tui-app.js +0 -1
  399. package/dist/src/ui/tui/tui-backlog.js +53 -14
  400. package/dist/src/ui/tui/tui-editor-answer.js +27 -31
  401. package/dist/src/ui/tui/tui-editor-attach.js +4 -12
  402. package/dist/src/ui/tui/tui-editor-backends.js +127 -0
  403. package/dist/src/ui/tui/tui-editor-brief.js +14 -36
  404. package/dist/src/ui/tui/tui-editor-budget.js +36 -39
  405. package/dist/src/ui/tui/tui-editor-check.js +29 -0
  406. package/dist/src/ui/tui/tui-editor-checks.js +28 -0
  407. package/dist/src/ui/tui/tui-editor-claude-reserve.js +24 -0
  408. package/dist/src/ui/tui/tui-editor-concurrency.js +25 -0
  409. package/dist/src/ui/tui/tui-editor-config.js +99 -0
  410. package/dist/src/ui/tui/tui-editor-entry.js +39 -64
  411. package/dist/src/ui/tui/tui-editor-fallback.js +31 -0
  412. package/dist/src/ui/tui/tui-editor-instances.js +46 -0
  413. package/dist/src/ui/tui/tui-editor-instructions.js +117 -0
  414. package/dist/src/ui/tui/tui-editor-interval.js +29 -16
  415. package/dist/src/ui/tui/tui-editor-model.js +29 -0
  416. package/dist/src/ui/tui/tui-editor-notes.js +9 -29
  417. package/dist/src/ui/tui/tui-editor-notify.js +25 -0
  418. package/dist/src/ui/tui/tui-editor-pause.js +48 -59
  419. package/dist/src/ui/tui/tui-editor-prompt.js +11 -16
  420. package/dist/src/ui/tui/tui-editor-provider-caps.js +27 -0
  421. package/dist/src/ui/tui/tui-editor-queued.js +5 -9
  422. package/dist/src/ui/tui/tui-editor-quiet.js +95 -41
  423. package/dist/src/ui/tui/tui-editor-retire.js +5 -13
  424. package/dist/src/ui/tui/tui-editor-role-enabled.js +126 -0
  425. package/dist/src/ui/tui/tui-editor-role-key.js +71 -0
  426. package/dist/src/ui/tui/tui-editor-role-model.js +28 -0
  427. package/dist/src/ui/tui/tui-editor-search.js +45 -33
  428. package/dist/src/ui/tui/tui-editor-session.js +101 -34
  429. package/dist/src/ui/tui/tui-editor-slots.js +24 -0
  430. package/dist/src/ui/tui/tui-editors.js +44 -2
  431. package/dist/src/ui/tui/tui-frame.js +68 -11
  432. package/dist/src/ui/tui/tui-history.js +8 -9
  433. package/dist/src/ui/tui/tui-input.js +13 -11
  434. package/dist/src/ui/tui/tui-keymap.js +0 -1
  435. package/dist/src/ui/tui/tui-keys.js +33 -9
  436. package/dist/src/ui/tui/tui-pane-activity.js +35 -19
  437. package/dist/src/ui/tui/tui-pane-backlog.js +198 -126
  438. package/dist/src/ui/tui/tui-pane-brief.js +0 -1
  439. package/dist/src/ui/tui/tui-pane-ctx.js +2 -2
  440. package/dist/src/ui/tui/tui-pane-health.js +168 -8
  441. package/dist/src/ui/tui/tui-pane-history.js +446 -82
  442. package/dist/src/ui/tui/tui-pane-pending.js +539 -15
  443. package/dist/src/ui/tui/tui-pane-queued.js +78 -57
  444. package/dist/src/ui/tui/tui-pane-report.js +54 -16
  445. package/dist/src/ui/tui/tui-pane-session.js +34 -6
  446. package/dist/src/ui/tui/tui-pane-transcript.js +111 -37
  447. package/dist/src/ui/tui/tui-pane.js +91 -28
  448. package/dist/src/ui/tui/tui-panes.js +153 -34
  449. package/dist/src/ui/tui/tui.js +18 -15
  450. package/dist/src/verdict/fix-claim.js +129 -33
  451. package/dist/src/verdict/no-change.js +4 -4
  452. package/dist/src/verdict/refusal.js +40 -16
  453. package/dist/src/verdict/reply-contract.js +77 -31
  454. package/dist/src/version.js +0 -1
  455. package/package.json +2 -1
  456. package/dist/src/loop/leftover.js +0 -130
  457. package/dist/src/loop/revision.js +0 -70
  458. package/dist/src/roles/loop-ids.js +0 -77
  459. package/dist/src/tick/qa-coverage.js +0 -108
  460. package/dist/src/tick/stage-check.js +0 -419
  461. package/dist/src/tick/telemetry-digest.js +0 -25
  462. package/dist/src/tick/tick-detail-data.js +0 -108
  463. package/dist/src/tick/tick-detail.js +0 -163
  464. package/dist/src/ui/gui/gui-client-sound.js +0 -53
@@ -0,0 +1,184 @@
1
+ /** The live backlog state a role's notes are checked against, so a note cannot keep a belief the
2
+ * backlog has lifted. Role notes are free text carried into every later run and rewritten from
3
+ * the previous note; when a note states something about the backlog (an entry is refused, a
4
+ * series is dead, a part is done) nothing used to check that claim again — on 2026-10-21 a plan
5
+ * run wrote "Codex 2b/9 carry Refused — never re-add or re-author them; the Codex theme is dead",
6
+ * then both Refused notes became Needs-replan notes the plan role exists to act on, but its own
7
+ * notes kept telling it to skip them and the series stalled. This module renders, from the notes
8
+ * and the live backlog, a short block saying what is currently true of each entry and series the
9
+ * notes name, so the live state wins without anyone editing a notes file.
10
+ *
11
+ * Naming is a pure function of the notes text, case-insensitive on word boundaries:
12
+ * - a series among the planned entries is named by its full name, or by its first word when no
13
+ * other live series shares that first word;
14
+ * - a line holding a series token and a `i/n` part ref of that series names that part;
15
+ * - a line holding a series token and no part ref names the series;
16
+ * - a line holding, in order, the first six words of a planned entry's or Open bug's title
17
+ * names that entry.
18
+ * Each named planned part carries its eligibility hold (entryHoldAgainst); a part in
19
+ * PLANS-DONE.md reads `done`, a part found nowhere reads `not in the backlog`. Each named series
20
+ * gets one summary line of its planned-part state. The block is at most 12 lines and returns
21
+ * undefined when the notes name nothing live. */
22
+ import { entryHoldAgainst, entryKindLabel } from "../backlog/backlog-eligibility.js";
23
+ import { entryKey, partKey, plannedPartKeys, seriesPart } from "../backlog/backlog-parts.js";
24
+ import { collapseWhitespace, escapeRegExp } from "../text/text.js";
25
+ const MAX_BLOCK_LINES = 12;
26
+ const HEADER = "What the backlog says now about entries your notes name (PLANS.md and BUGS.md as of this run; where your notes disagree, this is current):";
27
+ /** Build the per-series state maps from the planned entries and done titles. Holds are judged
28
+ * against all planned parts (cross-series prerequisites count too), exactly as entryHoldAgainst
29
+ * does, so a part that waits on another series reads `waits on …`. */
30
+ function seriesInfos(planned, doneTitles) {
31
+ const allParts = plannedPartKeys(planned);
32
+ const map = new Map();
33
+ for (const entry of planned) {
34
+ const part = seriesPart(entry.title);
35
+ if (part === null)
36
+ continue;
37
+ const key = partKey(part.series, part.part);
38
+ let info = map.get(part.series.toLowerCase());
39
+ if (info === undefined) {
40
+ info = { name: part.series, of: part.of, plannedCount: 0, replan: 0, review: 0, waiting: 0, refused: 0, holds: new Map(), done: new Set() };
41
+ map.set(part.series.toLowerCase(), info);
42
+ }
43
+ info.plannedCount++;
44
+ const hold = entryHoldAgainst(entry, allParts);
45
+ info.holds.set(key, hold);
46
+ if (hold === "needs-replan")
47
+ info.replan++;
48
+ else if (hold === "needs-review" || hold === "held-for-operator")
49
+ info.review++; // vocabulary-ok: the held-for-operator hold is an operator decision
50
+ else if (hold === "refused")
51
+ info.refused++;
52
+ else if (typeof hold === "object" && hold !== null)
53
+ info.waiting++;
54
+ }
55
+ for (const title of doneTitles) {
56
+ const part = seriesPart(title);
57
+ if (part === null)
58
+ continue;
59
+ const info = map.get(part.series.toLowerCase());
60
+ if (info !== undefined)
61
+ info.done.add(partKey(part.series, part.part));
62
+ }
63
+ return map;
64
+ }
65
+ /** The first word of a series name, lowercased. */
66
+ function firstWord(name) {
67
+ return name.toLowerCase().split(/\s+/)[0];
68
+ }
69
+ /** Whether `lowerLine` contains `token` on word boundaries (both already lowercased). */
70
+ function lineHas(lowerLine, token) {
71
+ const quoted = escapeRegExp(token);
72
+ return new RegExp(`\\b${quoted}\\b`).test(lowerLine);
73
+ }
74
+ /** The `i/n` part refs in a line, numerators lowercased. */
75
+ function partRefsInLine(line) {
76
+ const out = [];
77
+ const re = /\b([0-9]+[a-z]?)\/([0-9]+)\b/g;
78
+ for (let m = re.exec(line); m !== null; m = re.exec(line)) {
79
+ out.push({ part: m[1].toLowerCase(), of: Number(m[2]) });
80
+ }
81
+ return out;
82
+ }
83
+ /** The first six words of an entry title, entryKey-normalized (stamp stripped, whitespace
84
+ * collapsed, lowercased). */
85
+ function firstSixWords(normalizedKey) {
86
+ return normalizedKey.split(/\s+/).slice(0, 6).join(" ");
87
+ }
88
+ /** The wording of one named item's state: an eligibility hold, `done`, or `not in the backlog`.
89
+ * `file` is which backlog the entry lives in, so a held-for-operator entry names the operator's
90
+ * matching release command (`tumwater plan --release` for a plan, `tumwater bug --release` for a
91
+ * bug) — the same Plan/Bug derivation the operator-held alert uses. */
92
+ function holdWording(state, file = "plans") {
93
+ if (state === "done")
94
+ return "done";
95
+ if (state === "not-in-backlog")
96
+ return "not in the backlog";
97
+ if (state === null)
98
+ return "eligible";
99
+ if (state === "refused")
100
+ return "refused (only the operator clears it)"; // vocabulary-ok: the plan-mandated refused hold wording refers to the tumwater operator
101
+ if (state === "needs-review")
102
+ return "needs review";
103
+ if (state === "needs-replan")
104
+ return "needs replan (the plan role rewrites it)";
105
+ if (state === "held-for-operator")
106
+ return `held for the operator (tumwater ${entryKindLabel(file).toLowerCase()} --release)`; // vocabulary-ok: names the operator-held wording and the operator's release command
107
+ if (state === "waiting-for-failure")
108
+ return "waiting for the next failure";
109
+ return `waits on ${state.blockedBy.join(", ")}`;
110
+ }
111
+ /** The one summary line of a named series' planned-part state. */
112
+ function seriesSummary(info) {
113
+ const counts = [];
114
+ if (info.replan > 0)
115
+ counts.push(`${info.replan} ${info.replan === 1 ? "needs a replan" : "need a replan"}`);
116
+ if (info.review > 0)
117
+ counts.push(`${info.review} ${info.review === 1 ? "needs review" : "need review"}`);
118
+ if (info.waiting > 0)
119
+ counts.push(`${info.waiting} ${info.waiting === 1 ? "waits" : "wait"} on an earlier part`);
120
+ counts.push(info.refused === 0 ? "none refused" : `${info.refused} refused`);
121
+ return `${info.plannedCount} ${info.plannedCount === 1 ? "part" : "parts"} planned: ${counts.join(", ")}`;
122
+ }
123
+ /** The live backlog block for the notes, or undefined when they name nothing live. */
124
+ export function notesBacklogBlock(notes, backlog) {
125
+ const { planned, openBugs, donePlanTitles } = backlog;
126
+ const series = seriesInfos(planned, donePlanTitles);
127
+ const allParts = plannedPartKeys(planned);
128
+ const firstWordCounts = new Map();
129
+ for (const info of series.values()) {
130
+ const w = firstWord(info.name);
131
+ firstWordCounts.set(w, (firstWordCounts.get(w) ?? 0) + 1);
132
+ }
133
+ const allEntries = [...planned, ...openBugs];
134
+ const namedSeries = new Set();
135
+ const namedParts = new Map();
136
+ const namedEntries = new Map();
137
+ for (const rawLine of notes.split("\n")) {
138
+ const line = collapseWhitespace(rawLine).toLowerCase();
139
+ if (line === "")
140
+ continue;
141
+ for (const [sLower, info] of series) {
142
+ const hasFull = lineHas(line, info.name.toLowerCase());
143
+ const fw = firstWord(info.name);
144
+ const hasFirst = firstWordCounts.get(fw) === 1 && lineHas(line, fw);
145
+ if (!hasFull && !hasFirst)
146
+ continue;
147
+ const refs = partRefsInLine(line).filter((r) => r.of === info.of);
148
+ if (refs.length === 0) {
149
+ namedSeries.add(sLower);
150
+ }
151
+ else {
152
+ for (const r of refs) {
153
+ const key = partKey(info.name, r.part);
154
+ const state = info.holds.has(key) ? info.holds.get(key) : info.done.has(key) ? "done" : "not-in-backlog";
155
+ namedParts.set(`${sLower}\u0000${r.part}\u0000${r.of}`, { seriesLower: sLower, part: r.part, of: r.of, state });
156
+ }
157
+ }
158
+ }
159
+ for (const [i, entry] of allEntries.entries()) {
160
+ const phrase = firstSixWords(entryKey(entry.title));
161
+ if (phrase !== "" && line.includes(phrase)) {
162
+ namedEntries.set(entryKey(entry.title), { title: entry.title, file: i < planned.length ? "plans" : "bugs", state: entryHoldAgainst(entry, allParts) });
163
+ }
164
+ }
165
+ }
166
+ const lines = [];
167
+ for (const sLower of namedSeries) {
168
+ const info = series.get(sLower);
169
+ if (info !== undefined)
170
+ lines.push(`- ${info.name} — ${seriesSummary(info)}`);
171
+ }
172
+ for (const p of namedParts.values()) {
173
+ const info = series.get(p.seriesLower);
174
+ if (info === undefined)
175
+ continue;
176
+ lines.push(`- ${info.name}, part ${p.part}/${p.of} — ${holdWording(p.state, "plans")}`);
177
+ }
178
+ for (const entry of namedEntries.values())
179
+ lines.push(`- ${entry.title} — ${holdWording(entry.state, entry.file)}`);
180
+ if (lines.length === 0)
181
+ return undefined;
182
+ const shown = lines.slice(0, MAX_BLOCK_LINES - 1);
183
+ return [HEADER, ...shown].join("\n");
184
+ }
@@ -1,9 +1,8 @@
1
- // vocabulary: plain
2
1
  import path from "node:path";
3
2
  import { readTextOrNull } from "../files/files.js";
4
3
  import { truncateWithNote } from "../text/text.js";
5
4
  /** Cap on the PRINCIPLES.md text injected into every prompt, so a runaway file cannot blow up
6
- * each tick's prefill. */
5
+ * each run's prefill. */
7
6
  export const PRINCIPLES_MAX_CHARS = 4000;
8
7
  /** The project's design principles (PRINCIPLES.md), capped for injection into prompts. Empty
9
8
  * string when the file is missing or unreadable — prompt building must never throw on it.
@@ -1,4 +1,3 @@
1
- // vocabulary: plain
2
1
  import { contextBudgetRule } from "./prompt.js";
3
2
  import { dialectFor } from "./dialect.js";
4
3
  import { NOTHING_TO_DO, REPLY_ENDINGS, SUMMARY_BLOCK } from "../verdict/reply-contract.js";
@@ -8,7 +7,7 @@ import { NOTHING_TO_DO, REPLY_ENDINGS, SUMMARY_BLOCK } from "../verdict/reply-co
8
7
  * the cut-off and timeout bridges deliberately phrase their own finish instructions instead. */
9
8
  const CONTINUE_TASK_BRIDGE = `Continue the SAME task you were working on and finish it. If the work so far turns out to be
10
9
  unusable, redo it — but stay on this task rather than picking a new one.`;
11
- /** The follow-up prompt for resuming an interrupted tick. It is sent into the SAME pi session as
10
+ /** The follow-up prompt for resuming an interrupted run. It is sent into the SAME pi session as
12
11
  * the interrupted run — which already carries the full original prompt, all rules, and the work
13
12
  * so far — so it only needs to bridge the gap. The bridge names the real cause: a run cut off at
14
13
  * the context ceiling needs to finish with the smallest change and read almost nothing more, not
@@ -63,11 +62,13 @@ ${contextBudgetRule(dialectFor(agent))}
63
62
  ${REPLY_ENDINGS}`;
64
63
  }
65
64
  /** The bridge for a `handoff` resume (plans/agent-backends.md "Sessions"): the newest session
66
- * in the worktree's session dir belongs to another agent, so this tick runs a FRESH session —
67
- * the full assembled tick prompt, plus the one fact a fresh session cannot know: an interrupted
65
+ * in the worktree's session dir belongs to another agent, so this run starts a FRESH session —
66
+ * the full assembled run prompt, plus the one fact a fresh session cannot know: an interrupted
68
67
  * run's uncommitted edits are sitting in the worktree. The worktree is NOT reset for a handoff,
69
- * so the bridge must send the new run to `git diff` before it starts its own work. */
70
- export function buildHandoffPrompt(roleId, tickPrompt, cause = "handoff",
68
+ * so the bridge must send the new run to `git diff` before it starts its own work. A `salvaged`
69
+ * handoff's edits were restored from a patch of a run the harness lost track of
70
+ * (src/git/slot-salvage.ts) rather than kept in place. */
71
+ export function buildHandoffPrompt(roleId, runPrompt, cause = "handoff",
71
72
  /** Named facts an image-reroute handoff note needs that the cause alone cannot carry: the
72
73
  * model the blind run was on and the image file it read. */
73
74
  imageReroute) {
@@ -80,12 +81,16 @@ discard them. This run starts on the model job the daily budget left you.`
80
81
  when it read ${imageReroute?.path ?? "an image"}, because that model cannot read images; its
81
82
  uncommitted edits are in your worktree — review \`git diff\`, then finish or discard them. This
82
83
  run is on a model that CAN read images, so read the image again.`
83
- : `An earlier run of the "${roleId}" role on another model was interrupted; its
84
+ : cause === "salvaged"
85
+ ? `An earlier run of the "${roleId}" role was cut short before tumwater could save its work;
86
+ its uncommitted edits were recovered and are in your worktree — review \`git status\` and
87
+ \`git diff\` (new files show as untracked), then finish or discard them.`
88
+ : `An earlier run of the "${roleId}" role on another model was interrupted; its
84
89
  uncommitted edits are in your worktree — review \`git diff\`, then finish or discard them.`;
85
- return `${tickPrompt}\n\n${note}`;
90
+ return `${runPrompt}\n\n${note}`;
86
91
  }
87
- /** The one-turn follow-up sent into a tick's OWN session (--continue) when the run changed files
88
- * but its reply carried no SUMMARY line — 73 of the first 670 commits merged as "<role> tick N"
92
+ /** The one-turn follow-up sent into a run's OWN session (--continue) when the run changed files
93
+ * but its reply carried no SUMMARY line — 73 of the first 670 commits merged as "<role> run N"
89
94
  * because of that, most of them the largest diffs in the repo. The session still holds everything
90
95
  * the run did, so one short reply recovers the subject and body the commit deserves; the caller
91
96
  * bounds the run tightly and falls back to a diff-derived subject if this too yields nothing. */
@@ -101,10 +106,10 @@ did not include the required closing block, so tumwater cannot describe the comm
101
106
  to make. Reply now with ONLY that block — no tool calls, no other text, one line each:
102
107
  ${SUMMARY_BLOCK}`;
103
108
  }
104
- /** The note injected into a role's next FRESH tick prompt after its previous run(s) were cut
105
- * off at the context ceiling without merging anything (the loop gave up resuming — see
106
- * tick-apply.ts's CUT_OFF_RESUME_LIMIT — or a cut-off director prompt is re-running). The only
107
- * cross-tick memory that the last attempt was too big for the window. */
109
+ /** The note injected into a role's next FRESH run prompt after its previous run(s) were cut
110
+ * off at the context ceiling without merging anything (the role gave up resuming — see
111
+ * run-apply.ts's CUT_OFF_RESUME_LIMIT — or a cut-off director prompt is re-running). The only
112
+ * cross-run memory that the last attempt was too big for the window. */
108
113
  export function buildCutOffNote(streak) {
109
114
  const runs = streak === 1 ? "run" : `${streak} runs`;
110
115
  return `Your previous ${runs} as this role ran out of context before merging anything. Pick a