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.
- package/README.md +27 -13
- package/dist/build-info.json +2 -2
- package/dist/src/agent/agent-args.js +8 -9
- package/dist/src/agent/agent-backend.js +8 -6
- package/dist/src/agent/backend-traits.js +55 -25
- package/dist/src/agent/claude/claude-account.js +71 -204
- package/dist/src/agent/claude/claude-args.js +9 -6
- package/dist/src/agent/claude/claude-backend.js +10 -10
- package/dist/src/agent/claude/claude-env.js +1 -1
- package/dist/src/agent/claude/claude-stream.js +6 -4
- package/dist/src/agent/claude/claude-write-guard.js +49 -0
- package/dist/src/agent/claude/write-guard-hook.js +13 -0
- package/dist/src/agent/codex/codex-account.js +119 -0
- package/dist/src/agent/codex/codex-args.js +181 -0
- package/dist/src/agent/codex/codex-backend.js +279 -0
- package/dist/src/agent/codex/codex-catalog.js +97 -0
- package/dist/src/agent/codex/codex-env.js +18 -0
- package/dist/src/agent/codex/codex-hook-trust.js +246 -0
- package/dist/src/agent/codex/codex-patch-paths.js +36 -0
- package/dist/src/agent/codex/codex-rollout.js +179 -0
- package/dist/src/agent/codex/codex-stream.js +404 -0
- package/dist/src/agent/codex/codex-write-guard.js +86 -0
- package/dist/src/agent/codex/write-guard-hook.js +12 -0
- package/dist/src/agent/image-input.js +29 -24
- package/dist/src/agent/notes-shim.js +11 -12
- package/dist/src/agent/opencode/opencode-args.js +0 -1
- package/dist/src/agent/opencode/opencode-backend.js +12 -9
- package/dist/src/agent/opencode/opencode-catalog.js +55 -29
- package/dist/src/agent/opencode/opencode-config.js +19 -14
- package/dist/src/agent/opencode/opencode-env.js +0 -1
- package/dist/src/agent/opencode/opencode-session-id.js +1 -2
- package/dist/src/agent/opencode/opencode-stream.js +1 -1
- package/dist/src/agent/opencode/write-guard-plugin/index.js +48 -0
- package/dist/src/agent/role-notes-write.js +5 -6
- package/dist/src/agent/run-agent.js +465 -448
- package/dist/src/agent/run-settle.js +214 -0
- package/dist/src/agent/session-ledger.js +86 -16
- package/dist/src/agent/subscription-account.js +220 -0
- package/dist/src/agent/write-guard.js +148 -0
- package/dist/src/backlog/backlog-archive.js +281 -55
- package/dist/src/backlog/backlog-cli-view.js +255 -0
- package/dist/src/backlog/backlog-cli.js +91 -335
- package/dist/src/backlog/backlog-commit.js +20 -13
- package/dist/src/backlog/backlog-eligibility.js +193 -242
- package/dist/src/backlog/backlog-index.js +149 -0
- package/dist/src/backlog/backlog-md.js +54 -6
- package/dist/src/backlog/backlog-parts.js +264 -0
- package/dist/src/backlog/backlog-release.js +134 -0
- package/dist/src/backlog/backlog-render.js +27 -0
- package/dist/src/backlog/backlog-structure.js +99 -156
- package/dist/src/backlog/backlog-write.js +40 -127
- package/dist/src/backlog/backlog.js +21 -6
- package/dist/src/backlog/question-answer.js +21 -15
- package/dist/src/baseline/main-baseline.js +89 -20
- package/dist/src/baseline/main-guardrails.js +136 -0
- package/dist/src/baseline/main-red.js +153 -36
- package/dist/src/baseline/main-watch.js +232 -0
- package/dist/src/brief/brief-edit.js +12 -12
- package/dist/src/brief/brief.js +31 -51
- package/dist/src/budget/budget-fallback-view.js +288 -0
- package/dist/src/budget/budget-wiring.js +158 -0
- package/dist/src/budget/budget.js +31 -20
- package/dist/src/budget/fallback-breaker.js +26 -27
- package/dist/src/build/build-check-detect.js +23 -15
- package/dist/src/build/build-check-events.js +25 -6
- package/dist/src/build/build-check-report.js +49 -9
- package/dist/src/build/build-check-scoped.js +18 -11
- package/dist/src/build/build-check.js +2 -1
- package/dist/src/build/build-info.js +2 -3
- package/dist/src/build/build-stage.js +9 -14
- package/dist/src/build/dep-install.js +65 -3
- package/dist/src/change/change-data.js +123 -31
- package/dist/src/change/change-render.js +46 -5
- package/dist/src/cli/brief-command.js +3 -4
- package/dist/src/cli/cli-args.js +181 -33
- package/dist/src/cli/cli-command-args.js +46 -18
- package/dist/src/cli/cli-editor.js +2 -1
- package/dist/src/cli/cli-flag-specs.js +183 -45
- package/dist/src/cli/cli-init.js +51 -0
- package/dist/src/cli/cli-marker-commands.js +4 -4
- package/dist/src/cli/cli-query-commands.js +291 -598
- package/dist/src/cli/cli-repo-gate.js +11 -1
- package/dist/src/cli/cli-review-commands.js +113 -0
- package/dist/src/cli/cli-role-command.js +525 -0
- package/dist/src/cli/cli-start-summary.js +167 -0
- package/dist/src/cli/{cli-run.js → cli-start.js} +193 -237
- package/dist/src/cli/completion.js +169 -22
- package/dist/src/cli/config-commands.js +58 -26
- package/dist/src/cli/follow-view.js +75 -0
- package/dist/src/cli/help.js +258 -82
- package/dist/src/cli/log-commands.js +164 -85
- package/dist/src/cli/question-commands.js +211 -10
- package/dist/src/cli.js +173 -45
- package/dist/src/collections.js +56 -13
- package/dist/src/concurrency/check-permit.js +20 -3
- package/dist/src/concurrency/lock.js +17 -13
- package/dist/src/concurrency/provider-lease.js +44 -8
- package/dist/src/concurrency/semaphore.js +102 -26
- package/dist/src/config/config-aliases.js +0 -1
- package/dist/src/config/config-editable-keys.js +16 -1
- package/dist/src/config/config-fallbacks.js +94 -56
- package/dist/src/config/config-field-checks.js +40 -10
- package/dist/src/config/config-keys.js +30 -8
- package/dist/src/config/config-live.js +63 -24
- package/dist/src/config/config-request.js +137 -0
- package/dist/src/config/config-schema.js +31 -24
- package/dist/src/config/config-selector-checks.js +123 -0
- package/dist/src/config/config-validation-agents.js +80 -0
- package/dist/src/config/config-validation-model.js +116 -0
- package/dist/src/config/config-validation.js +169 -222
- package/dist/src/config/config-views.js +136 -54
- package/dist/src/config/config-write-core.js +135 -0
- package/dist/src/config/config-write.js +164 -265
- package/dist/src/config/config.js +53 -38
- package/dist/src/config/model-selector.js +34 -34
- package/dist/src/doctor/doctor-backlog-bugs.js +330 -0
- package/dist/src/doctor/doctor-backlog-plans.js +398 -0
- package/dist/src/doctor/doctor-backlog.js +249 -512
- package/dist/src/doctor/doctor-check-names.js +85 -0
- package/dist/src/doctor/doctor-checks.js +61 -593
- package/dist/src/doctor/doctor-claude-checks.js +142 -0
- package/dist/src/doctor/doctor-codex-checks.js +276 -0
- package/dist/src/doctor/doctor-contention-checks.js +506 -0
- package/dist/src/doctor/doctor-fallback-checks.js +130 -0
- package/dist/src/doctor/doctor-holds.js +80 -66
- package/dist/src/doctor/doctor-install.js +2 -1
- package/dist/src/doctor/doctor-model-checks.js +216 -537
- package/dist/src/doctor/doctor-notify.js +9 -5
- package/dist/src/doctor/doctor-opencode-checks.js +164 -0
- package/dist/src/doctor/doctor-orphans.js +182 -63
- package/dist/src/doctor/doctor-pi-checks.js +62 -0
- package/dist/src/doctor/doctor-project-checks.js +397 -0
- package/dist/src/doctor/doctor.js +126 -77
- package/dist/src/doctor/image-probe.js +21 -8
- package/dist/src/doctor/outcome.js +3 -2
- package/dist/src/doctor/probe.js +21 -12
- package/dist/src/events/event-format.js +185 -89
- package/dist/src/events/event-labels.js +11 -5
- package/dist/src/events/event-legacy.js +39 -15
- package/dist/src/events/event-read.js +52 -39
- package/dist/src/events/event-tally.js +16 -0
- package/dist/src/events/event-window.js +80 -26
- package/dist/src/events/events.js +30 -13
- package/dist/src/events/notify.js +7 -7
- package/dist/src/failure/failure-cluster.js +12 -12
- package/dist/src/failure/failure-data.js +65 -60
- package/dist/src/failure/failure-render.js +29 -21
- package/dist/src/failure/failure-state-change.js +17 -12
- package/dist/src/failure/time-spend.js +35 -35
- package/dist/src/files/file-queue.js +17 -0
- package/dist/src/files/files.js +111 -35
- package/dist/src/files/json-files.js +3 -3
- package/dist/src/files/json-object.js +28 -7
- package/dist/src/files/stat-cache.js +2 -2
- package/dist/src/files/tail.js +1 -1
- package/dist/src/gates/bootstrap-gates.js +4 -5
- package/dist/src/gates/budget-gates.js +88 -225
- package/dist/src/gates/disk-gate.js +1 -1
- package/dist/src/gates/gate-polls.js +101 -143
- package/dist/src/gates/maintenance-quota.js +37 -30
- package/dist/src/gates/pause-gates.js +28 -10
- package/dist/src/gates/readiness.js +7 -3
- package/dist/src/gates/role-cap-gates.js +8 -8
- package/dist/src/gates/startup-gate.js +94 -32
- package/dist/src/gates/streak-gate.js +54 -30
- package/dist/src/git/commit-message.js +89 -46
- package/dist/src/git/git-diff.js +16 -10
- package/dist/src/git/git-run.js +79 -38
- package/dist/src/git/git.js +54 -34
- package/dist/src/git/slot-salvage.js +253 -0
- package/dist/src/git/slots-state.js +6 -6
- package/dist/src/git/worktree-pool.js +132 -38
- package/dist/src/git/worktree-use.js +4 -11
- package/dist/src/git/worktree.js +94 -37
- package/dist/src/gui/gui-admin-endpoints.js +96 -0
- package/dist/src/gui/gui-args.js +79 -8
- package/dist/src/gui/gui-backlog-commands.js +43 -19
- package/dist/src/gui/gui-backlog-endpoints.js +156 -0
- package/dist/src/gui/gui-command.js +26 -13
- package/dist/src/gui/gui-config-commands.js +168 -80
- package/dist/src/gui/gui-endpoint-commands.js +5 -4
- package/dist/src/gui/gui-endpoint-common.js +4 -4
- package/dist/src/gui/gui-endpoints.js +11 -380
- package/dist/src/gui/gui-history-endpoints.js +301 -0
- package/dist/src/gui/gui-operator-commands.js +235 -13
- package/dist/src/gui/gui-prompt-commands.js +26 -20
- package/dist/src/gui/gui-report-endpoints.js +97 -0
- package/dist/src/gui/gui-server.js +26 -5
- package/dist/src/gui/gui-team-commands.js +7 -7
- package/dist/src/gui/http-body.js +1 -1
- package/dist/src/history/history-data.js +122 -234
- package/dist/src/history/history-queued.js +155 -0
- package/dist/src/history/history-render.js +42 -22
- package/dist/src/history/history.js +190 -49
- package/dist/src/inbox/inbox-attachments.js +29 -30
- package/dist/src/inbox/inbox-cancel.js +10 -11
- package/dist/src/inbox/inbox-edit.js +9 -9
- package/dist/src/inbox/inbox-submit.js +18 -18
- package/dist/src/inbox/inbox-top.js +28 -17
- package/dist/src/inbox/inbox.js +42 -43
- package/dist/src/inbox/pending-prompt.js +26 -26
- package/dist/src/inbox/prompt-commands.js +62 -49
- package/dist/src/inbox/prompt-not-before.js +2 -2
- package/dist/src/init/init-templates.js +1 -2
- package/dist/src/init/init.js +28 -23
- package/dist/src/merge/backlog-conflicts.js +215 -35
- package/dist/src/merge/merge-batch.js +14 -8
- package/dist/src/merge/merge-cancel.js +53 -0
- package/dist/src/merge/merge-check-failures.js +44 -22
- package/dist/src/merge/merge-core.js +58 -32
- package/dist/src/merge/merge-diff.js +5 -4
- package/dist/src/merge/merge-drain.js +45 -19
- package/dist/src/merge/merge-git.js +177 -38
- package/dist/src/merge/merge-pipeline.js +15 -3
- package/dist/src/merge/merge-post-review.js +214 -0
- package/dist/src/merge/merge-queue-render.js +48 -11
- package/dist/src/merge/merge-queue.js +52 -15
- package/dist/src/merge/merge-requeue.js +103 -0
- package/dist/src/merge/merge-slot.js +61 -16
- package/dist/src/merge/merge-stack.js +27 -11
- package/dist/src/merge/merge-to-main.js +77 -26
- package/dist/src/merge/merge-top.js +83 -0
- package/dist/src/merge/merge-verify.js +75 -18
- package/dist/src/notes-cli.js +35 -15
- package/dist/src/operator/operator-commands.js +192 -81
- package/dist/src/operator/operator-intent.js +69 -42
- package/dist/src/operator/operator-requests.js +35 -40
- package/dist/src/operator/retire.js +5 -6
- package/dist/src/operator/revert.js +142 -34
- package/dist/src/orchestrator/orchestrator-launch.js +60 -52
- package/dist/src/orchestrator/orchestrator-poll.js +352 -0
- package/dist/src/orchestrator/orchestrator-scheduling.js +71 -370
- package/dist/src/orchestrator/orchestrator.js +129 -369
- package/dist/src/orchestrator/retention.js +42 -8
- package/dist/src/orchestrator/scheduling-admit.js +116 -0
- package/dist/src/orchestrator/scheduling-scope.js +245 -0
- package/dist/src/orchestrator/scheduling-skip.js +195 -0
- package/dist/src/orchestrator/startup-migration-steps.js +8 -7
- package/dist/src/orchestrator/startup-migrations.js +11 -7
- package/dist/src/paths.js +126 -49
- package/dist/src/pi/command-shape.js +12 -1
- package/dist/src/pi/pi-args.js +6 -4
- package/dist/src/pi/pi-backend.js +6 -6
- package/dist/src/pi/pi-bin.js +54 -63
- package/dist/src/pi/pi-listed-models.js +53 -0
- package/dist/src/pi/pi-models.js +63 -30
- package/dist/src/pi/pi-run-result.js +1 -1
- package/dist/src/pi/pi-settings.js +1 -1
- package/dist/src/pi/pi-stream.js +6 -6
- package/dist/src/pi/pi-watchdogs.js +18 -19
- package/dist/src/pi-extension/bounded-output.js +5 -3
- package/dist/src/pi-extension/context-budget.js +2 -2
- package/dist/src/pi-extension/context-shake.js +1 -1
- package/dist/src/pi-extension/context-window.js +0 -1
- package/dist/src/pi-extension/full-output.js +3 -10
- package/dist/src/pi-extension/strip-thinking.js +0 -1
- package/dist/src/pi-extension/trim-system-prompt.js +3 -4
- package/dist/src/pi-extension/write-guard.js +37 -0
- package/dist/src/process/launch-services.js +1 -2
- package/dist/src/process/node-bin.js +16 -0
- package/dist/src/process/process-group.js +8 -18
- package/dist/src/process/process.js +41 -2
- package/dist/src/process/run-marker.js +26 -6
- package/dist/src/process/supervisor.js +22 -21
- package/dist/src/prompt/dialect.js +17 -2
- package/dist/src/prompt/gate-notes.js +203 -0
- package/dist/src/prompt/gate-prompts.js +150 -217
- package/dist/src/prompt/notes-backlog.js +184 -0
- package/dist/src/prompt/principles.js +1 -2
- package/dist/src/prompt/prompt-followup.js +19 -14
- package/dist/src/prompt/prompt.js +131 -204
- package/dist/src/redeploy/redeploy-policy.js +24 -19
- package/dist/src/redeploy/redeploy-probes.js +1 -1
- package/dist/src/redeploy/redeploy.js +2 -3
- package/dist/src/redeploy/redeployer.js +20 -20
- package/dist/src/redeploy/self-reload.js +2 -1
- package/dist/src/report/report-data.js +188 -124
- package/dist/src/report/report-fold.js +130 -54
- package/dist/src/report/report-main-red.js +55 -0
- package/dist/src/report/report-render.js +136 -65
- package/dist/src/report/report-types.js +1 -0
- package/dist/src/report/report.js +23 -9
- package/dist/src/request-timeouts.js +2 -2
- package/dist/src/review/diff-rules.js +53 -0
- package/dist/src/review/known-flakes.js +112 -1
- package/dist/src/review/post-merge-review-accept.js +51 -0
- package/dist/src/review/post-merge-review-render.js +112 -0
- package/dist/src/review/post-merge-review.js +239 -0
- package/dist/src/review/protected-edits.js +24 -10
- package/dist/src/review/quarantine-render.js +65 -0
- package/dist/src/review/review-followup.js +8 -8
- package/dist/src/review/review-precheck.js +66 -23
- package/dist/src/review/review-run.js +395 -0
- package/dist/src/review/review-verdict.js +2 -2
- package/dist/src/review/review.js +180 -401
- package/dist/src/review/secret-leaks.js +36 -16
- package/dist/src/review/suite-rerun.js +0 -1
- package/dist/src/roles/legacy-role-migration.js +80 -7
- package/dist/src/roles/role-catalog.js +127 -12
- package/dist/src/roles/role-guidance.js +65 -20
- package/dist/src/roles/role-labels.js +7 -5
- package/dist/src/roles/role-render.js +108 -56
- package/dist/src/roles/role-view.js +95 -56
- package/dist/src/roles/roles.js +33 -33
- package/dist/src/roles/runner-ids.js +97 -0
- package/dist/src/run/acceptance-greps.js +119 -0
- package/dist/src/run/ci-parity.js +121 -0
- package/dist/src/run/feedback-filings.js +51 -0
- package/dist/src/run/qa-coverage.js +125 -0
- package/dist/src/{tick/tick-apply.js → run/run-apply.js} +95 -94
- package/dist/src/run/run-detail-data.js +175 -0
- package/dist/src/run/run-detail-render.js +91 -0
- package/dist/src/run/run-detail.js +168 -0
- package/dist/src/{tick/tick-finalize.js → run/run-finalize.js} +73 -60
- package/dist/src/{tick/tick-outcome.js → run/run-outcome.js} +6 -7
- package/dist/src/{tick/tick-prompt.js → run/run-prompt.js} +122 -73
- package/dist/src/{tick/tick-resume.js → run/run-resume.js} +55 -26
- package/dist/src/{tick/tick-stage.js → run/run-stage.js} +170 -83
- package/dist/src/{tick/tick-timing.js → run/run-timing.js} +43 -41
- package/dist/src/{tick/tick-usage.js → run/run-usage.js} +45 -37
- package/dist/src/{tick/tick-verdict.js → run/run-verdict.js} +105 -57
- package/dist/src/run/selfcheck-digest.js +40 -0
- package/dist/src/run/stage-backlog-checks.js +249 -0
- package/dist/src/run/stage-check.js +178 -0
- package/dist/src/run/stage-checks-shared.js +65 -0
- package/dist/src/run/stage-name-checks.js +204 -0
- package/dist/src/run/stage-path-checks.js +231 -0
- package/dist/src/run/stage-prose-checks.js +261 -0
- package/dist/src/runner/leftover.js +216 -0
- package/dist/src/{loop → runner}/model-fallback.js +12 -12
- package/dist/src/runner/revision.js +191 -0
- package/dist/src/{loop/loop-fallback.js → runner/runner-fallback.js} +8 -8
- package/dist/src/runner/runner-outcome.js +109 -0
- package/dist/src/{loop/loop-pi.js → runner/runner-pi.js} +140 -131
- package/dist/src/{loop/loop-recovery.js → runner/runner-recovery.js} +39 -18
- package/dist/src/{loop/loop-tick.js → runner/runner-run.js} +236 -245
- package/dist/src/{loop/loop-state.js → runner/runner-state-load.js} +61 -114
- package/dist/src/runner/runner-state.js +103 -0
- package/dist/src/{loop/loop.js → runner/runner.js} +123 -120
- package/dist/src/scheduling/backoff.js +38 -38
- package/dist/src/scheduling/claim-entries.js +49 -0
- package/dist/src/scheduling/claims.js +35 -22
- package/dist/src/scheduling/once-round.js +22 -22
- package/dist/src/scheduling/quiet-hours.js +5 -6
- package/dist/src/scheduling/scheduling.js +74 -64
- package/dist/src/scheduling/work-merged-cache.js +2 -2
- package/dist/src/status/status-budget.js +55 -47
- package/dist/src/status/status-data.js +49 -17
- package/dist/src/status/status-inbox.js +2 -2
- package/dist/src/status/status-install.js +0 -1
- package/dist/src/status/status-polls.js +43 -28
- package/dist/src/status/status-roles.js +50 -13
- package/dist/src/team/error-storm.js +8 -8
- package/dist/src/team/failure-spread.js +2 -2
- package/dist/src/team/orchestrator-info.js +15 -9
- package/dist/src/team/reclaim.js +7 -8
- package/dist/src/team/team-hold.js +7 -7
- package/dist/src/team/team-polls.js +91 -50
- package/dist/src/team/team-state.js +8 -2
- package/dist/src/text/datetime.js +65 -18
- package/dist/src/text/format.js +48 -11
- package/dist/src/text/markdown.js +8 -5
- package/dist/src/text/phrases.js +60 -23
- package/dist/src/text/suggest.js +1 -1
- package/dist/src/text/text.js +78 -13
- package/dist/src/ui/badges.js +99 -38
- package/dist/src/ui/gui/gui-client-backlog.js +314 -0
- package/dist/src/ui/gui/gui-client-boot.js +89 -61
- package/dist/src/ui/gui/gui-client-composer.js +8 -9
- package/dist/src/ui/gui/gui-client-drawer-config.js +254 -0
- package/dist/src/ui/gui/gui-client-drawer.js +155 -289
- package/dist/src/ui/gui/gui-client-feed.js +271 -0
- package/dist/src/ui/gui/gui-client-history.js +437 -68
- package/dist/src/ui/gui/gui-client-labels.js +6 -3
- package/dist/src/ui/gui/gui-client-markdown.js +1 -2
- package/dist/src/ui/gui/gui-client-model.js +27 -36
- package/dist/src/ui/gui/gui-client-operator.js +60 -52
- package/dist/src/ui/gui/gui-client-pending.js +405 -24
- package/dist/src/ui/gui/gui-client-report-chart.js +492 -0
- package/dist/src/ui/gui/gui-client-report.js +105 -430
- package/dist/src/ui/gui/{gui-client-loops.js → gui-client-roles.js} +43 -44
- package/dist/src/ui/gui/gui-client-settings.js +163 -5
- package/dist/src/ui/gui/gui-client-team.js +36 -465
- package/dist/src/ui/gui/gui-client.js +38 -26
- package/dist/src/ui/gui/gui-icons.js +0 -2
- package/dist/src/ui/gui/gui-page.js +10 -7
- package/dist/src/ui/gui/gui-styles.js +38 -34
- package/dist/src/ui/progress-data.js +9 -11
- package/dist/src/ui/{tick-progress-model.js → run-progress-model.js} +33 -32
- package/dist/src/ui/status-model.js +133 -125
- package/dist/src/ui/status-payload.js +364 -49
- package/dist/src/ui/status-render.js +109 -82
- package/dist/src/ui/team-alerts.js +728 -62
- package/dist/src/ui/tone.js +12 -6
- package/dist/src/ui/transcript-run.js +58 -0
- package/dist/src/ui/transcript-tail.js +28 -20
- package/dist/src/ui/transcript.js +63 -23
- package/dist/src/ui/tui/tui-app.js +0 -1
- package/dist/src/ui/tui/tui-backlog.js +53 -14
- package/dist/src/ui/tui/tui-editor-answer.js +27 -31
- package/dist/src/ui/tui/tui-editor-attach.js +4 -12
- package/dist/src/ui/tui/tui-editor-backends.js +127 -0
- package/dist/src/ui/tui/tui-editor-brief.js +14 -36
- package/dist/src/ui/tui/tui-editor-budget.js +36 -39
- package/dist/src/ui/tui/tui-editor-check.js +29 -0
- package/dist/src/ui/tui/tui-editor-checks.js +28 -0
- package/dist/src/ui/tui/tui-editor-claude-reserve.js +24 -0
- package/dist/src/ui/tui/tui-editor-concurrency.js +25 -0
- package/dist/src/ui/tui/tui-editor-config.js +99 -0
- package/dist/src/ui/tui/tui-editor-entry.js +39 -64
- package/dist/src/ui/tui/tui-editor-fallback.js +31 -0
- package/dist/src/ui/tui/tui-editor-instances.js +46 -0
- package/dist/src/ui/tui/tui-editor-instructions.js +117 -0
- package/dist/src/ui/tui/tui-editor-interval.js +29 -16
- package/dist/src/ui/tui/tui-editor-model.js +29 -0
- package/dist/src/ui/tui/tui-editor-notes.js +9 -29
- package/dist/src/ui/tui/tui-editor-notify.js +25 -0
- package/dist/src/ui/tui/tui-editor-pause.js +48 -59
- package/dist/src/ui/tui/tui-editor-prompt.js +11 -16
- package/dist/src/ui/tui/tui-editor-provider-caps.js +27 -0
- package/dist/src/ui/tui/tui-editor-queued.js +5 -9
- package/dist/src/ui/tui/tui-editor-quiet.js +95 -41
- package/dist/src/ui/tui/tui-editor-retire.js +5 -13
- package/dist/src/ui/tui/tui-editor-role-enabled.js +126 -0
- package/dist/src/ui/tui/tui-editor-role-key.js +71 -0
- package/dist/src/ui/tui/tui-editor-role-model.js +28 -0
- package/dist/src/ui/tui/tui-editor-search.js +45 -33
- package/dist/src/ui/tui/tui-editor-session.js +101 -34
- package/dist/src/ui/tui/tui-editor-slots.js +24 -0
- package/dist/src/ui/tui/tui-editors.js +44 -2
- package/dist/src/ui/tui/tui-frame.js +68 -11
- package/dist/src/ui/tui/tui-history.js +8 -9
- package/dist/src/ui/tui/tui-input.js +13 -11
- package/dist/src/ui/tui/tui-keymap.js +0 -1
- package/dist/src/ui/tui/tui-keys.js +33 -9
- package/dist/src/ui/tui/tui-pane-activity.js +35 -19
- package/dist/src/ui/tui/tui-pane-backlog.js +198 -126
- package/dist/src/ui/tui/tui-pane-brief.js +0 -1
- package/dist/src/ui/tui/tui-pane-ctx.js +2 -2
- package/dist/src/ui/tui/tui-pane-health.js +168 -8
- package/dist/src/ui/tui/tui-pane-history.js +446 -82
- package/dist/src/ui/tui/tui-pane-pending.js +539 -15
- package/dist/src/ui/tui/tui-pane-queued.js +78 -57
- package/dist/src/ui/tui/tui-pane-report.js +54 -16
- package/dist/src/ui/tui/tui-pane-session.js +34 -6
- package/dist/src/ui/tui/tui-pane-transcript.js +111 -37
- package/dist/src/ui/tui/tui-pane.js +91 -28
- package/dist/src/ui/tui/tui-panes.js +153 -34
- package/dist/src/ui/tui/tui.js +18 -15
- package/dist/src/verdict/fix-claim.js +129 -33
- package/dist/src/verdict/no-change.js +4 -4
- package/dist/src/verdict/refusal.js +40 -16
- package/dist/src/verdict/reply-contract.js +77 -31
- package/dist/src/version.js +0 -1
- package/package.json +2 -1
- package/dist/src/loop/leftover.js +0 -130
- package/dist/src/loop/revision.js +0 -70
- package/dist/src/roles/loop-ids.js +0 -77
- package/dist/src/tick/qa-coverage.js +0 -108
- package/dist/src/tick/stage-check.js +0 -419
- package/dist/src/tick/telemetry-digest.js +0 -25
- package/dist/src/tick/tick-detail-data.js +0 -108
- package/dist/src/tick/tick-detail.js +0 -163
- package/dist/src/ui/gui/gui-client-sound.js +0 -53
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// vocabulary: plain
|
|
2
1
|
/**
|
|
3
2
|
* The dashboard's POST prompt-queueing command handlers (barrelled into
|
|
4
3
|
* gui/gui-endpoint-commands.ts, which routes to them from src/gui/gui-server.ts): prompt,
|
|
@@ -19,7 +18,7 @@ import { PAUSE_FOR_MAX_MS, submitRolePromptAndWake } from "../operator/operator-
|
|
|
19
18
|
import { DIRECTOR_ROLE } from "../roles/roles.js";
|
|
20
19
|
import { rejectBadQueueFileName, rejectBadRole, requirePromptText } from "./gui-args.js";
|
|
21
20
|
import { badRequest, OK_GONE, sendJson } from "./http-body.js";
|
|
22
|
-
import { errorMessage, gotSuffix } from "../text/text.js";
|
|
21
|
+
import { errorMessage, gotSuffix, joinParts } from "../text/text.js";
|
|
23
22
|
import { readPostBody, readRoleBody } from "./gui-endpoint-common.js";
|
|
24
23
|
/** Handle POST /api/prompt: queue a director prompt. An over-long prompt
|
|
25
24
|
* (DIRECTOR_PROMPT_MAX_CHARS) is a user-input error, not a server fault: the shared length
|
|
@@ -93,10 +92,10 @@ function checkedPromptFields(res, body, role = DIRECTOR_ROLE) {
|
|
|
93
92
|
return null;
|
|
94
93
|
return { text, images, notBeforeMs };
|
|
95
94
|
}
|
|
96
|
-
/** Handle POST /api/prompt-role: queue a prompt for one
|
|
95
|
+
/** Handle POST /api/prompt-role: queue a prompt for one role — the dashboard's per-row
|
|
97
96
|
* prompt affordance submits here, calling the same path `tumwater prompt --role <id>` uses
|
|
98
|
-
* (submitRolePrompt enqueues into that
|
|
99
|
-
* wake brings the live
|
|
97
|
+
* (submitRolePrompt enqueues into that role's own queue and logs under it, then a single-role
|
|
98
|
+
* wake brings the live role in within one poll; the wake message rides back for the flash).
|
|
100
99
|
* The role validates exactly like /api/transcript (the shared rejectBadRole wording), and the
|
|
101
100
|
* body discipline is /api/prompt's: readJsonObject → 400 malformed/non-object, 413 oversized,
|
|
102
101
|
* text a non-empty string within the shared length rule → 400 otherwise — plus the same
|
|
@@ -110,9 +109,9 @@ export async function handlePromptRole(req, res, root) {
|
|
|
110
109
|
if (!fields)
|
|
111
110
|
return;
|
|
112
111
|
// Image-input submit gate (plans/image-input.md "Attachments", part 5/5): an attachment the
|
|
113
|
-
// target
|
|
112
|
+
// target role cannot read (and that no tier reroutes) answers 400 naming the fix before
|
|
114
113
|
// anything is queued — the same gate submitRolePrompt enforces, surfaced as a user-input
|
|
115
|
-
// error rather than the server's 500. A
|
|
114
|
+
// error rather than the server's 500. A role that reroutes a blind read is not refused; its
|
|
116
115
|
// notice rides in the confirmation the composer flashes.
|
|
117
116
|
let notice = "";
|
|
118
117
|
if (fields.images && fields.images.length > 0) {
|
|
@@ -123,29 +122,36 @@ export async function handlePromptRole(req, res, root) {
|
|
|
123
122
|
}
|
|
124
123
|
notice = guidance.notice ?? "";
|
|
125
124
|
}
|
|
126
|
-
const message = [
|
|
125
|
+
const message = joinParts([
|
|
127
126
|
submitRolePromptAndWake(root, role, fields.text, fields.images, fields.notBeforeMs),
|
|
128
127
|
notice,
|
|
129
|
-
]
|
|
130
|
-
.filter(Boolean)
|
|
131
|
-
.join("\n");
|
|
128
|
+
], "\n");
|
|
132
129
|
sendJson(res, 200, { ok: true, message });
|
|
133
130
|
}
|
|
131
|
+
/** The file-addressed prompt handlers' shared role prologue: validate the optional role
|
|
132
|
+
* (400 sent on a present-but-invalid one and null returned, so the caller stops) and default
|
|
133
|
+
* an absent role to the director's queue. The same optional-role rule handlePromptCancel,
|
|
134
|
+
* handlePromptEdit and handlePromptTop state once instead of a guard-plus-default pair. */
|
|
135
|
+
function promptFileRole(body, res, root) {
|
|
136
|
+
if (body.role !== undefined && rejectBadRole(root, res, body.role))
|
|
137
|
+
return null;
|
|
138
|
+
return body.role === undefined ? DIRECTOR_ROLE : body.role;
|
|
139
|
+
}
|
|
134
140
|
/** Handle POST /api/prompt-cancel: retract one queued prompt addressed by its queue file —
|
|
135
141
|
* the dashboard's per-row cancel affordance, the file-addressed twin of the CLI's
|
|
136
142
|
* position-addressed `prompt --cancel`. The role is optional (absent cancels from the
|
|
137
143
|
* director's queue) and validates exactly like /api/transcript; a file name failing the
|
|
138
144
|
* shared rejectBadQueueFileName guard is a user-input error answered 400 with
|
|
139
|
-
* nothing touched on disk. A vanished file answers 200 { status: "gone" } — the
|
|
145
|
+
* nothing touched on disk. A vanished file answers 200 { status: "gone" } — the role already
|
|
140
146
|
* dequeued the prompt, which is data for the flash line, not a server fault. Same body
|
|
141
147
|
* discipline as /api/prompt (readJsonObject → 400 malformed/non-object, 413 oversized). */
|
|
142
148
|
export async function handlePromptCancel(req, res, root) {
|
|
143
149
|
const body = await readPostBody(req, res, '{"role": "feature", "file": "<stamp>-<seq>-<pid>.md"}');
|
|
144
150
|
if (!body)
|
|
145
151
|
return;
|
|
146
|
-
|
|
152
|
+
const role = promptFileRole(body, res, root);
|
|
153
|
+
if (role === null)
|
|
147
154
|
return;
|
|
148
|
-
const role = body.role === undefined ? DIRECTOR_ROLE : body.role;
|
|
149
155
|
if (rejectBadQueueFileName(res, body.file))
|
|
150
156
|
return;
|
|
151
157
|
const outcome = cancelQueuedFile(root, role, body.file);
|
|
@@ -161,7 +167,7 @@ export async function handlePromptCancel(req, res, root) {
|
|
|
161
167
|
* and images validate through the same checkedPromptFields /api/prompt and /api/prompt-role
|
|
162
168
|
* use; editQueuedFile throws for a bad name or an over-cap text — both user-input errors
|
|
163
169
|
* answered 400 (a filesystem failure reads as 400 like handleConfigSet's failed write). A
|
|
164
|
-
* vanished file answers 200 { ok: true, status: "gone" } — the
|
|
170
|
+
* vanished file answers 200 { ok: true, status: "gone" } — the role already dequeued the
|
|
165
171
|
* prompt, which is data for the flash line, not a server error; an edit answers 200 with the
|
|
166
172
|
* old and new operator-facing text the client flashes. Same body discipline as /api/prompt
|
|
167
173
|
* (readJsonObject → 400 malformed/non-object, 413 oversized). */
|
|
@@ -169,9 +175,9 @@ export async function handlePromptEdit(req, res, root) {
|
|
|
169
175
|
const body = await readPostBody(req, res, '{"role": "qa", "file": "<stamp>.md", "text": "..."}');
|
|
170
176
|
if (!body)
|
|
171
177
|
return;
|
|
172
|
-
|
|
178
|
+
const role = promptFileRole(body, res, root);
|
|
179
|
+
if (role === null)
|
|
173
180
|
return;
|
|
174
|
-
const role = body.role === undefined ? DIRECTOR_ROLE : body.role;
|
|
175
181
|
if (rejectBadQueueFileName(res, body.file))
|
|
176
182
|
return;
|
|
177
183
|
const fields = checkedPromptFields(res, body, role);
|
|
@@ -179,7 +185,7 @@ export async function handlePromptEdit(req, res, root) {
|
|
|
179
185
|
return;
|
|
180
186
|
// Image-input gate (plans/image-input.md "Attachments", part 5/5), the edit twin of
|
|
181
187
|
// handlePromptRole's: an image edited into the queued prompt answers 400 naming the fix
|
|
182
|
-
// when the target
|
|
188
|
+
// when the target role cannot read it (and no tier reroutes it) — the same gate
|
|
183
189
|
// submitRolePrompt enforces — before anything is written.
|
|
184
190
|
if (fields.images && fields.images.length > 0) {
|
|
185
191
|
const guidance = imagePromptGuidance(root, role);
|
|
@@ -213,9 +219,9 @@ export async function handlePromptTop(req, res, root) {
|
|
|
213
219
|
const body = await readPostBody(req, res, '{"role": "qa", "file": "<stamp>.md"}');
|
|
214
220
|
if (!body)
|
|
215
221
|
return;
|
|
216
|
-
|
|
222
|
+
const role = promptFileRole(body, res, root);
|
|
223
|
+
if (role === null)
|
|
217
224
|
return;
|
|
218
|
-
const role = body.role === undefined ? DIRECTOR_ROLE : body.role;
|
|
219
225
|
if (rejectBadQueueFileName(res, body.file))
|
|
220
226
|
return;
|
|
221
227
|
let outcome;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dashboard's GET report and failures handlers (src/gui/gui-server.ts routes to them):
|
|
3
|
+
* report and failures. Each answers its request and touches no socket beyond its own `res`;
|
|
4
|
+
* the domain work lives one layer down (report/report-data.ts, failure/failure-data.ts), so
|
|
5
|
+
* this module only adapts HTTP onto it. Barrelled into gui/gui-endpoints.ts beside the other
|
|
6
|
+
* per-family GET endpoint modules.
|
|
7
|
+
*/
|
|
8
|
+
import { collectReport, collectReportSince } from "../report/report-data.js";
|
|
9
|
+
import { collectFailureReport, collectFailureReportSince } from "../failure/failure-data.js";
|
|
10
|
+
import { renderFailureMarkdown } from "../failure/failure-render.js";
|
|
11
|
+
import { renderSinceReportMarkdown } from "../report/report-render.js";
|
|
12
|
+
import { loadQuarantine } from "../review/known-flakes.js";
|
|
13
|
+
import { quarantineRows, renderQuarantineSection } from "../review/quarantine-render.js";
|
|
14
|
+
import { REPORT_SINCE_MAX_MS, reportSinceMsg } from "../events/event-window.js";
|
|
15
|
+
import { roleListQuery, sinceMsQuery, untilMsQuery, windowDays } from "./gui-args.js";
|
|
16
|
+
import { badRequest, sendJson } from "./http-body.js";
|
|
17
|
+
/** Parse and validate the role-scoped, sinceMs-or-days query the report and failures endpoints
|
|
18
|
+
* both take: the `?role=` filter, a comma-separated list (each id trimmed, deduplicated, and
|
|
19
|
+
* validated by rejectBadRole — an unknown id or an empty list → 400 naming it) and, when
|
|
20
|
+
* `?sinceMs=` is present, the trailing-window length (reportSinceMs, which 400s a simultaneous
|
|
21
|
+
* `?days=`). Returns null once a 400 is sent. `sinceMs` is defined exactly when the caller
|
|
22
|
+
* should use the since shape; otherwise it falls through to the days shape with `windowDays(q)`.
|
|
23
|
+
* The one home of that shared scaffolding, so the two endpoints cannot drift on the role rule or
|
|
24
|
+
* the days-vs-sinceMs mutual exclusion (the server twin of reportEndpoint on the GUI client). */
|
|
25
|
+
function reportScope(q, res, root) {
|
|
26
|
+
const roles = roleListQuery(q, res, root);
|
|
27
|
+
if (roles === null)
|
|
28
|
+
return null;
|
|
29
|
+
if (q.get("sinceMs") !== null) {
|
|
30
|
+
const sinceMs = reportSinceMs(q, res);
|
|
31
|
+
if (sinceMs === null)
|
|
32
|
+
return null;
|
|
33
|
+
return { roles, sinceMs };
|
|
34
|
+
}
|
|
35
|
+
return { roles };
|
|
36
|
+
}
|
|
37
|
+
/** Parse and bound the report endpoints' `?sinceMs=` trailing-window length: a simultaneous
|
|
38
|
+
* `?days=` is the CLI's rival shape (whole local days vs a trailing window) → 400 naming both;
|
|
39
|
+
* otherwise the length rides sinceMsQuery (gui-args.ts) — positive-integer parse, then a 400
|
|
40
|
+
* naming the cap rather than a silent clamp (an explicit window typo must not shrink to some
|
|
41
|
+
* other window) — with the "must be between 1 and …" wording. Returns the parsed length, or
|
|
42
|
+
* null once the 400 is sent. */
|
|
43
|
+
function reportSinceMs(q, res) {
|
|
44
|
+
if (q.get("days") !== null) {
|
|
45
|
+
badRequest(res, "days and sinceMs are mutually exclusive; days counts whole local days, sinceMs totals a trailing window");
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return sinceMsQuery(q, res, REPORT_SINCE_MAX_MS, reportSinceMsg);
|
|
49
|
+
}
|
|
50
|
+
/** Handle GET /api/report?days=N[&role=<id>[,<id>...]] or
|
|
51
|
+
* /api/report?sinceMs=<ms>[&untilMs=<ms>][&role=<id>[,<id>...]]: the
|
|
52
|
+
* usage report — the day series (collectReport's ReportData) as JSON the dashboard's report tab
|
|
53
|
+
* charts, or, when sinceMs is set, the trailing-window totals rendered through
|
|
54
|
+
* renderSinceReportMarkdown as { markdown } (the CLI's `report --since` shape). The day window
|
|
55
|
+
* follows windowDays. An absent role is the team-wide report; the listed roles, summed
|
|
56
|
+
* (each id validated by reportScope). Reads files directly, so it works whether or not the team
|
|
57
|
+
* is running. */
|
|
58
|
+
export function handleReport(q, res, root) {
|
|
59
|
+
const scope = reportScope(q, res, root);
|
|
60
|
+
if (scope === null)
|
|
61
|
+
return;
|
|
62
|
+
const untilMs = untilMsQuery(q, res, scope.sinceMs);
|
|
63
|
+
if (untilMs === null)
|
|
64
|
+
return;
|
|
65
|
+
if (scope.sinceMs !== undefined) {
|
|
66
|
+
sendJson(res, 200, { markdown: renderSinceReportMarkdown(collectReportSince(root, scope.sinceMs, scope.roles, untilMs)) });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
sendJson(res, 200, collectReport(root, windowDays(q), scope.roles));
|
|
70
|
+
}
|
|
71
|
+
/** Handle GET /api/failures?days=N[&role=<id>[,<id>...]] or
|
|
72
|
+
* /api/failures?sinceMs=<ms>[&untilMs=<ms>][&role=<id>[,<id>...]]: the
|
|
73
|
+
* same bounded Markdown failure digest the selfcheck role feeds on and `tumwater report
|
|
74
|
+
* --failures` prints, as JSON ({ markdown }) — the dashboard's failures tab renders it; with
|
|
75
|
+
* sinceMs it is the trailing-window digest (collectFailureReportSince) through the same render,
|
|
76
|
+
* the CLI's `report --failures --since` shape. The response also carries `quarantine`, the
|
|
77
|
+
* Markdown section (renderQuarantineSection over the current loadQuarantine list, an empty
|
|
78
|
+
* string when it is empty) the Failures view paints below the digest — the read twin of the
|
|
79
|
+
* amber quarantine alert, current rather than window- or role-scoped. The digest's `markdown`
|
|
80
|
+
* is unchanged. The days window follows windowDays (so it can
|
|
81
|
+
* never drift from /api/report's). role rides the same rule as
|
|
82
|
+
* handleReport: absent → the team digest, present → the validated listed roles, summed. Reads files
|
|
83
|
+
* directly, so it works with no team running. */
|
|
84
|
+
export function handleFailures(q, res, root) {
|
|
85
|
+
const scope = reportScope(q, res, root);
|
|
86
|
+
if (scope === null)
|
|
87
|
+
return;
|
|
88
|
+
const untilMs = untilMsQuery(q, res, scope.sinceMs);
|
|
89
|
+
if (untilMs === null)
|
|
90
|
+
return;
|
|
91
|
+
const quarantine = renderQuarantineSection(quarantineRows(loadQuarantine(root)), Date.now());
|
|
92
|
+
if (scope.sinceMs !== undefined) {
|
|
93
|
+
sendJson(res, 200, { markdown: renderFailureMarkdown(collectFailureReportSince(root, scope.sinceMs, scope.roles, untilMs)), quarantine });
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
sendJson(res, 200, { markdown: renderFailureMarkdown(collectFailureReport(root, windowDays(q), scope.roles)), quarantine });
|
|
97
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** The dashboard HTTP server: routing, the shared-token gate, the static page, /api/status, and the
|
|
2
2
|
* self-reload watch. Every /api endpoint's handler lives in gui/gui-endpoints.ts (the GET data
|
|
3
|
-
* endpoints
|
|
3
|
+
* endpoints, barrelled there from one module per family — gui-history-endpoints,
|
|
4
|
+
* gui-backlog-endpoints, gui-report-endpoints, gui-admin-endpoints) and
|
|
5
|
+
* gui/gui-endpoint-commands.ts (the POST operator endpoints) — this module owns
|
|
4
6
|
* the socket, not the data. The `tumwater gui` CLI entry (cmdGui) lives in gui/gui-command.ts,
|
|
5
7
|
* which imports startGui from here, so the server and the command that boots it stay adjacent. */
|
|
6
8
|
import crypto from "node:crypto";
|
|
@@ -10,8 +12,8 @@ import { statusPayload } from "../ui/status-payload.js";
|
|
|
10
12
|
import { captureStartupBuild, createReloadWatch, reexecSelf, watchReloadSupervisor, } from "../redeploy/self-reload.js";
|
|
11
13
|
import { warnEvent, TUMWATER_SOURCE } from "../events/events.js";
|
|
12
14
|
import { errorMessage } from "../text/text.js";
|
|
13
|
-
import { handleBacklog, handleBrief, handleConfig, handleDiff, handleFailures, handleReport, handleHistory, handleLogs, handlePromptText,
|
|
14
|
-
import { handleAbort, handleBriefEdit, handleBudget, handleConfigSet, handleConfigUnset, handleRoleCap, handleRoleEnable, handleRoleDisable, handleRoleInstances, handleRoleInterval, handleRoleInstructions, handleRoleModel, handleRoleQuietHours, handleNotifyTest, handlePause, handlePauseRole, handlePrompt, handleBacklogFile, handleBacklogCancel, handleBacklogRelease, handleBacklogTop, handleBacklogEdit, handlePromptCancel, handlePromptEdit, handlePromptRole, handlePromptTop, handleQuestionAnswer, handleReclaim, handleRestart, handleStopSchedule, handleResetCounters, handleRoleNotes, handleRetire, handleWake, handleWakeCancel, } from "./gui-endpoint-commands.js";
|
|
15
|
+
import { handleBacklog, handleBacklogMatch, handleBrief, handleConfig, handleDiff, handleFailures, handleReport, handleHistory, handleLogs, handlePromptText, handleRun, handleRole, handleTranscript, handleDoctor, handleRetireList, } from "./gui-endpoints.js";
|
|
16
|
+
import { handleAbort, handleBriefEdit, handleBudget, handleConfigSet, handleConfigUnset, handleRoleCap, handleRoleReviewAfterMerge, handleRoleEnable, handleRoleDisable, handleRoleInstances, handleRoleInterval, handleRoleInstructions, handleRoleModel, handleRoleQuietHours, handleNotifyTest, handlePause, handlePauseRole, handlePrompt, handleBacklogFile, handleBacklogCancel, handleBacklogRelease, handleBacklogTop, handleBacklogEdit, handlePromptCancel, handlePromptEdit, handlePromptRole, handlePromptTop, handleQuestionAnswer, handleReclaim, handleKillOrphans, handleDropBrokenPins, handleCommitBacklog, handleResyncInstall, handleRetireLeftovers, handleDoctorReprobe, handleRestart, handleStopSchedule, handleResetCounters, handleRoleNotes, handleRetire, handleRevert, handleQueueCancel, handleQueueTop, handlePostReviewAccept, handleWake, handleWakeCancel, } from "./gui-endpoint-commands.js";
|
|
15
17
|
import { sendJson } from "./http-body.js";
|
|
16
18
|
/** Constant-time credential comparison for the shared-token gate: `timingSafeEqual` throws
|
|
17
19
|
* on unequal lengths, so the length equality is the guard. A naive `===` string compare
|
|
@@ -148,10 +150,11 @@ export function startGui(root, port, allInterfaces = false, token = "", watch =
|
|
|
148
150
|
"GET /api/logs": (_req, res, target) => handleLogs(target.searchParams, res, root),
|
|
149
151
|
"GET /api/transcript": (_req, res, target) => handleTranscript(target.searchParams, res, root),
|
|
150
152
|
"GET /api/prompt-text": (_req, res, target) => handlePromptText(target.searchParams, res, root),
|
|
151
|
-
"GET /api/run": (_req, res, target) =>
|
|
153
|
+
"GET /api/run": (_req, res, target) => handleRun(target.searchParams, res, root),
|
|
152
154
|
"GET /api/role": (_req, res, target) => handleRole(target.searchParams, res, root),
|
|
153
155
|
"GET /api/diff": (_req, res, target) => handleDiff(target.searchParams, res, root),
|
|
154
156
|
"GET /api/backlog": (_req, res, target) => handleBacklog(target.searchParams, res, root),
|
|
157
|
+
"GET /api/backlog-match": (_req, res, target) => handleBacklogMatch(target.searchParams, res, root),
|
|
155
158
|
"GET /api/config": (_req, res) => handleConfig(res, root),
|
|
156
159
|
"GET /api/brief": (_req, res) => handleBrief(res, root),
|
|
157
160
|
"GET /api/doctor": (_req, res) => handleDoctor(res, root),
|
|
@@ -173,6 +176,7 @@ export function startGui(root, port, allInterfaces = false, token = "", watch =
|
|
|
173
176
|
"POST /api/question-answer": (req, res) => handleQuestionAnswer(req, res, root),
|
|
174
177
|
"POST /api/budget": (req, res) => handleBudget(req, res, root),
|
|
175
178
|
"POST /api/role-cap": (req, res) => handleRoleCap(req, res, root),
|
|
179
|
+
"POST /api/role-review-after-merge": (req, res) => handleRoleReviewAfterMerge(req, res, root),
|
|
176
180
|
"POST /api/role-enable": (req, res) => handleRoleEnable(req, res, root),
|
|
177
181
|
"POST /api/role-disable": (req, res) => handleRoleDisable(req, res, root),
|
|
178
182
|
"POST /api/role-interval": (req, res) => handleRoleInterval(req, res, root),
|
|
@@ -186,9 +190,19 @@ export function startGui(root, port, allInterfaces = false, token = "", watch =
|
|
|
186
190
|
"POST /api/reset-counters": (req, res) => handleResetCounters(req, res, root),
|
|
187
191
|
"POST /api/role-notes": (req, res) => handleRoleNotes(req, res, root),
|
|
188
192
|
"POST /api/retire": (req, res) => handleRetire(req, res, root),
|
|
193
|
+
"POST /api/revert": (req, res) => handleRevert(req, res, root),
|
|
194
|
+
"POST /api/queue-cancel": (req, res) => handleQueueCancel(req, res, root),
|
|
195
|
+
"POST /api/queue-top": (req, res) => handleQueueTop(req, res, root),
|
|
196
|
+
"POST /api/post-review-accept": (req, res) => handlePostReviewAccept(req, res, root),
|
|
189
197
|
"POST /api/restart": (req, res) => handleRestart(req, res, root),
|
|
190
198
|
"POST /api/stop-schedule": (req, res) => handleStopSchedule(req, res, root),
|
|
191
199
|
"POST /api/reclaim": (req, res) => handleReclaim(req, res, root),
|
|
200
|
+
"POST /api/kill-orphans": (req, res) => handleKillOrphans(req, res, root),
|
|
201
|
+
"POST /api/doctor-drop-broken-pins": (req, res) => handleDropBrokenPins(req, res, root),
|
|
202
|
+
"POST /api/doctor-commit-backlog": (req, res) => handleCommitBacklog(req, res, root),
|
|
203
|
+
"POST /api/doctor-resync-install": (req, res) => handleResyncInstall(req, res, root),
|
|
204
|
+
"POST /api/doctor-retire-leftovers": (req, res) => handleRetireLeftovers(req, res, root),
|
|
205
|
+
"POST /api/doctor-reprobe": (req, res) => handleDoctorReprobe(req, res, root),
|
|
192
206
|
"POST /api/abort": (req, res) => handleAbort(req, res, root),
|
|
193
207
|
"POST /api/pause-role": (req, res) => handlePauseRole(req, res, root),
|
|
194
208
|
};
|
|
@@ -240,8 +254,15 @@ export function startGui(root, port, allInterfaces = false, token = "", watch =
|
|
|
240
254
|
if (route)
|
|
241
255
|
await route(req, res, target);
|
|
242
256
|
else {
|
|
257
|
+
// Unknown path: a bare "not found" hides which path failed, so name the offending
|
|
258
|
+
// target, JSON.stringify-quoted like every sibling error-answer (the quote-the-
|
|
259
|
+
// offending-value convention). Plain text, not sendJson's {error}, on purpose: this
|
|
260
|
+
// also answers non-/api requests (a stale /api route, a proxy's /favicon.ico), and the
|
|
261
|
+
// client's apiError treats a plain-text 404 body as a bare message. `pathname` is null
|
|
262
|
+
// only for a target the URL parser rejected, so fall back to the raw url. No "no such
|
|
263
|
+
// route" claim: a known path with a wrong method lands here too (GET /api/stop-schedule).
|
|
243
264
|
res.writeHead(404, { "content-type": "text/plain" });
|
|
244
|
-
res.end(
|
|
265
|
+
res.end(`not found: ${JSON.stringify(pathname ?? req.url ?? "/")}`);
|
|
245
266
|
}
|
|
246
267
|
}
|
|
247
268
|
catch (err) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `wakeInSecondsMs` body rules they share. Each handler adapts HTTP onto the domain work one
|
|
6
6
|
* layer down (team/team-state, operator-intent) and touches no socket beyond its own `res`.
|
|
7
7
|
*/
|
|
8
|
-
import { baseRoleOf, INSTANCE_ROLES } from "../roles/
|
|
8
|
+
import { baseRoleOf, INSTANCE_ROLES } from "../roles/runner-ids.js";
|
|
9
9
|
import { normalizePauseReason, pauseTeam, pauseRole, resumeTeam, resumeRole } from "../team/team-state.js";
|
|
10
10
|
import { cancelWakes, PAUSE_FOR_MAX_MS, requestWake } from "../operator/operator-intent.js";
|
|
11
11
|
import { requirePausedFlag, validRoleIds } from "./gui-args.js";
|
|
@@ -127,13 +127,13 @@ export async function handleWakeCancel(req, res, root) {
|
|
|
127
127
|
const body = await readRoleBody(req, res, '{"role": "feature"}', root, true);
|
|
128
128
|
if (!body)
|
|
129
129
|
return;
|
|
130
|
-
sendJson(res, 200, { ok: true, message: cancelWakes(root, body.role) });
|
|
130
|
+
sendJson(res, 200, { ok: true, message: cancelWakes(root, body.role === undefined ? undefined : [body.role]) });
|
|
131
131
|
}
|
|
132
|
-
/** Resume a row: lift every marker key that pauses this
|
|
133
|
-
* instance 1's `<role>-1`), since the row shows Resume whenever `
|
|
132
|
+
/** Resume a row: lift every marker key that pauses this role id (its own, its base role's, and
|
|
133
|
+
* instance 1's `<role>-1`), since the row shows Resume whenever `runnerPaused` holds and the key
|
|
134
134
|
* actually in the marker may differ from the row's id. Reports whether any key was lifted. */
|
|
135
|
-
function
|
|
136
|
-
const keys = new Set([
|
|
135
|
+
function resumeRunnerKeys(root, runnerId) {
|
|
136
|
+
const keys = new Set([runnerId, baseRoleOf(runnerId), ...(INSTANCE_ROLES.has(runnerId) ? [`${runnerId}-1`] : [])]);
|
|
137
137
|
let changed = false;
|
|
138
138
|
for (const key of keys)
|
|
139
139
|
changed = resumeRole(root, key) || changed;
|
|
@@ -159,6 +159,6 @@ export async function handlePauseRole(req, res, root) {
|
|
|
159
159
|
return;
|
|
160
160
|
const changed = value
|
|
161
161
|
? pauseRole(root, body.role, untilMs)
|
|
162
|
-
:
|
|
162
|
+
: resumeRunnerKeys(root, body.role);
|
|
163
163
|
sendJson(res, 200, { ok: true, changed, paused: value, ...(untilMs === undefined ? {} : { until: untilMs }) });
|
|
164
164
|
}
|
|
@@ -13,7 +13,7 @@ export function badRequest(res, message) {
|
|
|
13
13
|
sendJson(res, 400, { error: message });
|
|
14
14
|
}
|
|
15
15
|
/** Send 200 with the {"ok":true,"status":"gone"} body every file-addressed handler that answers
|
|
16
|
-
* for a vanished entry (the
|
|
16
|
+
* for a vanished entry (the role already dequeued it) replies with — data for the UI's flash
|
|
17
17
|
* line, not a server fault — so the status and the `{ ok, status }` wrapper live here instead
|
|
18
18
|
* of being open-coded at each call site. */
|
|
19
19
|
export function okGone(res) {
|