tumwater 0.4.0 → 0.4.2
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.
- package/README.md +4 -6
- package/dist/build-info.json +2 -2
- package/dist/src/agent/agent-backend.js +5 -2
- package/dist/src/agent/backend-traits.js +21 -0
- package/dist/src/agent/claude/claude-backend.js +1 -1
- package/dist/src/agent/claude/claude-stream.js +181 -182
- package/dist/src/agent/claude/{write-guard-hook.js → claude-write-guard-hook.js} +1 -1
- package/dist/src/agent/claude/claude-write-guard.js +5 -4
- package/dist/src/agent/codex/codex-backend.js +1 -1
- package/dist/src/agent/codex/codex-rollout.js +48 -45
- package/dist/src/agent/codex/codex-stream.js +269 -215
- package/dist/src/agent/codex/{write-guard-hook.js → codex-write-guard-hook.js} +2 -1
- package/dist/src/agent/codex/codex-write-guard.js +3 -3
- package/dist/src/agent/image-input.js +18 -87
- package/dist/src/agent/notes-shim.js +2 -2
- package/dist/src/agent/opencode/opencode-backend.js +2 -2
- package/dist/src/agent/opencode/opencode-catalog.js +2 -2
- package/dist/src/agent/opencode/opencode-config.js +2 -2
- package/dist/src/agent/opencode/opencode-stream.js +101 -92
- package/dist/src/agent/run-agent.js +76 -382
- package/dist/src/agent/run-settle.js +25 -15
- package/dist/src/agent/run-spawn.js +226 -0
- package/dist/src/agent/run-stream.js +185 -0
- package/dist/src/agent/session-ledger.js +16 -0
- package/dist/src/agent/write-guard.js +5 -3
- package/dist/src/backlog/backlog-archive.js +86 -170
- package/dist/src/backlog/backlog-cli-view.js +89 -70
- package/dist/src/backlog/backlog-eligibility.js +51 -59
- package/dist/src/backlog/backlog-file-bugs.js +133 -0
- package/dist/src/backlog/backlog-index-data.js +159 -0
- package/dist/src/backlog/backlog-index.js +7 -5
- package/dist/src/backlog/backlog-md.js +39 -28
- package/dist/src/backlog/backlog-release.js +21 -36
- package/dist/src/backlog/backlog-render.js +1 -1
- package/dist/src/backlog/backlog-structure.js +14 -145
- package/dist/src/backlog/backlog-write.js +31 -18
- package/dist/src/backlog/backlog.js +14 -4
- package/dist/src/backlog/question-answer.js +33 -15
- package/dist/src/baseline/main-baseline.js +71 -26
- package/dist/src/baseline/main-guardrails.js +76 -15
- package/dist/src/baseline/main-red.js +45 -94
- package/dist/src/baseline/main-watch.js +9 -3
- package/dist/src/brief/brief.js +40 -0
- package/dist/src/budget/budget-fallback-view.js +50 -8
- package/dist/src/budget/budget-wiring.js +15 -11
- package/dist/src/budget/budget.js +3 -2
- package/dist/src/build/build-check-events.js +4 -2
- package/dist/src/build/build-check-report.js +2 -1
- package/dist/src/build/build-check-scoped.js +70 -41
- package/dist/src/change/change-data.js +4 -2
- package/dist/src/cli/cli-args.js +9 -0
- package/dist/src/cli/cli-command-args.js +199 -98
- package/dist/src/cli/cli-flag-specs.js +6 -4
- package/dist/src/cli/cli-marker-commands.js +2 -2
- package/dist/src/cli/cli-query-commands.js +41 -6
- package/dist/src/cli/cli-review-commands.js +2 -1
- package/dist/src/cli/cli-role-command.js +46 -92
- package/dist/src/cli/cli-start.js +123 -47
- package/dist/src/cli/follow-view.js +3 -1
- package/dist/src/cli/help.js +19 -12
- package/dist/src/cli/log-commands.js +128 -107
- package/dist/src/cli/question-commands.js +82 -63
- package/dist/src/cli.js +396 -343
- package/dist/src/collections.js +46 -9
- package/dist/src/config/config-fallbacks.js +0 -4
- package/dist/src/config/config-live.js +179 -147
- package/dist/src/config/config-request.js +176 -51
- package/dist/src/config/config-validation-roles.js +271 -0
- package/dist/src/config/config-validation.js +10 -205
- package/dist/src/config/config-views.js +2 -7
- package/dist/src/config/config-write.js +205 -175
- package/dist/src/config/config.js +2 -1
- package/dist/src/doctor/doctor-backlog-bugs.js +24 -122
- package/dist/src/doctor/doctor-backlog-plans.js +24 -25
- package/dist/src/doctor/doctor-backlog.js +34 -42
- package/dist/src/doctor/doctor-check-names.js +4 -2
- package/dist/src/doctor/doctor-checks.js +16 -4
- package/dist/src/doctor/doctor-claude-checks.js +2 -2
- package/dist/src/doctor/doctor-codex-checks.js +9 -20
- package/dist/src/doctor/doctor-contention-checks.js +52 -19
- package/dist/src/doctor/doctor-holds.js +22 -20
- package/dist/src/doctor/doctor-model-checks.js +8 -184
- package/dist/src/doctor/doctor-notify.js +2 -5
- package/dist/src/doctor/doctor-opencode-checks.js +90 -41
- package/dist/src/doctor/doctor-principles.js +26 -0
- package/dist/src/doctor/doctor-project-checks.js +69 -19
- package/dist/src/doctor/doctor-role-notes.js +33 -0
- package/dist/src/doctor/doctor.js +13 -6
- package/dist/src/doctor/probe.js +1 -1
- package/dist/src/events/event-format.js +307 -162
- package/dist/src/events/event-labels.js +0 -1
- package/dist/src/events/event-legacy.js +1 -1
- package/dist/src/events/event-window.js +1 -1
- package/dist/src/events/events.js +15 -2
- package/dist/src/events/notify.js +1 -1
- package/dist/src/failure/failure-cluster.js +4 -3
- package/dist/src/failure/failure-data.js +126 -94
- package/dist/src/failure/failure-render.js +58 -17
- package/dist/src/failure/failure-state-change.js +308 -27
- package/dist/src/failure/time-spend.js +139 -106
- package/dist/src/files/files.js +7 -0
- package/dist/src/files/json-object.js +15 -2
- package/dist/src/gates/budget-gates.js +90 -68
- package/dist/src/gates/gate-polls.js +92 -61
- package/dist/src/gates/role-cap-gates.js +1 -1
- package/dist/src/gates/startup-gate.js +28 -28
- package/dist/src/gates/streak-gate.js +1 -1
- package/dist/src/git/git.js +1 -1
- package/dist/src/git/slot-salvage.js +9 -9
- package/dist/src/git/slots-state.js +12 -3
- package/dist/src/git/worktree-pool-startup.js +127 -0
- package/dist/src/git/worktree-pool.js +1 -120
- package/dist/src/gui/gui-admin-endpoints.js +3 -4
- package/dist/src/gui/gui-args.js +1 -1
- package/dist/src/gui/gui-backlog-commands.js +20 -11
- package/dist/src/gui/gui-backlog-endpoints.js +2 -8
- package/dist/src/gui/gui-config-commands.js +51 -76
- package/dist/src/gui/gui-endpoint-commands.js +4 -2
- package/dist/src/gui/gui-endpoint-common.js +4 -3
- package/dist/src/gui/gui-history-endpoints.js +36 -27
- package/dist/src/gui/gui-operator-commands.js +43 -17
- package/dist/src/gui/gui-prompt-commands.js +27 -21
- package/dist/src/gui/gui-quarantine-commands.js +30 -0
- package/dist/src/gui/gui-report-endpoints.js +13 -9
- package/dist/src/gui/gui-server.js +5 -3
- package/dist/src/gui/gui-team-commands.js +1 -1
- package/dist/src/history/history-data.js +7 -1
- package/dist/src/history/history-render.js +15 -10
- package/dist/src/history/history.js +103 -68
- package/dist/src/inbox/inbox-submit.js +1 -5
- package/dist/src/inbox/pending-prompt.js +3 -2
- package/dist/src/inbox/prompt-commands.js +194 -161
- package/dist/src/init/init.js +104 -25
- package/dist/src/merge/merge-core.js +1 -1
- package/dist/src/merge/merge-drain.js +1 -1
- package/dist/src/merge/merge-git.js +5 -5
- package/dist/src/merge/{merge-post-review.js → merge-post-review-drain.js} +1 -1
- package/dist/src/merge/merge-queue.js +2 -1
- package/dist/src/merge/merge-to-main.js +1 -1
- package/dist/src/merge/merge-verify.js +3 -2
- package/dist/src/operator/operator-commands.js +84 -52
- package/dist/src/operator/operator-intent.js +26 -3
- package/dist/src/operator/retire.js +2 -1
- package/dist/src/operator/revert.js +18 -12
- package/dist/src/orchestrator/orchestrator-poll.js +2 -2
- package/dist/src/orchestrator/orchestrator.js +1 -1
- package/dist/src/orchestrator/retention.js +6 -5
- package/dist/src/paths.js +10 -10
- package/dist/src/pi/pi-bin.js +2 -2
- package/dist/src/pi/pi-models.js +9 -0
- package/dist/src/pi/pi-stream.js +63 -41
- package/dist/src/pi/pi-watchdogs.js +84 -49
- package/dist/src/pi-extension/context-shake.js +55 -31
- package/dist/src/pi-extension/full-output.js +2 -3
- package/dist/src/process/process.js +24 -1
- package/dist/src/process/run-marker.js +2 -2
- package/dist/src/process/supervisor.js +24 -5
- package/dist/src/prompt/gate-notes.js +41 -16
- package/dist/src/prompt/notes-backlog.js +22 -29
- package/dist/src/prompt/principles.js +11 -0
- package/dist/src/prompt/prompt-followup.js +4 -12
- package/dist/src/prompt/prompt.js +15 -12
- package/dist/src/redeploy/redeploy-probes.js +11 -1
- package/dist/src/redeploy/redeployer.js +54 -7
- package/dist/src/redeploy/self-reload.js +7 -2
- package/dist/src/report/report-data.js +224 -320
- package/dist/src/report/report-fold.js +23 -231
- package/dist/src/report/report-main-red.js +70 -3
- package/dist/src/report/report-render.js +181 -48
- package/dist/src/report/report-since-data.js +218 -0
- package/dist/src/report/report-usage-fold.js +288 -0
- package/dist/src/report/report.js +2 -1
- package/dist/src/review/known-flakes.js +22 -3
- package/dist/src/review/post-merge-review-accept.js +3 -2
- package/dist/src/review/post-merge-review.js +16 -14
- package/dist/src/review/quarantine-render.js +29 -11
- package/dist/src/review/review-precheck.js +2 -1
- package/dist/src/roles/role-catalog.js +30 -29
- package/dist/src/roles/role-guidance.js +26 -43
- package/dist/src/roles/role-render.js +19 -0
- package/dist/src/roles/role-view.js +19 -5
- package/dist/src/roles/roles.js +2 -22
- package/dist/src/run/ci-parity.js +5 -6
- package/dist/src/run/feedback-filings.js +10 -1
- package/dist/src/run/qa-coverage.js +4 -4
- package/dist/src/run/run-apply.js +14 -2
- package/dist/src/run/run-detail-data.js +50 -10
- package/dist/src/run/run-detail-render.js +32 -1
- package/dist/src/run/run-detail.js +44 -22
- package/dist/src/run/run-dismiss.js +43 -0
- package/dist/src/run/run-finalize.js +75 -46
- package/dist/src/run/run-prompt.js +271 -187
- package/dist/src/run/run-resume.js +32 -31
- package/dist/src/run/run-stage.js +116 -64
- package/dist/src/run/run-timing.js +18 -4
- package/dist/src/run/run-verdict.js +119 -83
- package/dist/src/run/stage-backlog-checks.js +4 -31
- package/dist/src/run/stage-check.js +4 -12
- package/dist/src/run/stage-checks-shared.js +15 -0
- package/dist/src/run/stage-name-checks.js +3 -13
- package/dist/src/run/stage-path-checks.js +26 -29
- package/dist/src/runner/leftover.js +13 -4
- package/dist/src/runner/revision.js +2 -2
- package/dist/src/runner/runner-fallback.js +1 -1
- package/dist/src/runner/runner-outcome.js +0 -5
- package/dist/src/runner/runner-pi.js +72 -49
- package/dist/src/runner/runner-run.js +19 -102
- package/dist/src/runner/runner-state-load.js +0 -10
- package/dist/src/runner/runner.js +1 -32
- package/dist/src/scheduling/claims.js +4 -11
- package/dist/src/status/status-data.js +140 -91
- package/dist/src/status/status-polls.js +41 -5
- package/dist/src/status/status-role-notes.js +53 -0
- package/dist/src/status/status-roles.js +10 -37
- package/dist/src/text/datetime.js +8 -1
- package/dist/src/text/format.js +13 -1
- package/dist/src/text/phrases.js +16 -2
- package/dist/src/text/text.js +12 -0
- package/dist/src/ui/alert-feeds.js +115 -0
- package/dist/src/ui/badges.js +3 -4
- package/dist/src/ui/gui/gui-client-boot.js +78 -57
- package/dist/src/ui/gui/gui-client-drawer-config.js +8 -3
- package/dist/src/ui/gui/gui-client-drawer.js +18 -2
- package/dist/src/ui/gui/gui-client-feed.js +3 -8
- package/dist/src/ui/gui/gui-client-history.js +16 -16
- package/dist/src/ui/gui/gui-client-model.js +9 -9
- package/dist/src/ui/gui/gui-client-operator.js +6 -10
- package/dist/src/ui/gui/gui-client-pending.js +4 -4
- package/dist/src/ui/gui/gui-client-report-chart.js +111 -10
- package/dist/src/ui/gui/gui-client-report.js +70 -11
- package/dist/src/ui/gui/gui-client-roles.js +52 -12
- package/dist/src/ui/gui/gui-client-settings.js +31 -26
- package/dist/src/ui/gui/gui-client-team.js +28 -2
- package/dist/src/ui/gui/gui-client.js +33 -4
- package/dist/src/ui/gui/gui-icons.js +7 -1
- package/dist/src/ui/progress-data.js +2 -2
- package/dist/src/ui/run-progress-model.js +2 -2
- package/dist/src/ui/status-model.js +26 -16
- package/dist/src/ui/status-payload.js +149 -326
- package/dist/src/ui/status-render.js +131 -80
- package/dist/src/ui/team-alert-backlog.js +236 -0
- package/dist/src/ui/team-alert-shared.js +92 -0
- package/dist/src/ui/team-alert-status.js +326 -0
- package/dist/src/ui/team-alert-tail.js +238 -0
- package/dist/src/ui/team-alerts.js +16 -984
- package/dist/src/ui/transcript-tail.js +137 -94
- package/dist/src/ui/tui/tui-backlog.js +1 -1
- package/dist/src/ui/tui/tui-editor-answer.js +54 -44
- package/dist/src/ui/tui/tui-editor-attach.js +74 -63
- package/dist/src/ui/tui/tui-editor-backends.js +62 -56
- package/dist/src/ui/tui/tui-editor-brief.js +64 -54
- package/dist/src/ui/tui/tui-editor-budget.js +106 -89
- package/dist/src/ui/tui/tui-editor-config.js +2 -4
- package/dist/src/ui/tui/tui-editor-ctx.js +12 -1
- package/dist/src/ui/tui/tui-editor-entry.js +171 -153
- package/dist/src/ui/tui/tui-editor-instances.js +2 -1
- package/dist/src/ui/tui/tui-editor-instructions.js +50 -107
- package/dist/src/ui/tui/tui-editor-interval.js +39 -112
- package/dist/src/ui/tui/tui-editor-notes.js +28 -84
- package/dist/src/ui/tui/tui-editor-pause.js +210 -183
- package/dist/src/ui/tui/tui-editor-prompt.js +46 -35
- package/dist/src/ui/tui/tui-editor-queued.js +74 -64
- package/dist/src/ui/tui/tui-editor-quiet.js +122 -108
- package/dist/src/ui/tui/tui-editor-release.js +85 -0
- package/dist/src/ui/tui/tui-editor-retire.js +57 -46
- package/dist/src/ui/tui/tui-editor-role-enabled.js +90 -80
- package/dist/src/ui/tui/tui-editor-role-file.js +87 -0
- package/dist/src/ui/tui/tui-editor-role-key.js +50 -42
- package/dist/src/ui/tui/tui-editor-search.js +70 -58
- package/dist/src/ui/tui/tui-editor-session.js +3 -0
- package/dist/src/ui/tui/tui-editors.js +4 -1
- package/dist/src/ui/tui/tui-frame.js +7 -3
- package/dist/src/ui/tui/tui-history.js +12 -10
- package/dist/src/ui/tui/tui-keys.js +6 -1
- package/dist/src/ui/tui/tui-pane-activity.js +62 -50
- package/dist/src/ui/tui/tui-pane-backlog.js +4 -4
- package/dist/src/ui/tui/tui-pane-ctx.js +1 -1
- package/dist/src/ui/tui/tui-pane-health.js +45 -26
- package/dist/src/ui/tui/tui-pane-history.js +296 -264
- package/dist/src/ui/tui/tui-pane-report.js +74 -57
- package/dist/src/ui/tui/tui-pane-session.js +6 -2
- package/dist/src/ui/tui/tui-pane-transcript.js +158 -131
- package/dist/src/ui/tui/tui-pane.js +201 -174
- package/dist/src/ui/tui/tui-panes.js +211 -148
- package/dist/src/ui/tui/tui.js +4 -4
- package/dist/src/verdict/fix-claim.js +18 -6
- package/dist/src/verdict/refusal.js +32 -7
- package/package.json +1 -1
- package/dist/src/doctor/image-probe.js +0 -257
- /package/dist/src/gui/{http-body.js → gui-http-body.js} +0 -0
- /package/dist/src/merge/{backlog-conflicts.js → merge-backlog-conflicts.js} +0 -0
|
@@ -151,6 +151,23 @@ const FORMAT_JS = String.raw ` // format:start
|
|
|
151
151
|
// section had the byte-identical map; a missing or non-array list paints nothing.
|
|
152
152
|
const commitRowsHtml = (commits) =>
|
|
153
153
|
(Array.isArray(commits) ? commits : []).map((c) => "<div class='mono clamp1'>" + esc(c.sha) + " " + esc(c.subject || "—") + "</div>").join("");
|
|
154
|
+
// Title-case a phrase's first character and keep the rest — backend-traits.ts's
|
|
155
|
+
// backendDisplayName rule, the one home of the upcasing gui-client-model.ts's result labels
|
|
156
|
+
// and gui-client-history.ts's window options each inlined, so a label cannot drift between
|
|
157
|
+
// them. A leading em dash or other non-letter upcases to itself, and an empty string stays
|
|
158
|
+
// empty.
|
|
159
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
160
|
+
// A whole-hour window length as "1 hour"/"N hours", or "1 day"/"N days" for a whole
|
|
161
|
+
// number of days — the shared span the activity feed's and History view's stepped-window
|
|
162
|
+
// bounds both print (each previously spelled out the modulo/pluralization inline). A minute
|
|
163
|
+
// count that isn't a whole number of days prints hours (a stepped window is always whole
|
|
164
|
+
// hours), and the singular drops the trailing s.
|
|
165
|
+
const timeSpan = (ms) => { const d = ms % 86400000 === 0; const n = d ? ms / 86400000 : ms / 3600000; return n + (d ? " day" : " hour") + (n === 1 ? "" : "s"); };
|
|
166
|
+
// The "between X and Y ago" window-length phrase a stepped window's two bounds both print
|
|
167
|
+
// (newer first) — the Activity feed's feedWindowPhrase and the History view's histWindowPhrase
|
|
168
|
+
// previously spelled out the span-and-framing inline, so the two could drift on the words
|
|
169
|
+
// around timeSpan. One home keeps the stepped-window phrasing identical everywhere.
|
|
170
|
+
const betweenAgo = (newerMs, olderMs) => "between " + timeSpan(newerMs) + " and " + timeSpan(olderMs) + " ago";
|
|
154
171
|
// human-seconds-fmt:start
|
|
155
172
|
// Whole-second s/m/h/d label: <60 → Ns, <3600 → rounded Nm, <86400 → rounded Nh, else
|
|
156
173
|
// rounded Nd — datetime.ts's humanSeconds, shared by every relative time on the page. A
|
|
@@ -179,12 +196,15 @@ const FORMAT_JS = String.raw ` // format:start
|
|
|
179
196
|
const isActivePhase = (phase) => ACTIVE_PHASE_PREFIXES.some((p) => phase.startsWith(p));
|
|
180
197
|
// active-phase-fmt:end
|
|
181
198
|
// last-run-fmt:start
|
|
199
|
+
// Whole seconds between two epoch-ms instants, clamped at zero and rounded to the nearest
|
|
200
|
+
// second — datetime.ts's secondsSince/secondsUntil (the browser runtime cannot import
|
|
201
|
+
// them), shared by every relative time on the page so the clamp cannot drift between
|
|
202
|
+
// fmtLastRun, fmtAgo, and the spliced views' pause/wake/queue ages.
|
|
203
|
+
const secsSince = (sinceMs, now) => Math.max(0, Math.round((now - sinceMs) / 1000));
|
|
204
|
+
const secsUntil = (atMs, now) => Math.max(0, Math.round((atMs - now) / 1000));
|
|
182
205
|
// The absolute local time of a run end with its age ("14:32:05 · 3m ago"), prefixed MM-DD
|
|
183
206
|
// once older than a day; "-" when never ran — status-render.ts's lastRunCell.
|
|
184
|
-
|
|
185
|
-
// second — datetime.ts's secondsSince (the browser runtime cannot import it), shared by
|
|
186
|
-
// fmtLastRun and fmtAgo below so the clamp cannot drift between the page's ages.
|
|
187
|
-
const ageSec = (ts) => Math.max(0, Math.round((Date.now() - ts) / 1000));
|
|
207
|
+
const ageSec = (ts) => secsSince(ts, Date.now());
|
|
188
208
|
const fmtLastRun = (ts) => {
|
|
189
209
|
if (!ts) return "-";
|
|
190
210
|
const d = new Date(ts);
|
|
@@ -222,6 +242,10 @@ const FORMAT_JS = String.raw ` // format:start
|
|
|
222
242
|
return sec < 60 ? "just now" : humanSeconds(sec) + " ago";
|
|
223
243
|
};
|
|
224
244
|
const fmtClock = (ts) => new Date(ts).toLocaleString([], { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
245
|
+
// The local wall-clock HH:MM of an instant — datetime.ts's clockHm, shared by the operator
|
|
246
|
+
// view's window clock (returnsAt/heldUntil/~cap-at stamps) and the role drawer's ~cap-at
|
|
247
|
+
// stamp, which each spelled the two-digit getHours/getMinutes join inline.
|
|
248
|
+
const clockHm = (ms) => { const d = new Date(ms); return String(d.getHours()).padStart(2, "0") + ":" + String(d.getMinutes()).padStart(2, "0"); };
|
|
225
249
|
// A run's duration: seconds under two minutes, then minutes, then hours. Each bucket is
|
|
226
250
|
// chosen from the rounded count so a span just under a cutoff never prints "120s" or "120m".
|
|
227
251
|
const fmtSpan = (ms) => {
|
|
@@ -238,6 +262,11 @@ const FORMAT_JS = String.raw ` // format:start
|
|
|
238
262
|
// Server text sometimes carries ISO instants (a restart cooldown's deadline); show them in
|
|
239
263
|
// the viewer's local time.
|
|
240
264
|
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)));
|
|
265
|
+
// Collapse runs of whitespace to a single space and trim — text.ts's squash, kept as this
|
|
266
|
+
// browser twin because the page cannot import the server module. The one shared home of the
|
|
267
|
+
// squash the drawer-config verbatim value's single-line clamp and the pending view's status
|
|
268
|
+
// suffix+clamp each spelled inline, so the two cannot drift on the collapse rule.
|
|
269
|
+
const squash = (s) => String(s).replace(/\s+/g, " ").trim();
|
|
241
270
|
// format:end
|
|
242
271
|
`;
|
|
243
272
|
/** Shared DOM helpers: icons, pills, panels that repaint only on change, local preferences,
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
* the browser script receives ICON_PATHS as data and builds the same markup for everything it
|
|
5
5
|
* renders. */
|
|
6
6
|
const FILLED = 'fill="currentColor" stroke="none"';
|
|
7
|
+
/** The fixed icon set, keyed by the name every renderer passes: a `Record<string, string>`
|
|
8
|
+
* here would let a typo'd icon name (a misspelled key in `iconSvg`'s argument) compile and
|
|
9
|
+
* silently render an empty SVG in the dashboard — the literal key union below turns that
|
|
10
|
+
* into a compile error at every call site. The browser script still embeds the whole map
|
|
11
|
+
* (gui-client.ts JSON.stringify) and looks names up dynamically, so a dynamic name there is
|
|
12
|
+
* unchecked the same way its other data-driven lookups are. */
|
|
7
13
|
export const ICON_PATHS = {
|
|
8
14
|
grid: '<rect x="4" y="4" width="7" height="7" rx="1.5"/><rect x="13" y="4" width="7" height="7" rx="1.5"/><rect x="4" y="13" width="7" height="7" rx="1.5"/><rect x="13" y="13" width="7" height="7" rx="1.5"/>',
|
|
9
15
|
list: `<path d="M9 6h11M9 12h11M9 18h11"/><circle cx="4.5" cy="6" r="1.2" ${FILLED}/><circle cx="4.5" cy="12" r="1.2" ${FILLED}/><circle cx="4.5" cy="18" r="1.2" ${FILLED}/>`,
|
|
@@ -36,7 +42,7 @@ export const ICON_PATHS = {
|
|
|
36
42
|
};
|
|
37
43
|
/** One icon's markup — the same shape the browser script's icon() builds. */
|
|
38
44
|
export function iconSvg(name, extraClass = "") {
|
|
39
|
-
return `<svg class="i${extraClass ? ` ${extraClass}` : ""}" viewBox="0 0 24 24" aria-hidden="true">${ICON_PATHS[name]
|
|
45
|
+
return `<svg class="i${extraClass ? ` ${extraClass}` : ""}" viewBox="0 0 24 24" aria-hidden="true">${ICON_PATHS[name]}</svg>`;
|
|
40
46
|
}
|
|
41
47
|
/** The tumwater mark: two waves on a teal tile (the name is Chinook Jargon for "thumping water").
|
|
42
48
|
* Also the page's favicon (as a data URI). */
|
|
@@ -86,7 +86,7 @@ function freshProgress(quietMs, agent) {
|
|
|
86
86
|
/** The event types feedLine acts on — everything else (streaming deltas, turn/agent
|
|
87
87
|
* bookkeeping) is ignored. Also passed as parsePiEventLine's pre-filter to skip JSON.parse for
|
|
88
88
|
* pi lines whose type is verifiably not one of these; a new case in the switch must be added
|
|
89
|
-
* here too. `tumwater_run` is the harness's own marker (src/agent/run-
|
|
89
|
+
* here too. `tumwater_run` is the harness's own marker (src/agent/run-spawn.ts), read for its
|
|
90
90
|
* run kind: a kind-bearing marker flips the demux and starts that accumulator fresh before
|
|
91
91
|
* its `session` event lands, and a legacy label-only marker ("review") still flips the demux
|
|
92
92
|
* to gate. */
|
|
@@ -251,7 +251,7 @@ function feedDemuxed(tail, line, gateCwd) {
|
|
|
251
251
|
* run in the role's own worktree, the default; `gate` — the review gate's runs in a leased pool
|
|
252
252
|
* slot, what the reviewing cell shows), or null when there is no log yet. The raw log is
|
|
253
253
|
* append-only while pi runs and every run starts with a `tumwater_run` marker
|
|
254
|
-
* (src/agent/run-
|
|
254
|
+
* (src/agent/run-spawn.ts), so after seeding from the tail window once we only read and parse
|
|
255
255
|
* bytes appended since the last poll — observers that call this every second (TUI, GUI) stop
|
|
256
256
|
* rescanning up to TAIL_BYTES
|
|
257
257
|
* of JSON per role per poll. */
|
|
@@ -59,11 +59,11 @@ function progressOfRun(s, p) {
|
|
|
59
59
|
* <tool>" and "no agent output for <duration>" to the head — as a regex SOURCE string plus the
|
|
60
60
|
* compiled matcher, single-homed beside the code that renders those phrases. Every consumer
|
|
61
61
|
* that must recognize a stall inside a rendered phase label goes through these two, so the
|
|
62
|
-
* server-side alert (team-
|
|
62
|
+
* server-side alert (team-alert-status.ts) and the dashboard's browser twin (gui-client-model.ts,
|
|
63
63
|
* interpolating the source into its String.raw script) cannot drift from the wording the cell
|
|
64
64
|
* actually renders. */
|
|
65
65
|
export const STALL_SOURCE = String.raw `tool call stalled[^·]*|no agent output for [^·]*`;
|
|
66
|
-
/** STALL_SOURCE compiled — the server-side matcher (team-
|
|
66
|
+
/** STALL_SOURCE compiled — the server-side matcher (team-alert-status.ts's stuck alert). */
|
|
67
67
|
export const STALL_RE = new RegExp(STALL_SOURCE);
|
|
68
68
|
/** The shared parts assembly for an in-flight state cell: `head` (the phase label with its
|
|
69
69
|
* own elapsed — inFlightLabel for a run, the merge branch's own for a merge) plus turn,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DIRECTOR_ROLE } from "../roles/roles.js";
|
|
2
2
|
import { baseRoleOf } from "../roles/runner-ids.js";
|
|
3
3
|
import { heldByMainRed } from "../status/status-polls.js";
|
|
4
|
-
import {
|
|
4
|
+
import { errorStreakAtWarn, QUIET_KILL_RESUME_LIMIT } from "../run/run-apply.js";
|
|
5
5
|
import { readLiveProgress } from "./progress-data.js";
|
|
6
6
|
import { quietWindowEnd } from "../scheduling/quiet-hours.js";
|
|
7
7
|
import { yieldMultiplierFor } from "../scheduling/backoff.js";
|
|
@@ -76,12 +76,12 @@ export function idleClaimText(s, _phase) {
|
|
|
76
76
|
export function onErrorStreak(s) {
|
|
77
77
|
// An error streak at or past the warning threshold (run-apply.ts's ERROR_STREAK_WARN), or
|
|
78
78
|
// a quiet-kill streak at the give-up threshold (BUGS.md 2026-09-18): the exact condition
|
|
79
|
-
// that makes rolePhase read "failing", split out so the team alert (team-
|
|
79
|
+
// that makes rolePhase read "failing", split out so the team alert (team-alert-status.ts) can
|
|
80
80
|
// key its red "failing run after run" banner on the streak rather than on the rendered
|
|
81
81
|
// phase — an in-flight run hides the streak behind a `working`/`merge` label (rolePhase
|
|
82
82
|
// ranks running work above failing), but the alert must stay up while the role's next
|
|
83
83
|
// run is in flight and clear only when the streak resets (BUGS.md 2026-10-14).
|
|
84
|
-
return ((s
|
|
84
|
+
return (errorStreakAtWarn(s) ||
|
|
85
85
|
(s.lastResult === "quiet_killed" && (s.quietKillStreak ?? 0) >= QUIET_KILL_RESUME_LIMIT));
|
|
86
86
|
}
|
|
87
87
|
export function rolePhase(s, orchestratorRunning, root, budgetPaused = false, live, userPaused = false, merge, mainCheck, capPaused = false, quietHold, diskHeld = false, bootstrapHeld = false, maintenanceQuotaHold, permits, pausedUntilMs) {
|
|
@@ -190,14 +190,14 @@ export function rolePhase(s, orchestratorRunning, root, budgetPaused = false, li
|
|
|
190
190
|
// snapshot's holder, like roleQuietPaused's window.
|
|
191
191
|
if (maintenanceQuotaHold)
|
|
192
192
|
return maintenanceQuotaHold;
|
|
193
|
-
// Main's own suite is known red at this role's last run:
|
|
194
|
-
//
|
|
193
|
+
// Main's own suite is known red at this role's last run: main_red is the last completed
|
|
194
|
+
// outcome. Shown before sleep/queue
|
|
195
195
|
// because it explains why the role keeps waking and merge nothing; self-correcting, since
|
|
196
|
-
// each
|
|
196
|
+
// each run re-records main_red while red and a green wake overwrites lastResult.
|
|
197
197
|
// Except a green wake that queues a change: `queued` is in flight, not a completed result,
|
|
198
198
|
// so it leaves the main_red pair in place until its merge resolves (run-apply.ts's
|
|
199
|
-
// applyRunOutcome) — its stashed summary is the tell that the role's latest run
|
|
200
|
-
//
|
|
199
|
+
// applyRunOutcome) — its stashed summary is the tell that the role's latest run saw
|
|
200
|
+
// main green, so "main red" would be stale.
|
|
201
201
|
// Except too when main's newest merge-scope check PASSED after this role's red run ended:
|
|
202
202
|
// the team-level verdict is fresher than the role's own, so the label is stale until the
|
|
203
203
|
// role's next run — which can be hours away (BUGS.md 2026-09-30). A check older than the
|
|
@@ -263,11 +263,21 @@ export function rolePhase(s, orchestratorRunning, root, budgetPaused = false, li
|
|
|
263
263
|
cell = "due";
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
-
// Two or more consecutive
|
|
267
|
-
//
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
266
|
+
// Two or more consecutive runs earn the suffix (N=1 is a single run — ordinary, not yet
|
|
267
|
+
// a pattern). A cut-off run is itself a `no_change`, so noChangeStreak counts a
|
|
268
|
+
// context-ceiling episode too — but the plain suffix would mislabel a window-burning
|
|
269
|
+
// episode as a benign idle one, so when the cut-off streak reads 2+ it wins: it names the
|
|
270
|
+
// costly cause (operator should split the task or raise the model's context window before
|
|
271
|
+
// the give-up). Observational only, like the no-change suffix — it never warns from here
|
|
272
|
+
// (the once-per-episode crossing warning comes from run-finalize.ts).
|
|
273
|
+
const cutOff = s.cutOffStreak ?? 0;
|
|
274
|
+
if (cutOff >= 2)
|
|
275
|
+
cell += ` · cut off ×${cutOff}`;
|
|
276
|
+
else {
|
|
277
|
+
const streak = s.noChangeStreak ?? 0;
|
|
278
|
+
if (streak >= 2)
|
|
279
|
+
cell += ` · no change ×${streak}`;
|
|
280
|
+
}
|
|
271
281
|
return cell;
|
|
272
282
|
}
|
|
273
283
|
/** One role row's display derivation — the block both observer surfaces re-ran per role
|
|
@@ -337,7 +347,7 @@ function isBindingLimit(permits, key) {
|
|
|
337
347
|
}
|
|
338
348
|
/** Is this phase one of the PERMIT-HOLDER in-flight states — the rows an operator counts
|
|
339
349
|
* against maxConcurrent? The three labels come from rolePhase: `working …`, `reviewing …`,
|
|
340
|
-
* and the marker-driven `merge …` (merge queue 4/5) —
|
|
350
|
+
* and the marker-driven `merge …` (merge queue 4/5) — an approved change waiting for the merge
|
|
341
351
|
* slot (`approved, awaiting merge`) runs nothing, so it is not in flight. The running director's
|
|
342
352
|
* `director working …` label is deliberately outside the set: the director never calls
|
|
343
353
|
* `semaphore.acquire`, so the cap-mirroring rows are exactly the permit holders (BUGS.md
|
|
@@ -352,9 +362,9 @@ export function isActivePhase(phase) {
|
|
|
352
362
|
/** A role's rank in the rendered tables, from its phase label (rolePhase): -1 a RUNNING
|
|
353
363
|
* DIRECTOR — live work of its own, outside the maxConcurrent cap it bypasses, so it groups
|
|
354
364
|
* apart and never inflates the permit-holder count (BUGS.md 2026-10-06); 0 live work —
|
|
355
|
-
* working, reviewing, merge (isActivePhase); 1 work waiting in the pipeline —
|
|
365
|
+
* working, reviewing, merge (isActivePhase); 1 work waiting in the pipeline — an approved change
|
|
356
366
|
* awaiting the merge slot, or a run parked awaiting a permit; 2 needs attention — failing, or
|
|
357
|
-
*
|
|
367
|
+
* its last run read main red; 3 paused — by the operator, by the budget, or by the role's own
|
|
358
368
|
* per-role cap; 4 everything else (idle: sleeping, queued, the director waiting for prompts, a
|
|
359
369
|
* stopped team). The dashboard groups its role table by these ranks; the TUI/status table
|
|
360
370
|
* orders by them.
|