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
|
import { roleLabel } from "../roles/role-labels.js";
|
|
3
2
|
import { pausedRoles, pausedRolesUntil, standingTeamPause } from "../team/team-state.js";
|
|
4
3
|
import { MODEL_TIERS } from "../config/config-schema.js";
|
|
@@ -9,34 +8,36 @@ import { roleCapVerdicts } from "../gates/role-cap-gates.js";
|
|
|
9
8
|
import { readMergeQueue } from "../merge/merge-queue.js";
|
|
10
9
|
import { MAINTENANCE_DAILY_FLOOR } from "../gates/maintenance-quota.js";
|
|
11
10
|
import { heldByMainRed, mainCheckForPoll, maintenanceQuotaForPoll } from "../status/status-polls.js";
|
|
12
|
-
import {
|
|
13
|
-
import { baseRoleOf,
|
|
14
|
-
import { ERROR_STREAK_BREAKER, ERROR_STREAK_WARN } from "../
|
|
11
|
+
import { loadRunnerState } from "../runner/runner-state-load.js";
|
|
12
|
+
import { baseRoleOf, runnerIds, runnerPaused } from "../roles/runner-ids.js";
|
|
13
|
+
import { ERROR_STREAK_BREAKER, ERROR_STREAK_WARN } from "../run/run-apply.js";
|
|
15
14
|
import { squash } from "../text/text.js";
|
|
16
15
|
import { usd } from "../text/format.js";
|
|
17
16
|
import { parseQuietHours, quietHoursStatus, quietWindowEnd, roleQuietHold } from "../scheduling/quiet-hours.js";
|
|
18
|
-
import { humanUntil } from "../text/datetime.js";
|
|
17
|
+
import { DAY_MS, HOUR_MS, humanUntil } from "../text/datetime.js";
|
|
19
18
|
import { budgetPhrase, pauseReasonSuffix, plural } from "../text/phrases.js";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
19
|
+
import { readAccount, utilizationPct, windowEntries, windowLabel } from "../agent/subscription-account.js";
|
|
20
|
+
import { backendDisplayName } from "../agent/backend-traits.js";
|
|
21
|
+
import { windowObservation } from "../team/team-polls.js";
|
|
22
22
|
import { readEventsSince } from "../events/event-window.js";
|
|
23
23
|
import { errorMessage } from "../text/text.js";
|
|
24
24
|
import { okOutcome, warnOutcome } from "./outcome.js";
|
|
25
|
+
import { redMainWarning } from "../baseline/main-guardrails.js";
|
|
25
26
|
/** The standing-hold checks: `pause` (checkPause), `quiet hours` (checkQuietHours), and `budget`
|
|
26
|
-
* (checkBudget), `claude window` (
|
|
27
|
-
* (checkMaintenanceQuota), and `error streaks` (checkErrorStreaks), all
|
|
28
|
-
* holds on
|
|
29
|
-
export function
|
|
30
|
-
return
|
|
31
|
-
.map((id) =>
|
|
27
|
+
* (checkBudget), the `claude window`/`codex window` rows (checkSubscriptionWindow),
|
|
28
|
+
* `maintenance quota` (checkMaintenanceQuota), and `error streaks` (checkErrorStreaks), all
|
|
29
|
+
* read-only reports of holds on running. */
|
|
30
|
+
export function loadRunnerStates(root, config) {
|
|
31
|
+
return runnerIds(config)
|
|
32
|
+
.map((id) => loadRunnerState(root, id))
|
|
32
33
|
.sort((a, b) => a.role.localeCompare(b.role));
|
|
33
34
|
}
|
|
34
35
|
/** The `pause` check: names a standing operator pause so doctor does not print "ready to run"
|
|
35
|
-
* over a team that starts no
|
|
36
|
+
* over a team that starts no run. Read-only: it reads the same team and per-role pause
|
|
36
37
|
* markers the scheduler reads (standingTeamPause, pausedRoles, pausedRolesUntil — all treat
|
|
37
38
|
* an expired marker as absent), so its verdict cannot disagree with what the team does. A
|
|
38
|
-
* team pause is a warn because it stops every
|
|
39
|
-
* chose them by name and every other
|
|
39
|
+
* team pause is a warn because it stops every role; paused roles are ok because the operator
|
|
40
|
+
* chose them by name and every other role keeps running. `now` only drives the countdowns. */
|
|
40
41
|
export function checkPause(root, now = Date.now()) {
|
|
41
42
|
const team = standingTeamPause(root);
|
|
42
43
|
const roles = pausedRoles(root);
|
|
@@ -53,10 +54,10 @@ export function checkPause(root, now = Date.now()) {
|
|
|
53
54
|
return warnOutcome(`${head}${pauseReasonSuffix(team.reason)}${rolesPhrase ? `; ${rolesPhrase}` : ""}`);
|
|
54
55
|
}
|
|
55
56
|
/** The `quiet hours` check: names the team quiet window and any per-role windows holding now,
|
|
56
|
-
* so doctor does not print "ready to run" over a team that starts no
|
|
57
|
+
* so doctor does not print "ready to run" over a team that starts no run until the window
|
|
57
58
|
* ends. Read-only: membership comes from the scheduler's own parser and predicate
|
|
58
59
|
* (quietHoursStatus, roleQuietHold), so the verdict cannot disagree with the gate. A team
|
|
59
|
-
* window holding is a warn because it stops every
|
|
60
|
+
* window holding is a warn because it stops every role (the director is exempt); held per-role
|
|
60
61
|
* windows are ok because the operator chose those roles by name. A malformed value reads as
|
|
61
62
|
* unset here — checkInit owns that error. `now` is injected so tests never read the clock. */
|
|
62
63
|
export function checkQuietHours(config, now = new Date()) {
|
|
@@ -89,13 +90,13 @@ export function checkQuietHours(config, now = new Date()) {
|
|
|
89
90
|
* own `maxDailyCostUsdPerRole` cap. Read-only and built on the scheduler's own definitions
|
|
90
91
|
* (teamDailyCost, budgetReached, roleCapVerdicts), so the verdict cannot disagree with the gate.
|
|
91
92
|
* `published` is the running scheduler's figure (it includes runs charged since the last save)
|
|
92
|
-
* and wins over the persisted sum, as in status. A reached team cap is a warn because
|
|
93
|
+
* and wins over the persisted sum, as in status. A reached team cap is a warn because roles
|
|
93
94
|
* run on their tier fallback or hold until local midnight (the `fallback` row says which);
|
|
94
95
|
* per-role caps reached alone are ok because the operator chose them by name. */
|
|
95
96
|
export function checkBudget(root, config, published, now = Date.now()) {
|
|
96
97
|
if (config === undefined)
|
|
97
98
|
return okOutcome("not checked — tumwater.json unreadable");
|
|
98
|
-
const states =
|
|
99
|
+
const states = loadRunnerStates(root, config);
|
|
99
100
|
const spent = published?.spentUsd ?? teamDailyCost(states, now);
|
|
100
101
|
const caps = config.maxDailyCostUsdPerRole;
|
|
101
102
|
const capped = [...roleCapVerdicts(states.map((s) => ({ role: s.role, state: s })), caps, now)]
|
|
@@ -116,63 +117,65 @@ export function checkBudget(root, config, published, now = Date.now()) {
|
|
|
116
117
|
return okOutcome(`${phrase} today${cappedPhrase}`);
|
|
117
118
|
}
|
|
118
119
|
/** The `maintenance quota` check: rolling-24 h maintenance merges against the allowance
|
|
119
|
-
* (`maintenancePerWorkMerge` per work merge + the daily floor), naming the maintenance
|
|
120
|
+
* (`maintenancePerWorkMerge` per work merge + the daily floor), naming the maintenance roles held
|
|
120
121
|
* when it is full. Read-only and built on the same verdict the scheduler and status use
|
|
121
|
-
* (maintenanceQuotaForPoll). Only a live team's running
|
|
122
|
+
* (maintenanceQuotaForPoll). Only a live team's running roles and merge queue count as in flight,
|
|
122
123
|
* since a dead team's leftover `running` flag and queue drain nothing. A held allowance is a warn
|
|
123
124
|
* because it stops a whole tier. */
|
|
124
125
|
export function checkMaintenanceQuota(root, config, aliveTeam, now = Date.now()) {
|
|
125
126
|
if (config === undefined)
|
|
126
127
|
return okOutcome("not checked — tumwater.json unreadable");
|
|
127
|
-
const
|
|
128
|
+
const runners = loadRunnerStates(root, config).map((s) => ({ role: s.role, running: aliveTeam && s.running === true }));
|
|
128
129
|
const queued = aliveTeam ? new Set(readMergeQueue(root).entries.map((e) => e.role)) : new Set();
|
|
129
|
-
const { allowance, used, held } = maintenanceQuotaForPoll(root, config.maintenancePerWorkMerge,
|
|
130
|
+
const { allowance, used, held } = maintenanceQuotaForPoll(root, config.maintenancePerWorkMerge, runners, queued, now);
|
|
130
131
|
if (held.length > 0) {
|
|
131
132
|
return warnOutcome(`allowance reached — ${used}/${allowance} maintenance merges in the last 24h; held until the window rolls under: ${[...held].sort().join(", ")}`);
|
|
132
133
|
}
|
|
133
134
|
const base = `${used}/${allowance} maintenance merges in the last 24h (${config.maintenancePerWorkMerge} per work merge + ${MAINTENANCE_DAILY_FLOOR} floor)`;
|
|
134
|
-
const anyMaintenance =
|
|
135
|
+
const anyMaintenance = runners.some((l) => commitTier(l.role) === "maintenance");
|
|
135
136
|
return okOutcome(anyMaintenance ? base : `${base}; no maintenance role enabled`);
|
|
136
137
|
}
|
|
137
|
-
/** The
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
/** The `<backend> window` check, one row per subscription backend in use (claude and codex):
|
|
139
|
+
* whether a rejected subscription window holds the subscription `<backend>` seams. Read-only and
|
|
140
|
+
* built on windowObservation (the backend's own), the verdict the scheduler's team hold uses, so
|
|
141
|
+
* it cannot disagree with the hold. A hold is a warn because it stops every subscription seam on
|
|
142
|
+
* that backend until the window resets; otherwise the most constrained window's state is
|
|
143
|
+
* reported as ok (a rejected window spending overage reads `rejected` here: overage spends, it
|
|
144
|
+
* does not hold). Returns null (omitting the row from doctor) when the backend has no
|
|
145
|
+
* subscription account — the same omit-a-row pattern as `pi extensions` — because an absent or
|
|
146
|
+
* API-billed account never holds. */
|
|
147
|
+
export function checkSubscriptionWindow(backend, root, now = Date.now(), chain, config) {
|
|
148
|
+
const account = readAccount(root, backend, now);
|
|
145
149
|
if (account?.billing !== "subscription")
|
|
146
|
-
return
|
|
147
|
-
const held =
|
|
150
|
+
return null;
|
|
151
|
+
const held = windowObservation(backend, account, now);
|
|
148
152
|
if (held?.kind === "subscription-window" && held.windowType !== undefined && held.resetsAt !== undefined) {
|
|
149
|
-
const label =
|
|
153
|
+
const label = windowLabel(held.windowType);
|
|
150
154
|
const resets = humanUntil(held.resetsAt, now);
|
|
151
|
-
const moved = MODEL_TIERS.filter((t) =>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
155
|
+
const moved = MODEL_TIERS.filter((t) => (chain?.[t]?.reason === "window" || chain?.[t]?.reason === "reserve") &&
|
|
156
|
+
config !== undefined &&
|
|
157
|
+
withModelOverrides(config, t, {}).agent === backend);
|
|
155
158
|
if (moved.length > 0) {
|
|
156
|
-
const waiting = MODEL_TIERS.filter((t) => !chain?.[t] && config !== undefined && withModelOverrides(config, t, {}).agent ===
|
|
159
|
+
const waiting = MODEL_TIERS.filter((t) => !chain?.[t] && config !== undefined && withModelOverrides(config, t, {}).agent === backend);
|
|
157
160
|
return warnOutcome(`${label} window rejected — ${moved.join(", ")} moved to fallbacks until it resets in ${resets}${waiting.length > 0 ? `; ${waiting.join(", ")} wait` : ""}`);
|
|
158
161
|
}
|
|
159
|
-
return warnOutcome(`${label} window rejected — subscription
|
|
162
|
+
return warnOutcome(`${label} window rejected — subscription ${backendDisplayName(backend)} model jobs wait until it resets in ${resets}`);
|
|
160
163
|
}
|
|
161
|
-
const top =
|
|
164
|
+
const top = windowEntries(account)[0];
|
|
162
165
|
if (top === undefined)
|
|
163
166
|
return okOutcome("subscription; no window reported yet");
|
|
164
|
-
const pct = typeof top.utilization === "number" ? ` (${
|
|
165
|
-
const label =
|
|
167
|
+
const pct = typeof top.utilization === "number" ? ` (${utilizationPct(top.utilization)}% used)` : "";
|
|
168
|
+
const label = windowLabel(top.type);
|
|
166
169
|
return okOutcome(top.status === "allowed_warning" ? `${label} window nearing its limit${pct}` : `${label} window ${top.status}${pct}`);
|
|
167
170
|
}
|
|
168
171
|
/** How far back the `provider hold` check reads for hold/resume crossings. The longest a
|
|
169
172
|
* hold can stay is HOLD_CAP_MS (team-hold's 15-minute cap that escalation doubles against),
|
|
170
173
|
* so a window a comfortable multiple of that covers any standing hold's crossing event plus
|
|
171
174
|
* its resume — an older resumed event must not be missed or a re-opened provider reads held. */
|
|
172
|
-
const HOLD_CHECK_WINDOW_MS = 2 *
|
|
175
|
+
const HOLD_CHECK_WINDOW_MS = 2 * HOUR_MS;
|
|
173
176
|
/** The `provider hold` check: names each provider whose team-wide failure hold
|
|
174
177
|
* (src/team/team-hold.ts, polled by pollTeamHold) stands now — a 429/backend-failure storm
|
|
175
|
-
* that stops the roles on that provider from starting new
|
|
178
|
+
* that stops the roles on that provider from starting new runs until it re-opens. Read-only:
|
|
176
179
|
* it infers the standing set from the event log's own `rate_limit_hold`/`rate_limit_resumed`
|
|
177
180
|
* crossings, the events pollTeamHold writes, so it cannot disagree with the hold. A standing
|
|
178
181
|
* hold is a warn (as with the `claude window` row) because it stops every role on that
|
|
@@ -210,16 +213,16 @@ export function checkProviderHolds(root, now = Date.now()) {
|
|
|
210
213
|
});
|
|
211
214
|
return warnOutcome(lines.join("; "));
|
|
212
215
|
}
|
|
213
|
-
/** The `error streaks` check: names each enabled
|
|
216
|
+
/** The `error streaks` check: names each enabled role whose `consecutiveErrors` is at or past
|
|
214
217
|
* ERROR_STREAK_WARN, with its streak and last error, and whether it is paused. Read-only; it reads
|
|
215
218
|
* the same `consecutiveErrors` the error-streak breaker and `teamAlerts` read, and the same
|
|
216
219
|
* `pausedRoles` marker the scheduler reads. The marker does not record who wrote it, so a paused
|
|
217
|
-
*
|
|
218
|
-
* fail: a failing
|
|
220
|
+
* role at ERROR_STREAK_BREAKER's bar is described, not attributed to the breaker. A warn, not a
|
|
221
|
+
* fail: a failing role does not stop the team from running. */
|
|
219
222
|
export function checkErrorStreaks(root, config) {
|
|
220
223
|
if (config === undefined)
|
|
221
224
|
return okOutcome("not checked — tumwater.json unreadable");
|
|
222
|
-
const failing =
|
|
225
|
+
const failing = loadRunnerStates(root, config)
|
|
223
226
|
.filter((s) => (s.consecutiveErrors ?? 0) >= ERROR_STREAK_WARN);
|
|
224
227
|
if (failing.length === 0)
|
|
225
228
|
return okOutcome("no role failing repeatedly");
|
|
@@ -227,7 +230,7 @@ export function checkErrorStreaks(root, config) {
|
|
|
227
230
|
const phrases = failing.map((s) => {
|
|
228
231
|
const n = s.consecutiveErrors ?? 0;
|
|
229
232
|
let phrase = `${roleLabel(s.role)}: ${n} failed runs`;
|
|
230
|
-
if (
|
|
233
|
+
if (runnerPaused(paused, s.role)) {
|
|
231
234
|
const key = paused.has(s.role) ? s.role : paused.has(baseRoleOf(s.role)) ? baseRoleOf(s.role) : `${s.role}-1`;
|
|
232
235
|
phrase +=
|
|
233
236
|
n >= ERROR_STREAK_BREAKER
|
|
@@ -240,23 +243,34 @@ export function checkErrorStreaks(root, config) {
|
|
|
240
243
|
});
|
|
241
244
|
return warnOutcome(`failing run after run: ${phrases.join("; ")}`);
|
|
242
245
|
}
|
|
243
|
-
/** The `main red` check: names the code
|
|
244
|
-
* each blocked
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
|
|
246
|
+
/** The `main red` check: names the code roles the red-main gate (mainRedGate) holds, ending
|
|
247
|
+
* each blocked run `main_red` while main's suite is red, and warns when main has been red over
|
|
248
|
+
* RED_MAIN_WARN_MS even with no role held (the red-main gate's guardrail, G1). Read-only: it
|
|
249
|
+
* asks heldByMainRed, the predicate the status phase's `main red` label reads, so the two
|
|
250
|
+
* cannot disagree on the held roles, and redMainWarning over the event trail, so both phrases
|
|
251
|
+
* can appear in one row. A warn, not a fail: a red main does not stop the team from running.
|
|
252
|
+
* `now` is injected so a test can pin a red's age. */
|
|
253
|
+
export function checkMainRed(root, config, now = Date.now()) {
|
|
248
254
|
if (config === undefined)
|
|
249
255
|
return okOutcome("not checked — tumwater.json unreadable");
|
|
250
256
|
const mainCheck = mainCheckForPoll(root, config);
|
|
251
|
-
const ids =
|
|
252
|
-
const held =
|
|
257
|
+
const ids = runnerIds(config);
|
|
258
|
+
const held = loadRunnerStates(root, config)
|
|
253
259
|
.filter((s) => heldByMainRed(s, mainCheck));
|
|
254
|
-
|
|
260
|
+
const phrases = [];
|
|
261
|
+
if (held.length > 0) {
|
|
262
|
+
const err = held.find((s) => s.lastError)?.lastError;
|
|
263
|
+
const cause = err ? ` — ${squash(err, 160)}` : "";
|
|
264
|
+
const healer = ids.some((id) => baseRoleOf(id) === "ci")
|
|
265
|
+
? "; the ci role is exempt and repairs it"
|
|
266
|
+
: "; no ci role is enabled to repair it — fix main by hand or enable ci";
|
|
267
|
+
phrases.push(`main's check is failing; ${plural(held.length, "code role")} waiting: ${held.map((s) => roleLabel(s.role)).join(", ")}${cause}${healer}`);
|
|
268
|
+
}
|
|
269
|
+
const events = readEventsSince(root, DAY_MS).events;
|
|
270
|
+
const red = redMainWarning(events, now);
|
|
271
|
+
if (red !== null)
|
|
272
|
+
phrases.push(red);
|
|
273
|
+
if (phrases.length === 0)
|
|
255
274
|
return okOutcome("no role waiting on main's check");
|
|
256
|
-
|
|
257
|
-
const cause = err ? ` — ${squash(err, 160)}` : "";
|
|
258
|
-
const healer = ids.some((id) => baseRoleOf(id) === "bugfix")
|
|
259
|
-
? "; the bugfix role is exempt and repairs it"
|
|
260
|
-
: "; no bugfix role is enabled to repair it — fix main by hand or enable bugfix";
|
|
261
|
-
return warnOutcome(`main's check is failing; ${plural(held.length, "code role")} waiting: ${held.map((s) => roleLabel(s.role)).join(", ")}${cause}${healer}`);
|
|
275
|
+
return warnOutcome(phrases.join("; "));
|
|
262
276
|
}
|
|
@@ -5,11 +5,12 @@ import fs from "node:fs";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { installDrift } from "../build/dep-install.js";
|
|
7
7
|
import { readEventsSince } from "../events/event-window.js";
|
|
8
|
+
import { DAY_MS } from "../text/datetime.js";
|
|
8
9
|
import { plural, shortSpanPhrase } from "../text/phrases.js";
|
|
9
10
|
import { errorMessage, textOr } from "../text/text.js";
|
|
10
11
|
import { okOutcome, warnOutcome } from "./outcome.js";
|
|
11
12
|
/** How far back a failed `dep_install` event may sit and still explain the drift. */
|
|
12
|
-
const DEP_INSTALL_CHECK_WINDOW_MS =
|
|
13
|
+
const DEP_INSTALL_CHECK_WINDOW_MS = DAY_MS;
|
|
13
14
|
export function checkRootInstall(root, now = Date.now()) {
|
|
14
15
|
if (!fs.existsSync(path.join(root, "package-lock.json")))
|
|
15
16
|
return okOutcome("no package-lock.json — nothing pinned");
|