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.
- package/README.md +74 -108
- package/dist/build-info.json +2 -2
- package/dist/src/agent/agent-args.js +24 -0
- package/dist/src/agent/agent-backend.js +2 -2
- package/dist/src/agent/backend-traits.js +60 -0
- package/dist/src/agent/claude/claude-account.js +61 -8
- package/dist/src/agent/claude/claude-args.js +12 -15
- package/dist/src/agent/claude/claude-backend.js +51 -41
- package/dist/src/agent/claude/claude-env.js +7 -3
- package/dist/src/agent/claude/claude-stream.js +7 -16
- package/dist/src/agent/image-input.js +107 -0
- package/dist/src/agent/notes-shim.js +41 -0
- package/dist/src/agent/opencode/opencode-args.js +61 -0
- package/dist/src/agent/opencode/opencode-backend.js +255 -0
- package/dist/src/agent/opencode/opencode-catalog.js +184 -0
- package/dist/src/agent/opencode/opencode-config.js +188 -0
- package/dist/src/agent/opencode/opencode-env.js +36 -0
- package/dist/src/agent/opencode/opencode-session-id.js +37 -0
- package/dist/src/agent/opencode/opencode-stream.js +278 -0
- package/dist/src/agent/role-notes-write.js +16 -32
- package/dist/src/agent/run-agent.js +95 -18
- package/dist/src/agent/session-ledger.js +57 -1
- package/dist/src/backlog/backlog-archive.js +296 -0
- package/dist/src/backlog/backlog-cli.js +573 -0
- package/dist/src/backlog/backlog-commit.js +31 -0
- package/dist/src/backlog/backlog-eligibility.js +357 -33
- package/dist/src/backlog/backlog-md.js +98 -18
- package/dist/src/backlog/backlog-render.js +62 -11
- package/dist/src/backlog/backlog-structure.js +261 -58
- package/dist/src/backlog/backlog-write.js +197 -319
- package/dist/src/backlog/backlog.js +113 -16
- package/dist/src/backlog/question-answer.js +339 -0
- package/dist/src/baseline/main-baseline.js +75 -88
- package/dist/src/baseline/main-red.js +38 -30
- package/dist/src/brief/brief-edit.js +43 -0
- package/dist/src/{brief.js → brief/brief.js} +66 -10
- package/dist/src/budget/budget.js +32 -15
- package/dist/src/budget/fallback-breaker.js +8 -7
- package/dist/src/build/build-check-detect.js +8 -7
- package/dist/src/build/build-check-events.js +68 -22
- package/dist/src/build/build-check-report.js +22 -23
- package/dist/src/build/build-check-scoped.js +51 -62
- package/dist/src/build/build-check.js +15 -14
- package/dist/src/build/build-info.js +2 -1
- package/dist/src/build/build-stage.js +23 -22
- package/dist/src/build/dep-install.js +22 -21
- package/dist/src/build/host-sleep.js +1 -1
- package/dist/src/change/change-data.js +25 -14
- package/dist/src/change/change-render.js +11 -10
- package/dist/src/cli/brief-command.js +58 -0
- package/dist/src/cli/cli-args.js +25 -5
- package/dist/src/cli/cli-command-args.js +46 -14
- package/dist/src/cli/cli-editor.js +64 -0
- package/dist/src/cli/cli-flag-specs.js +54 -16
- package/dist/src/cli/cli-marker-commands.js +13 -10
- package/dist/src/cli/cli-output.js +9 -0
- package/dist/src/cli/cli-query-commands.js +458 -49
- package/dist/src/cli/cli-repo-gate.js +1 -1
- package/dist/src/cli/cli-run.js +208 -59
- package/dist/src/cli/completion.js +207 -0
- package/dist/src/cli/config-commands.js +14 -11
- package/dist/src/cli/help.js +305 -110
- package/dist/src/cli/log-commands.js +127 -21
- package/dist/src/cli/notify-command.js +33 -18
- package/dist/src/cli/question-commands.js +29 -224
- package/dist/src/cli.js +121 -40
- package/dist/src/collections.js +66 -16
- package/dist/src/concurrency/check-permit.js +16 -17
- package/dist/src/concurrency/lock.js +6 -5
- package/dist/src/concurrency/provider-lease.js +69 -0
- package/dist/src/concurrency/semaphore.js +258 -36
- package/dist/src/config/config-aliases.js +106 -0
- package/dist/src/config/config-editable-keys.js +3 -3
- package/dist/src/config/config-fallbacks.js +379 -0
- package/dist/src/config/config-field-checks.js +19 -10
- package/dist/src/config/config-keys.js +160 -0
- package/dist/src/config/config-live.js +64 -12
- package/dist/src/config/config-schema.js +34 -22
- package/dist/src/config/config-validation.js +132 -48
- package/dist/src/config/config-views.js +119 -337
- package/dist/src/config/config-write.js +138 -177
- package/dist/src/config/config.js +60 -49
- package/dist/src/config/model-selector.js +28 -2
- package/dist/src/doctor/doctor-backlog.js +546 -49
- package/dist/src/doctor/doctor-checks.js +534 -56
- package/dist/src/doctor/doctor-holds.js +193 -53
- package/dist/src/doctor/doctor-install.js +30 -0
- package/dist/src/doctor/doctor-launch-services.js +2 -2
- package/dist/src/doctor/doctor-model-checks.js +549 -157
- package/dist/src/doctor/doctor-notify.js +27 -0
- package/dist/src/doctor/doctor-orphans.js +10 -9
- package/dist/src/doctor/doctor-render.js +36 -9
- package/dist/src/doctor/doctor.js +80 -22
- package/dist/src/doctor/image-probe.js +244 -0
- package/dist/src/doctor/probe.js +64 -0
- package/dist/src/events/event-format.js +226 -102
- package/dist/src/events/event-labels.js +116 -0
- package/dist/src/events/event-legacy.js +140 -0
- package/dist/src/events/event-read.js +58 -22
- package/dist/src/events/event-window.js +27 -7
- package/dist/src/events/events.js +18 -14
- package/dist/src/events/notify.js +137 -38
- package/dist/src/failure/failure-cluster.js +12 -9
- package/dist/src/failure/failure-data.js +96 -48
- package/dist/src/failure/failure-render.js +69 -58
- package/dist/src/failure/failure-state-change.js +33 -26
- package/dist/src/failure/time-spend.js +79 -59
- package/dist/src/files/file-queue.js +16 -4
- package/dist/src/files/files.js +18 -6
- package/dist/src/files/json-object.js +18 -3
- package/dist/src/files/tail.js +1 -1
- package/dist/src/gates/bootstrap-gates.js +5 -4
- package/dist/src/gates/budget-gates.js +250 -34
- package/dist/src/gates/disk-gate.js +18 -18
- package/dist/src/gates/gate-polls.js +117 -69
- package/dist/src/gates/maintenance-quota.js +29 -29
- package/dist/src/gates/pause-gates.js +11 -11
- package/dist/src/gates/readiness.js +2 -1
- package/dist/src/gates/role-cap-gates.js +16 -21
- package/dist/src/gates/startup-gate.js +75 -31
- package/dist/src/gates/streak-gate.js +18 -16
- package/dist/src/git/commit-message.js +12 -5
- package/dist/src/git/git-diff.js +16 -16
- package/dist/src/git/git-run.js +8 -8
- package/dist/src/git/git.js +86 -55
- package/dist/src/git/slots-state.js +14 -5
- package/dist/src/git/worktree-pool.js +25 -18
- package/dist/src/git/worktree-use.js +15 -14
- package/dist/src/git/worktree.js +18 -18
- package/dist/src/gui/gui-args.js +10 -14
- package/dist/src/gui/gui-backlog-commands.js +273 -0
- package/dist/src/gui/gui-command.js +1 -1
- package/dist/src/gui/gui-config-commands.js +440 -0
- package/dist/src/gui/gui-endpoint-commands.js +16 -669
- package/dist/src/gui/gui-endpoint-common.js +49 -0
- package/dist/src/gui/gui-endpoints.js +116 -56
- package/dist/src/gui/gui-operator-commands.js +145 -0
- package/dist/src/gui/gui-prompt-commands.js +234 -0
- package/dist/src/gui/gui-server.js +28 -8
- package/dist/src/gui/gui-team-commands.js +164 -0
- package/dist/src/gui/http-body.js +17 -1
- package/dist/src/history/history-data.js +194 -98
- package/dist/src/history/history-render.js +76 -0
- package/dist/src/history/history.js +37 -58
- package/dist/src/inbox/inbox-attachments.js +75 -14
- package/dist/src/inbox/inbox-cancel.js +7 -5
- package/dist/src/inbox/inbox-edit.js +1 -1
- package/dist/src/inbox/inbox-submit.js +44 -4
- package/dist/src/inbox/inbox-top.js +83 -0
- package/dist/src/inbox/inbox.js +8 -2
- package/dist/src/inbox/pending-prompt.js +1 -1
- package/dist/src/inbox/prompt-commands.js +170 -80
- package/dist/src/init/init-templates.js +16 -14
- package/dist/src/init/init.js +12 -11
- package/dist/src/loop/leftover.js +28 -27
- package/dist/src/loop/loop-fallback.js +2 -2
- package/dist/src/loop/loop-pi.js +106 -52
- package/dist/src/loop/loop-recovery.js +15 -15
- package/dist/src/loop/loop-state.js +139 -13
- package/dist/src/loop/loop-tick.js +194 -86
- package/dist/src/loop/loop.js +72 -36
- package/dist/src/loop/model-fallback.js +3 -2
- package/dist/src/loop/revision.js +16 -7
- package/dist/src/merge/backlog-conflicts.js +155 -0
- package/dist/src/{landing/landing-batch.js → merge/merge-batch.js} +90 -89
- package/dist/src/{landing/landing-check-failures.js → merge/merge-check-failures.js} +87 -41
- package/dist/src/{landing/landing-core.js → merge/merge-core.js} +119 -95
- package/dist/src/{landing/landing-diff.js → merge/merge-diff.js} +1 -1
- package/dist/src/merge/merge-drain.js +212 -0
- package/dist/src/{landing/landing-git.js → merge/merge-git.js} +94 -21
- package/dist/src/merge/merge-pipeline.js +99 -0
- package/dist/src/{landing/landing-questions.js → merge/merge-questions.js} +9 -6
- package/dist/src/merge/merge-queue-render.js +75 -0
- package/dist/src/{landing/landing-queue.js → merge/merge-queue.js} +95 -36
- package/dist/src/merge/merge-slot.js +340 -0
- package/dist/src/{landing/landing-stack.js → merge/merge-stack.js} +66 -62
- package/dist/src/{landing/landing-merge.js → merge/merge-to-main.js} +72 -62
- package/dist/src/merge/merge-verify.js +212 -0
- package/dist/src/notes-cli.js +97 -0
- package/dist/src/operator/operator-commands.js +154 -47
- package/dist/src/operator/operator-intent.js +87 -49
- package/dist/src/operator/operator-requests.js +52 -52
- package/dist/src/operator/retire.js +62 -27
- package/dist/src/operator/revert.js +71 -0
- package/dist/src/orchestrator/orchestrator-launch.js +74 -14
- package/dist/src/orchestrator/orchestrator-scheduling.js +129 -44
- package/dist/src/orchestrator/orchestrator.js +158 -100
- package/dist/src/orchestrator/retention.js +29 -12
- package/dist/src/orchestrator/startup-migration-steps.js +51 -0
- package/dist/src/orchestrator/startup-migrations.js +40 -0
- package/dist/src/paths.js +128 -37
- package/dist/src/pi/pi-args.js +26 -3
- package/dist/src/pi/pi-backend.js +15 -23
- package/dist/src/pi/pi-bin.js +18 -12
- package/dist/src/pi/pi-event-line.js +17 -1
- package/dist/src/pi/pi-failure.js +87 -0
- package/dist/src/pi/pi-models.js +126 -38
- package/dist/src/pi/pi-run-result.js +1 -1
- package/dist/src/pi/pi-settings.js +86 -0
- package/dist/src/pi/pi-stream.js +131 -107
- package/dist/src/pi/pi-watchdogs.js +47 -43
- package/dist/src/pi-extension/bounded-output.js +20 -5
- package/dist/src/pi-extension/context-budget.js +3 -1
- package/dist/src/pi-extension/context-shake.js +54 -21
- package/dist/src/pi-extension/context-window.js +37 -0
- package/dist/src/pi-extension/full-output.js +2 -2
- package/dist/src/pi-extension/strip-thinking.js +80 -0
- package/dist/src/pi-extension/trim-system-prompt.js +38 -0
- package/dist/src/process/launch-services.js +11 -10
- package/dist/src/process/process-table.js +1 -1
- package/dist/src/process/process.js +7 -7
- package/dist/src/process/run-marker.js +29 -6
- package/dist/src/process/supervisor.js +47 -25
- package/dist/src/prompt/dialect.js +30 -10
- package/dist/src/prompt/gate-prompts.js +170 -67
- package/dist/src/prompt/principles.js +1 -0
- package/dist/src/prompt/prompt-followup.js +35 -20
- package/dist/src/prompt/prompt.js +249 -91
- package/dist/src/redeploy/redeploy-policy.js +10 -10
- package/dist/src/redeploy/redeploy.js +6 -4
- package/dist/src/redeploy/redeployer.js +63 -55
- package/dist/src/redeploy/self-reload.js +1 -1
- package/dist/src/report/report-data.js +264 -255
- package/dist/src/report/report-fold.js +353 -0
- package/dist/src/report/report-render.js +270 -33
- package/dist/src/request-timeouts.js +1 -1
- package/dist/src/review/known-flakes.js +34 -14
- package/dist/src/review/protected-edits.js +33 -0
- package/dist/src/review/review-followup.js +16 -4
- package/dist/src/review/review-precheck.js +14 -13
- package/dist/src/review/review-verdict.js +14 -0
- package/dist/src/review/review.js +81 -39
- package/dist/src/review/secret-leaks.js +127 -0
- package/dist/src/review/suite-rerun.js +4 -3
- package/dist/src/roles/legacy-role-ids.js +21 -0
- package/dist/src/roles/legacy-role-migration.js +62 -0
- package/dist/src/roles/loop-ids.js +19 -2
- package/dist/src/roles/role-catalog.js +125 -135
- package/dist/src/roles/role-guidance.js +64 -31
- package/dist/src/roles/role-labels.js +10 -0
- package/dist/src/roles/role-render.js +194 -18
- package/dist/src/roles/role-view.js +216 -17
- package/dist/src/roles/roles.js +18 -15
- package/dist/src/scheduling/backoff.js +29 -19
- package/dist/src/scheduling/claims.js +25 -9
- package/dist/src/scheduling/once-round.js +11 -11
- package/dist/src/scheduling/quiet-hours.js +25 -32
- package/dist/src/scheduling/scheduling.js +43 -24
- package/dist/src/scheduling/{work-landed-cache.js → work-merged-cache.js} +14 -14
- package/dist/src/status/status-budget.js +115 -0
- package/dist/src/status/status-data.js +77 -184
- package/dist/src/status/status-inbox.js +47 -0
- package/dist/src/status/status-install.js +27 -0
- package/dist/src/status/status-polls.js +68 -33
- package/dist/src/status/status-roles.js +105 -0
- package/dist/src/{fleet → team}/error-storm.js +10 -10
- package/dist/src/{fleet → team}/failure-spread.js +8 -8
- package/dist/src/{fleet → team}/orchestrator-info.js +86 -18
- package/dist/src/{fleet → team}/reclaim.js +5 -4
- package/dist/src/{fleet/fleet-hold.js → team/team-hold.js} +55 -21
- package/dist/src/{fleet/fleet-polls.js → team/team-polls.js} +116 -65
- package/dist/src/{fleet/fleet-state.js → team/team-state.js} +62 -37
- package/dist/src/text/datetime.js +42 -2
- package/dist/src/text/format.js +10 -1
- package/dist/src/text/markdown.js +1 -1
- package/dist/src/text/phrases.js +35 -34
- package/dist/src/text/suggest.js +3 -2
- package/dist/src/text/text.js +2 -2
- package/dist/src/tick/qa-coverage.js +2 -1
- package/dist/src/tick/stage-check.js +147 -26
- package/dist/src/tick/telemetry-digest.js +10 -9
- package/dist/src/tick/tick-apply.js +101 -72
- package/dist/src/tick/tick-detail-data.js +32 -18
- package/dist/src/tick/tick-detail.js +62 -21
- package/dist/src/tick/tick-finalize.js +29 -22
- package/dist/src/tick/tick-outcome.js +2 -1
- package/dist/src/tick/tick-prompt.js +94 -26
- package/dist/src/tick/tick-resume.js +29 -13
- package/dist/src/tick/tick-stage.js +91 -47
- package/dist/src/tick/tick-timing.js +60 -59
- package/dist/src/tick/tick-usage.js +53 -23
- package/dist/src/tick/tick-verdict.js +76 -10
- package/dist/src/ui/badges.js +118 -67
- package/dist/src/ui/gui/gui-client-boot.js +209 -30
- package/dist/src/ui/gui/gui-client-composer.js +102 -23
- package/dist/src/ui/gui/gui-client-drawer.js +330 -75
- package/dist/src/ui/gui/gui-client-history.js +96 -38
- package/dist/src/ui/gui/gui-client-labels.js +24 -0
- package/dist/src/ui/gui/gui-client-loops.js +94 -52
- package/dist/src/ui/gui/gui-client-markdown.js +1 -0
- package/dist/src/ui/gui/gui-client-model.js +63 -43
- package/dist/src/ui/gui/gui-client-operator.js +129 -39
- package/dist/src/ui/gui/gui-client-pending.js +36 -32
- package/dist/src/ui/gui/gui-client-report.js +339 -46
- package/dist/src/ui/gui/gui-client-settings.js +148 -14
- package/dist/src/ui/gui/gui-client-sound.js +2 -1
- package/dist/src/ui/gui/{gui-client-fleet.js → gui-client-team.js} +196 -72
- package/dist/src/ui/gui/gui-client.js +26 -20
- package/dist/src/ui/gui/gui-page.js +19 -19
- package/dist/src/ui/gui/gui-styles.js +12 -4
- package/dist/src/ui/progress-data.js +5 -3
- package/dist/src/ui/status-model.js +184 -122
- package/dist/src/ui/status-payload.js +119 -32
- package/dist/src/ui/status-render.js +122 -52
- package/dist/src/ui/team-alerts.js +341 -0
- package/dist/src/ui/tick-progress-model.js +14 -14
- package/dist/src/ui/tone.js +11 -8
- package/dist/src/ui/transcript-tail.js +1 -0
- package/dist/src/ui/transcript.js +23 -16
- package/dist/src/ui/tui/tui-app.js +1 -0
- package/dist/src/ui/tui/tui-backlog.js +85 -11
- package/dist/src/ui/tui/tui-editor-answer.js +97 -0
- package/dist/src/ui/tui/tui-editor-attach.js +107 -0
- package/dist/src/ui/tui/tui-editor-brief.js +107 -0
- package/dist/src/ui/tui/tui-editor-budget.js +155 -0
- package/dist/src/ui/tui/tui-editor-ctx.js +1 -0
- package/dist/src/ui/tui/tui-editor-entry.js +230 -0
- package/dist/src/ui/tui/tui-editor-interval.js +122 -0
- package/dist/src/ui/tui/tui-editor-notes.js +114 -0
- package/dist/src/ui/tui/tui-editor-pause.js +266 -0
- package/dist/src/ui/tui/tui-editor-prompt.js +95 -0
- package/dist/src/ui/tui/tui-editor-queued.js +98 -0
- package/dist/src/ui/tui/tui-editor-quiet.js +106 -0
- package/dist/src/ui/tui/tui-editor-retire.js +83 -0
- package/dist/src/ui/tui/tui-editor-search.js +73 -0
- package/dist/src/ui/tui/tui-editor-session.js +97 -0
- package/dist/src/ui/tui/tui-editors.js +152 -0
- package/dist/src/ui/tui/tui-frame.js +67 -55
- package/dist/src/ui/tui/tui-history.js +12 -7
- package/dist/src/ui/tui/tui-input.js +49 -44
- package/dist/src/ui/tui/tui-keymap.js +1 -0
- package/dist/src/ui/tui/tui-keys.js +91 -1704
- package/dist/src/ui/tui/tui-pane-activity.js +99 -0
- package/dist/src/ui/tui/tui-pane-backlog.js +224 -0
- package/dist/src/ui/tui/tui-pane-brief.js +30 -0
- package/dist/src/ui/tui/tui-pane-ctx.js +11 -0
- package/dist/src/ui/tui/tui-pane-health.js +124 -0
- package/dist/src/ui/tui/tui-pane-history.js +316 -0
- package/dist/src/ui/tui/tui-pane-pending.js +74 -0
- package/dist/src/ui/tui/tui-pane-queued.js +143 -0
- package/dist/src/ui/tui/tui-pane-report.js +122 -0
- package/dist/src/ui/tui/tui-pane-session.js +101 -0
- package/dist/src/ui/tui/tui-pane-transcript.js +150 -0
- package/dist/src/ui/tui/tui-pane.js +66 -28
- package/dist/src/ui/tui/tui-panes.js +294 -0
- package/dist/src/ui/tui/tui.js +45 -25
- package/dist/src/verdict/fix-claim.js +141 -38
- package/dist/src/verdict/no-change.js +19 -0
- package/dist/src/verdict/refusal.js +92 -8
- package/dist/src/verdict/reply-contract.js +17 -5
- package/dist/src/version.js +3 -2
- package/package.json +4 -2
- package/dist/src/agent/mcp/role-notes-server.js +0 -160
- package/dist/src/landing/backlog-conflicts.js +0 -116
- package/dist/src/landing/landing-drain.js +0 -204
- package/dist/src/landing/landing-pipeline.js +0 -96
- package/dist/src/landing/landing-queue-render.js +0 -31
- package/dist/src/landing/landing-slot.js +0 -246
- package/dist/src/landing/landing-vetting.js +0 -196
- package/dist/src/pi-extension/role-notes.js +0 -40
- package/dist/src/ui/fleet-alerts.js +0 -174
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
// vocabulary: plain
|
|
1
2
|
/** The dashboard's Settings view, browser-side: the curated top-level config keys
|
|
2
3
|
* (EDITABLE_CONFIG_KEYS's set, mirrored here for the labels) as label + current value +
|
|
3
|
-
* inline field + Save + Clear, one row per key
|
|
4
|
+
* inline field + Save + Clear, one row per key (the Notify row also has Send test, which
|
|
5
|
+
* posts to POST /api/notify-test). Values load once through GET /api/config when
|
|
4
6
|
* the view is first opened — no polling loop of its own; a re-click of the tab refetches, like
|
|
5
7
|
* the other views' refresh-on-open. Save posts {key, value} to POST /api/config-set — the
|
|
6
8
|
* same setConfigKey write path `tumwater config set` uses — and Clear posts {key} to
|
|
@@ -9,8 +11,18 @@
|
|
|
9
11
|
* success/error toast pattern the composer's send uses (showFlash). Spliced into
|
|
10
12
|
* gui-client.ts's script, reaching its helpers (esc, $, getJson, postJson, showFlash) through
|
|
11
13
|
* that concatenation. A second card, "Health check", runs the same checks as `tumwater doctor`
|
|
12
|
-
* through GET /api/doctor on each open (and on its Re-run button) and paints the report
|
|
14
|
+
* through GET /api/doctor on each open (and on its Re-run button) and paints the report; a
|
|
15
|
+
* third, "Disabled roles", lists every disabled role (GET /api/retire), each with an Enable
|
|
16
|
+
* button (POST /api/role-enable) and — for a role that still keeps worktree/branch leftovers — a
|
|
17
|
+
* two-click Retire button (POST /api/retire). */
|
|
13
18
|
export const GUI_CLIENT_SETTINGS_JS = String.raw ` // settings-view:start
|
|
19
|
+
// One home for turning a thrown value into the message a flash shows: the fetch/parse/post
|
|
20
|
+
// helpers throw the server's JSON-decoded value, which for the server's own errors is an
|
|
21
|
+
// {error} object (its message on the .message field) — the three Save/Clear/Brief catch
|
|
22
|
+
// blocks that flash the outcome share this coercion so the wording cannot drift.
|
|
23
|
+
function clientErrorMessage(err) {
|
|
24
|
+
return err && err.message ? err.message : String(err);
|
|
25
|
+
}
|
|
14
26
|
// The curated keys, in display order: [key, label]. Mirrors the server's
|
|
15
27
|
// EDITABLE_CONFIG_KEYS (src/config/config-editable-keys.ts) by hand — the settings test pins
|
|
16
28
|
// this list's keys and order to that constant.
|
|
@@ -21,7 +33,7 @@ export const GUI_CLIENT_SETTINGS_JS = String.raw ` // settings-view:start
|
|
|
21
33
|
["maxDailyCostUsd", "Daily spend cap (USD)"],
|
|
22
34
|
["quietHours", "Quiet hours"],
|
|
23
35
|
["notify", "Notify hook"],
|
|
24
|
-
["
|
|
36
|
+
["backends", "Agent backends (JSON)"],
|
|
25
37
|
];
|
|
26
38
|
// One row per key: the current value into an inline field (esc'd, like every rendered
|
|
27
39
|
// value on the page), Save submits the row's form. A null (unset) key renders empty —
|
|
@@ -39,38 +51,124 @@ export const GUI_CLIENT_SETTINGS_JS = String.raw ` // settings-view:start
|
|
|
39
51
|
"<input class='field' id='set-" + k[0] + "' value='" + esc(settingsFieldValue(d[k[0]])) + "'>" +
|
|
40
52
|
"<button type='submit' class='btn btn-sm'>Save</button>" +
|
|
41
53
|
"<button type='button' class='btn btn-sm rowaction' data-action='unset'>Clear</button>" +
|
|
54
|
+
(k[0] === "notify" ? "<button type='button' class='btn btn-sm rowaction' data-action='notify-test' title='Runs the saved hook once with a synthetic merge_failed event'>Send test</button>" : "") +
|
|
42
55
|
"</form>").join("");
|
|
43
56
|
}
|
|
44
57
|
// The view's one panel: built once, values fetched on each open of the tab (the boot's
|
|
45
58
|
// switchView calls fetchSettings) — no polling loop of its own.
|
|
46
59
|
function buildSettingsView() {
|
|
47
60
|
buildOnce("settings-view", "<div class='view-head'><div><h1>Settings</h1>" +
|
|
48
|
-
"<p>The
|
|
61
|
+
"<p>The team-wide settings you edit from here; everything else lives in tumwater.json or the CLI.</p></div></div>" +
|
|
49
62
|
"<div class='card' id='settingscard'><div class='empty'>Loading…</div></div>" +
|
|
50
|
-
"<div class='card' id='doctorcard'><div class='settings-row'><strong>Health
|
|
63
|
+
"<div class='card' id='doctorcard'><div class='settings-row'><strong>Health</strong>" +
|
|
51
64
|
"<span>The same checks as <code>tumwater doctor</code>.</span>" +
|
|
65
|
+
"<label><input type='checkbox' data-action='doctor-problems'> Problems only</label>" +
|
|
52
66
|
"<button type='button' class='btn btn-sm' data-action='doctor-rerun'>Re-run</button></div>" +
|
|
53
|
-
"<div id='doctorbody'><div class='empty'>Checking…</div></div></div>"
|
|
67
|
+
"<div id='doctorbody'><div class='empty'>Checking…</div></div></div>" +
|
|
68
|
+
"<div class='card' id='retirecard'><div class='empty'>Loading…</div></div>" +
|
|
69
|
+
"<div class='card' id='briefcard'><div class='empty'>Loading…</div></div>");
|
|
54
70
|
}
|
|
55
71
|
// The Health check card's body: header, one row per check (level badge, name, detail), the
|
|
56
72
|
// verdict — everything esc'd. The pill is built inline (gui-client.ts's pill sits outside
|
|
57
|
-
// this region). A missing checks array renders no rows.
|
|
58
|
-
|
|
73
|
+
// this region). A missing checks array renders no rows. With problems (the Problems only
|
|
74
|
+
// checkbox), only the warn and fail rows render and a hidden-count line names how many ok
|
|
75
|
+
// rows were cut, mirroring tumwater doctor --problems's problemsOnly/renderDoctorProblems.
|
|
76
|
+
function renderDoctorReport(d, problems) {
|
|
59
77
|
const tones = { ok: "green", warn: "amber", fail: "red" };
|
|
60
|
-
const
|
|
78
|
+
const all = Array.isArray(d.checks) ? d.checks : [];
|
|
79
|
+
const checks = problems ? all.filter((c) => c.level !== "ok") : all;
|
|
80
|
+
const hidden = all.length - checks.length;
|
|
81
|
+
const rows = checks.map((c) =>
|
|
61
82
|
"<div class='settings-row'><span class='pill t-" + (tones[c.level] || "amber") + "'>" + esc(c.level) + "</span>" +
|
|
62
83
|
"<strong>" + esc(c.name) + "</strong><span>" + esc(c.detail) + "</span></div>").join("");
|
|
63
|
-
return "<p>" + esc(d.header) + "</p>" + rows +
|
|
84
|
+
return "<p>" + esc(d.header) + "</p>" + rows +
|
|
85
|
+
(problems && hidden > 0 ? "<p class='empty'>" + hidden + " " + (hidden === 1 ? "ok check" : "ok checks") + " hidden</p>" : "") +
|
|
86
|
+
"<p>" + esc(d.verdict) + "</p>";
|
|
64
87
|
}
|
|
88
|
+
// The last resolved doctor report and whether the card paints only its problems; the
|
|
89
|
+
// Problems only checkbox toggles the latter and repaints the cached body without rerunning
|
|
90
|
+
// the checks.
|
|
91
|
+
let lastDoctor = null;
|
|
92
|
+
let doctorProblems = false;
|
|
65
93
|
async function fetchDoctor() {
|
|
66
94
|
buildSettingsView();
|
|
67
95
|
const body = $("doctorbody");
|
|
68
96
|
body.innerHTML = "<div class='empty'>Checking…</div>";
|
|
69
97
|
try {
|
|
70
|
-
|
|
98
|
+
const report = await getJson("/api/doctor");
|
|
99
|
+
lastDoctor = report;
|
|
100
|
+
body.innerHTML = renderDoctorReport(report, doctorProblems);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
body.innerHTML = errorPanel("Health checks could not run", err, "empty");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function toggleDoctorProblems(checked) {
|
|
106
|
+
doctorProblems = checked;
|
|
107
|
+
const body = $("doctorbody");
|
|
108
|
+
if (lastDoctor !== null) body.innerHTML = renderDoctorReport(lastDoctor, doctorProblems);
|
|
109
|
+
}
|
|
110
|
+
// The Disabled roles card: every role set to enabled: false (GET /api/retire), each with an
|
|
111
|
+
// Enable button (POST /api/role-enable) and — for a role that still keeps a worktree, branch,
|
|
112
|
+
// merge ref, or paused marker — a two-click Retire button (POST /api/retire), the same removal
|
|
113
|
+
// as tumwater retire --role <id>. A role the safety rails object to shows the objections and
|
|
114
|
+
// the CLI's --force command instead: the dashboard never forces.
|
|
115
|
+
let lastRetirable = null;
|
|
116
|
+
const retireSlot = confirmSlot(paintRetirable);
|
|
117
|
+
function renderRetirable(d, armed) {
|
|
118
|
+
const rows = (d.roles || []).map((r) => {
|
|
119
|
+
const hasLeftovers = (r.wouldRemove || []).length > 0;
|
|
120
|
+
const head = "<strong>" + esc(r.role) + "</strong>" +
|
|
121
|
+
(hasLeftovers ? "<span>would remove " + r.phrases.map(esc).join(", ") + "</span>" : "<span>no leftovers to remove</span>") +
|
|
122
|
+
"<button type='button' class='btn btn-sm' data-action='enable' data-role='" + esc(r.role) + "'>Enable</button>";
|
|
123
|
+
if (r.objections.length > 0) {
|
|
124
|
+
return "<div class='settings-row'>" + head + r.objections.map((o) => "<span>" + esc(o) + "</span>").join("") +
|
|
125
|
+
"<code>tumwater retire --role " + esc(r.role) + " --force</code></div>";
|
|
126
|
+
}
|
|
127
|
+
const retireBtn = hasLeftovers ? "<button type='button' class='btn btn-sm' data-action='retire' data-role='" + esc(r.role) + "'>" +
|
|
128
|
+
(armed(r.role) ? "Confirm retire" : "Retire") + "</button>" : "";
|
|
129
|
+
return "<div class='settings-row'>" + head + retireBtn + "</div>";
|
|
130
|
+
}).join("");
|
|
131
|
+
return "<div class='settings-row'><strong>Disabled roles</strong><span>Roles set to enabled: false — re-enable one, or remove the leftovers " +
|
|
132
|
+
"the same way <code>tumwater retire --role <id></code> does.</span></div>" +
|
|
133
|
+
(rows || "<div class='empty'>No role is disabled.</div>");
|
|
134
|
+
}
|
|
135
|
+
function paintRetirable() {
|
|
136
|
+
if (lastRetirable) $("retirecard").innerHTML = renderRetirable(lastRetirable, retireSlot.armed);
|
|
137
|
+
}
|
|
138
|
+
async function fetchRetirable() {
|
|
139
|
+
buildSettingsView();
|
|
140
|
+
try {
|
|
141
|
+
lastRetirable = await getJson("/api/retire");
|
|
142
|
+
paintRetirable();
|
|
143
|
+
} catch (err) {
|
|
144
|
+
$("retirecard").innerHTML = errorPanel("Disabled roles could not load", err, "empty");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// The row's Enable button: re-enable the role through POST /api/role-enable (writing
|
|
148
|
+
// roles.<base>.enabled), flash the server's message, and refetch so the card drops the row.
|
|
149
|
+
async function enableRole(role) {
|
|
150
|
+
try {
|
|
151
|
+
const d = await postJson("/api/role-enable", { role: role });
|
|
152
|
+
showFlash(d.message);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
155
|
+
}
|
|
156
|
+
await fetchRetirable();
|
|
157
|
+
}
|
|
158
|
+
// First click arms the role's button; a second within the confirm window posts the retire.
|
|
159
|
+
async function confirmRetire(role) {
|
|
160
|
+
if (!retireSlot.armed(role)) {
|
|
161
|
+
retireSlot.arm(role);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
retireSlot.disarm();
|
|
165
|
+
try {
|
|
166
|
+
const d = await postJson("/api/retire", { role: role });
|
|
167
|
+
showFlash(d.message);
|
|
71
168
|
} catch (err) {
|
|
72
|
-
|
|
169
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
73
170
|
}
|
|
171
|
+
await fetchRetirable();
|
|
74
172
|
}
|
|
75
173
|
async function fetchSettings() {
|
|
76
174
|
buildSettingsView();
|
|
@@ -101,7 +199,7 @@ export const GUI_CLIENT_SETTINGS_JS = String.raw ` // settings-view:start
|
|
|
101
199
|
const d = await postJson("/api/config-set", { key: key, value: value });
|
|
102
200
|
showFlash(d && d.oldValue === null ? "Saved " + key + " (was unset)" : "Saved " + key);
|
|
103
201
|
} catch (err) {
|
|
104
|
-
showFlash("error: " + (err
|
|
202
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
105
203
|
}
|
|
106
204
|
}
|
|
107
205
|
// The row's Clear button: retract the key through /api/config-unset, then refetch so the
|
|
@@ -115,7 +213,43 @@ export const GUI_CLIENT_SETTINGS_JS = String.raw ` // settings-view:start
|
|
|
115
213
|
showFlash(d && d.oldValue !== undefined ? "Unset " + key + " (was " + JSON.stringify(d.oldValue) + ")" : "Nothing to unset for " + key + " — it was already the default");
|
|
116
214
|
await fetchSettings();
|
|
117
215
|
} catch (err) {
|
|
118
|
-
showFlash("error: " + (err
|
|
216
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// The Notify row's Send test button: POST /api/notify-test runs the saved hook once, the same
|
|
220
|
+
// test that "tumwater notify --test" runs. The hook can take up to 10 s, so say so first.
|
|
221
|
+
async function testNotify() {
|
|
222
|
+
showFlash("Sending a test notification…");
|
|
223
|
+
try {
|
|
224
|
+
const d = await postJson("/api/notify-test", {});
|
|
225
|
+
showFlash((d.passed ? "" : "error: ") + d.message);
|
|
226
|
+
} catch (err) {
|
|
227
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// The Brief card: the brief file's name and the prompt in a textarea, filled from
|
|
231
|
+
// GET /api/brief on each open. The form is deliberately not a settings-row, so the boot's
|
|
232
|
+
// delegated settings submit listener never routes it to saveSetting.
|
|
233
|
+
async function fetchBrief() {
|
|
234
|
+
buildSettingsView();
|
|
235
|
+
const card = $("briefcard");
|
|
236
|
+
try {
|
|
237
|
+
const d = await getJson("/api/brief");
|
|
238
|
+
card.innerHTML = "<form class='brief-form'><strong>Brief</strong> <span class='settings-key'>" + esc(d.file) + "</span>" +
|
|
239
|
+
"<textarea class='field' id='brief-text' rows='12'>" + esc(d.prompt) + "</textarea>" +
|
|
240
|
+
"<button type='submit' class='btn btn-sm'>Save</button></form>";
|
|
241
|
+
} catch (err) {
|
|
242
|
+
card.innerHTML = errorPanel("Brief could not load", err, "empty");
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Save posts the textarea's text to POST /api/brief — the same checks and commit as
|
|
246
|
+
// tumwater brief --file — and flashes the outcome.
|
|
247
|
+
async function saveBrief(form) {
|
|
248
|
+
try {
|
|
249
|
+
const d = await postJson("/api/brief", { prompt: form.querySelector("textarea").value });
|
|
250
|
+
showFlash(!d.changed ? "Brief unchanged" : d.committed ? "Brief saved (committed to main)" : "Brief saved");
|
|
251
|
+
} catch (err) {
|
|
252
|
+
showFlash("error: " + clientErrorMessage(err));
|
|
119
253
|
}
|
|
120
254
|
}
|
|
121
255
|
// settings-view:end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
// vocabulary: plain
|
|
1
2
|
/** The dashboard's sound layer, browser-side: one short synthesized cue when a new needs-you
|
|
2
3
|
* alert appears (a failing loop, a red main, a spent budget, a lost server), scoped from
|
|
3
|
-
* docs/feature-gui-audio-sound-effects.md to the alerts cue — the one moment the
|
|
4
|
+
* docs/feature-gui-audio-sound-effects.md to the alerts cue — the one moment the team
|
|
4
5
|
* genuinely needs a human. Client-side only: Web Audio is a browser built-in, so the zero
|
|
5
6
|
* runtime dependencies principle holds, and every path degrades to silence — no AudioContext,
|
|
6
7
|
* no user gesture yet, or a muted preference all leave the page quiet and error-free. Spliced
|