tumwater 0.2.0 → 0.3.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 +42 -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 +4 -3
- 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 +402 -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 +246 -55
- package/dist/src/backlog/backlog-cli-view.js +280 -0
- package/dist/src/backlog/backlog-cli.js +85 -274
- package/dist/src/backlog/backlog-commit.js +4 -5
- package/dist/src/backlog/backlog-eligibility.js +175 -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 +254 -0
- package/dist/src/backlog/backlog-release.js +117 -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-culprit.js +94 -0
- package/dist/src/baseline/main-guardrails.js +209 -0
- package/dist/src/baseline/main-red.js +139 -32
- package/dist/src/baseline/main-revert.js +133 -0
- package/dist/src/baseline/main-watch.js +184 -0
- package/dist/src/brief/brief-edit.js +9 -11
- package/dist/src/brief/brief.js +31 -51
- package/dist/src/budget/budget.js +30 -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 +1 -2
- 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 +118 -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 +150 -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 +308 -590
- package/dist/src/cli/cli-repo-gate.js +11 -1
- package/dist/src/cli/cli-role-command.js +420 -0
- package/dist/src/cli/cli-start-summary.js +160 -0
- package/dist/src/cli/{cli-run.js → cli-start.js} +165 -237
- package/dist/src/cli/completion.js +149 -22
- package/dist/src/cli/config-commands.js +41 -18
- package/dist/src/cli/follow-view.js +75 -0
- package/dist/src/cli/help.js +189 -73
- package/dist/src/cli/log-commands.js +148 -82
- package/dist/src/cli/question-commands.js +205 -10
- package/dist/src/cli.js +106 -43
- package/dist/src/collections.js +26 -10
- 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 +13 -1
- package/dist/src/config/config-fallbacks.js +93 -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 +141 -199
- package/dist/src/config/config-views.js +127 -53
- package/dist/src/config/config-write-core.js +135 -0
- package/dist/src/config/config-write.js +131 -264
- package/dist/src/config/config.js +48 -38
- package/dist/src/config/model-selector.js +34 -34
- package/dist/src/doctor/doctor-backlog-bugs.js +287 -0
- package/dist/src/doctor/doctor-backlog-plans.js +263 -0
- package/dist/src/doctor/doctor-backlog.js +100 -496
- package/dist/src/doctor/doctor-check-names.js +81 -0
- package/dist/src/doctor/doctor-checks.js +52 -579
- package/dist/src/doctor/doctor-claude-checks.js +145 -0
- package/dist/src/doctor/doctor-codex-checks.js +279 -0
- package/dist/src/doctor/doctor-contention-checks.js +380 -0
- package/dist/src/doctor/doctor-holds.js +82 -66
- package/dist/src/doctor/doctor-install.js +2 -1
- package/dist/src/doctor/doctor-model-checks.js +236 -402
- package/dist/src/doctor/doctor-notify.js +3 -4
- package/dist/src/doctor/doctor-opencode-checks.js +162 -0
- package/dist/src/doctor/doctor-orphans.js +182 -63
- package/dist/src/doctor/doctor-project-checks.js +303 -0
- package/dist/src/doctor/doctor.js +121 -77
- package/dist/src/doctor/image-probe.js +21 -8
- package/dist/src/doctor/outcome.js +3 -2
- package/dist/src/doctor/probe.js +7 -11
- package/dist/src/events/event-format.js +181 -86
- package/dist/src/events/event-labels.js +12 -5
- package/dist/src/events/event-legacy.js +39 -15
- package/dist/src/events/event-read.js +39 -39
- package/dist/src/events/event-tally.js +16 -0
- package/dist/src/events/event-window.js +60 -24
- 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 +56 -56
- package/dist/src/failure/failure-render.js +31 -23
- package/dist/src/failure/failure-state-change.js +17 -12
- package/dist/src/failure/time-spend.js +99 -35
- 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 +177 -84
- package/dist/src/gates/disk-gate.js +1 -1
- package/dist/src/gates/gate-polls.js +108 -58
- package/dist/src/gates/maintenance-quota.js +10 -13
- 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 +77 -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 +36 -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 +42 -18
- package/dist/src/gui/gui-backlog-endpoints.js +155 -0
- package/dist/src/gui/gui-command.js +8 -13
- package/dist/src/gui/gui-config-commands.js +94 -72
- package/dist/src/gui/gui-endpoint-commands.js +4 -3
- 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 +108 -13
- package/dist/src/gui/gui-prompt-commands.js +11 -14
- package/dist/src/gui/gui-report-endpoints.js +90 -0
- package/dist/src/gui/gui-server.js +11 -4
- 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 +147 -0
- package/dist/src/history/history-render.js +42 -22
- package/dist/src/history/history.js +193 -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 +25 -9
- 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 +81 -32
- package/dist/src/merge/merge-diff.js +5 -4
- package/dist/src/merge/merge-drain.js +150 -11
- 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 +90 -0
- package/dist/src/merge/merge-queue-render.js +49 -11
- package/dist/src/merge/merge-queue.js +31 -15
- package/dist/src/merge/merge-requeue.js +102 -0
- package/dist/src/merge/merge-slot.js +61 -16
- package/dist/src/merge/merge-stack.js +33 -11
- package/dist/src/merge/merge-to-main.js +86 -27
- package/dist/src/merge/merge-top.js +69 -0
- package/dist/src/merge/merge-verify.js +12 -10
- package/dist/src/notes-cli.js +30 -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 +320 -0
- package/dist/src/orchestrator/orchestrator-scheduling.js +68 -369
- package/dist/src/orchestrator/orchestrator.js +128 -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 +201 -0
- package/dist/src/orchestrator/scheduling-skip.js +185 -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 +116 -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 +18 -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 +121 -211
- package/dist/src/prompt/notes-backlog.js +181 -0
- package/dist/src/prompt/principles.js +1 -2
- package/dist/src/prompt/prompt-followup.js +19 -14
- package/dist/src/prompt/prompt.js +129 -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 +161 -77
- package/dist/src/report/report-fold.js +129 -52
- package/dist/src/report/report-main-red.js +55 -0
- package/dist/src/report/report-render.js +133 -64
- package/dist/src/report/report-types.js +1 -0
- package/dist/src/report/report.js +26 -9
- package/dist/src/request-timeouts.js +2 -2
- package/dist/src/review/known-flakes.js +100 -1
- package/dist/src/review/post-merge-review.js +106 -0
- package/dist/src/review/protected-edits.js +4 -5
- 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 +155 -360
- 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 +69 -12
- package/dist/src/roles/role-guidance.js +55 -20
- package/dist/src/roles/role-labels.js +1 -2
- package/dist/src/roles/role-render.js +67 -50
- package/dist/src/roles/role-view.js +59 -47
- package/dist/src/roles/roles.js +31 -31
- package/dist/src/roles/runner-ids.js +97 -0
- package/dist/src/run/acceptance-greps.js +119 -0
- package/dist/src/run/feedback-filings.js +51 -0
- package/dist/src/{tick → run}/qa-coverage.js +9 -27
- package/dist/src/{tick/tick-apply.js → run/run-apply.js} +95 -94
- package/dist/src/run/run-detail-data.js +179 -0
- package/dist/src/run/run-detail-render.js +98 -0
- package/dist/src/run/run-detail.js +168 -0
- package/dist/src/{tick/tick-finalize.js → run/run-finalize.js} +72 -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} +108 -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} +108 -50
- 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} +91 -56
- 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 +172 -0
- package/dist/src/run/stage-path-checks.js +730 -0
- package/dist/src/{loop → runner}/leftover.js +80 -25
- package/dist/src/{loop → runner}/model-fallback.js +12 -12
- package/dist/src/runner/revision.js +202 -0
- package/dist/src/{loop/loop-fallback.js → runner/runner-fallback.js} +8 -8
- package/dist/src/runner/runner-outcome.js +107 -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} +21 -15
- package/dist/src/{loop/loop-tick.js → runner/runner-run.js} +218 -240
- package/dist/src/{loop/loop-state.js → runner/runner-state-load.js} +61 -114
- package/dist/src/runner/runner-state.js +102 -0
- package/dist/src/{loop/loop.js → runner/runner.js} +123 -120
- package/dist/src/scheduling/backoff.js +38 -38
- 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 +43 -16
- 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 +28 -28
- package/dist/src/status/status-roles.js +39 -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 +5 -6
- 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 +63 -17
- package/dist/src/text/format.js +48 -11
- package/dist/src/text/markdown.js +8 -5
- package/dist/src/text/phrases.js +57 -23
- package/dist/src/text/suggest.js +1 -1
- package/dist/src/text/text.js +67 -13
- package/dist/src/ui/badges.js +65 -37
- package/dist/src/ui/gui/gui-client-backlog.js +292 -0
- package/dist/src/ui/gui/gui-client-boot.js +32 -26
- package/dist/src/ui/gui/gui-client-composer.js +8 -9
- package/dist/src/ui/gui/gui-client-drawer-config.js +212 -0
- package/dist/src/ui/gui/gui-client-drawer.js +126 -285
- package/dist/src/ui/gui/gui-client-feed.js +271 -0
- package/dist/src/ui/gui/gui-client-history.js +434 -67
- package/dist/src/ui/gui/gui-client-labels.js +1 -2
- 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 +55 -51
- package/dist/src/ui/gui/gui-client-pending.js +227 -23
- package/dist/src/ui/gui/gui-client-report-chart.js +464 -0
- package/dist/src/ui/gui/gui-client-report.js +87 -427
- package/dist/src/ui/gui/{gui-client-loops.js → gui-client-roles.js} +43 -44
- package/dist/src/ui/gui/gui-client-settings.js +56 -4
- package/dist/src/ui/gui/gui-client-team.js +25 -465
- package/dist/src/ui/gui/gui-client.js +27 -25
- package/dist/src/ui/gui/gui-icons.js +0 -2
- package/dist/src/ui/gui/gui-page.js +9 -7
- package/dist/src/ui/gui/gui-styles.js +34 -34
- package/dist/src/ui/progress-data.js +9 -11
- package/dist/src/ui/{tick-progress-model.js → run-progress-model.js} +31 -31
- package/dist/src/ui/status-model.js +133 -125
- package/dist/src/ui/status-payload.js +136 -49
- package/dist/src/ui/status-render.js +101 -82
- package/dist/src/ui/team-alerts.js +248 -57
- package/dist/src/ui/tone.js +5 -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 +51 -14
- package/dist/src/ui/tui/tui-editor-answer.js +27 -31
- package/dist/src/ui/tui/tui-editor-attach.js +3 -5
- package/dist/src/ui/tui/tui-editor-backends.js +132 -0
- package/dist/src/ui/tui/tui-editor-brief.js +10 -12
- package/dist/src/ui/tui/tui-editor-budget.js +35 -31
- package/dist/src/ui/tui/tui-editor-claude-reserve.js +24 -0
- package/dist/src/ui/tui/tui-editor-concurrency.js +24 -0
- package/dist/src/ui/tui/tui-editor-config.js +86 -0
- package/dist/src/ui/tui/tui-editor-entry.js +36 -47
- package/dist/src/ui/tui/tui-editor-fallback.js +31 -0
- package/dist/src/ui/tui/tui-editor-instances.js +37 -0
- package/dist/src/ui/tui/tui-editor-instructions.js +136 -0
- package/dist/src/ui/tui/tui-editor-interval.js +11 -9
- package/dist/src/ui/tui/tui-editor-model.js +29 -0
- package/dist/src/ui/tui/tui-editor-notes.js +3 -5
- 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 +99 -35
- package/dist/src/ui/tui/tui-editor-retire.js +4 -6
- package/dist/src/ui/tui/tui-editor-role-key.js +76 -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 +60 -34
- package/dist/src/ui/tui/tui-editor-slots.js +23 -0
- package/dist/src/ui/tui/tui-editors.js +35 -2
- package/dist/src/ui/tui/tui-frame.js +56 -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 +24 -9
- package/dist/src/ui/tui/tui-pane-activity.js +14 -11
- package/dist/src/ui/tui/tui-pane-backlog.js +171 -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 +58 -8
- package/dist/src/ui/tui/tui-pane-history.js +402 -82
- package/dist/src/ui/tui/tui-pane-pending.js +308 -13
- package/dist/src/ui/tui/tui-pane-queued.js +71 -55
- package/dist/src/ui/tui/tui-pane-report.js +46 -14
- package/dist/src/ui/tui/tui-pane-session.js +25 -6
- package/dist/src/ui/tui/tui-pane-transcript.js +111 -37
- package/dist/src/ui/tui/tui-pane.js +80 -23
- package/dist/src/ui/tui/tui-panes.js +100 -30
- package/dist/src/ui/tui/tui.js +14 -14
- package/dist/src/verdict/fix-claim.js +82 -32
- package/dist/src/verdict/no-change.js +4 -4
- package/dist/src/verdict/refusal.js +40 -16
- package/dist/src/verdict/reply-contract.js +42 -31
- package/dist/src/version.js +0 -1
- package/package.json +2 -1
- package/dist/src/loop/revision.js +0 -70
- package/dist/src/roles/loop-ids.js +0 -77
- 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
package/dist/src/cli/cli-args.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { fail } from "./cli-output.js";
|
|
2
|
-
import { BRANCH_VALUE_ERROR, ROLE_VALUE_ERROR } from "./cli-flag-specs.js";
|
|
2
|
+
import { BRANCH_VALUE_ERROR, ROLE_VALUE_ERROR, TOKEN_VALUE_ERROR } from "./cli-flag-specs.js";
|
|
3
3
|
import { knownRoleIdsCached } from "../config/config.js";
|
|
4
4
|
import { allRoleIds, unknownRoleMessage } from "../roles/roles.js";
|
|
5
|
-
import { gotSuffix, parsePositiveInt } from "../text/text.js";
|
|
5
|
+
import { gotSuffix, parsePositiveInt, splitCommaList } from "../text/text.js";
|
|
6
6
|
import { canonicalRoleId } from "../roles/legacy-role-ids.js";
|
|
7
7
|
/** CLI argument parsing and validation, shared by every command in cli.ts. The execution
|
|
8
8
|
* layer calls these before running a command, so a bad flag fails fast with an actionable
|
|
@@ -29,17 +29,68 @@ export function flagValue(args, flag) {
|
|
|
29
29
|
const i = args.indexOf(flag);
|
|
30
30
|
return i < 0 ? null : args[i + 1];
|
|
31
31
|
}
|
|
32
|
+
/** The one validation of a `--token <secret>` value, shared by `tumwater gui` (cmdGui) and
|
|
33
|
+
* `tumwater start --gui` (cmdStart) so the value checks and their wording cannot drift
|
|
34
|
+
* between the two callers. Returns null when the token is fine (or absent), the error text
|
|
35
|
+
* the caller `fail()`s otherwise: TOKEN_VALUE_ERROR for a valueless or empty `--token`, and a
|
|
36
|
+
* flag-looking-value message when the value starts with `--` (a valued flag claims the next
|
|
37
|
+
* token even when it is a known flag, so `--token --all-interfaces` would otherwise serve with
|
|
38
|
+
* the literal secret "--all-interfaces"). `example` names the command form the operator
|
|
39
|
+
* typed (e.g. "tumwater gui" or "tumwater start --gui") in the copyable fix, so the
|
|
40
|
+
* message names whichever command the secret was meant for. */
|
|
41
|
+
export function tokenValueProblem(args, example) {
|
|
42
|
+
const raw = flagValue(args, "--token");
|
|
43
|
+
if (raw === null)
|
|
44
|
+
return null;
|
|
45
|
+
if (raw === undefined || raw === "")
|
|
46
|
+
return TOKEN_VALUE_ERROR;
|
|
47
|
+
if (raw.startsWith("--"))
|
|
48
|
+
return `--token got the flag-looking value "${raw}" instead of a secret — write the secret as its own argument (e.g. \`${example} --token s3cret --all-interfaces\`)`;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
32
51
|
/** The "each flag at most once" rule at a flag fold: fail the occurrence after the first with
|
|
33
52
|
* the shared wording (`<flag> may only be given once`), `seen` being the caller's accumulator
|
|
34
53
|
* for that flag. One home for the wording the spec-driven gate (cli-flag-specs.ts), the
|
|
35
54
|
* free-form parsers' pre-scan (cli-command-args.ts), and the bespoke command shells
|
|
36
|
-
* (backlog-cli.ts, cli-query-commands.ts) all apply, so a repeat cannot be
|
|
37
|
-
* different error on one surface. Called per occurrence rather than pre-scanned
|
|
55
|
+
* (backlog-cli.ts, backlog-cli-view.ts, cli-query-commands.ts) all apply, so a repeat cannot be
|
|
56
|
+
* reported as a different error on one surface. Called per occurrence rather than pre-scanned
|
|
57
|
+
* at every site,
|
|
38
58
|
* so a malformed invocation still reports whichever error its token order reaches first. */
|
|
39
59
|
export function rejectRepeatFlag(seen, flag) {
|
|
40
60
|
if (seen)
|
|
41
61
|
fail(`${flag} may only be given once`);
|
|
42
62
|
}
|
|
63
|
+
/** Refuse a `--`-token in a valued flag's position — `--result --last` must not treat `--last`
|
|
64
|
+
* as its value. Both `history` forms used to swallow the following `--` token in the value
|
|
65
|
+
* slot: the trail's `--result`/`--model` then failed downstream with a misleading "--result
|
|
66
|
+
* needs --last" wording — the operator DID write `--last` — and the listing's `--model`
|
|
67
|
+
* silently treated `--last` as a model filter and matched no rows. Returns the value
|
|
68
|
+
* unchanged when it is not a `--` token; only a `--` token reads as a flag, so a single-dash
|
|
69
|
+
* token and the intentional-text filters (grep, type) are not refused. `flag` names the
|
|
70
|
+
* valued flag the way its missing-value error names the command (e.g. `history --model`). */
|
|
71
|
+
export function rejectFlagLookingValue(flag, value) {
|
|
72
|
+
if (typeof value === "string" && value.startsWith("--"))
|
|
73
|
+
fail(`${flag} needs a value (the next token ${JSON.stringify(value)} is a flag, not a value)`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
/** The shared body of the `parse*Flag` helpers (grep, type, result, model): the flag's
|
|
77
|
+
* value (null when absent) alongside `rest`, the args with the value token removed, failing
|
|
78
|
+
* with `missingValueError` when the flag is valueless or its value is empty.
|
|
79
|
+
* `guardFlagValue` opts the flag into rejectFlagLookingValue, the same refusal the history
|
|
80
|
+
* listing (cmdHistory) applies to its own `--result`/`--model` and `role <id>`'s write flags
|
|
81
|
+
* and `config set` make. The value-scored filters (grep, type) deliberately keep a
|
|
82
|
+
* flag-shaped token as filter text and so stay off this guard. */
|
|
83
|
+
function takeValuedFlag(args, flag, missingValueError, guardFlagValue = false) {
|
|
84
|
+
const i = args.indexOf(flag);
|
|
85
|
+
const rest = i >= 0 ? args.filter((_, j) => j !== i + 1) : args;
|
|
86
|
+
const raw = flagValue(args, flag);
|
|
87
|
+
if (raw === null)
|
|
88
|
+
return { rest, value: null };
|
|
89
|
+
const checked = guardFlagValue ? rejectFlagLookingValue(flag, raw) : raw;
|
|
90
|
+
if (checked === undefined || checked === "")
|
|
91
|
+
fail(missingValueError);
|
|
92
|
+
return { rest, value: checked };
|
|
93
|
+
}
|
|
43
94
|
/** Parse an optional `--grep <text>` filter flag for the filtering views (logs, history): the
|
|
44
95
|
* substring pattern, or null when absent, returned alongside `rest` — the args with the
|
|
45
96
|
* flag's value token removed. The value token leaves the list because a flag-shaped token
|
|
@@ -51,14 +102,8 @@ export function rejectRepeatFlag(seen, flag) {
|
|
|
51
102
|
* case. Lives beside flagValue, whose indexOf/value pairing it builds on, so the views'
|
|
52
103
|
* scans cannot drift apart. */
|
|
53
104
|
export function parseGrepFlag(args, missingValueError) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
const raw = flagValue(args, "--grep");
|
|
57
|
-
if (raw === null)
|
|
58
|
-
return { rest, pattern: null };
|
|
59
|
-
if (raw === undefined || raw === "")
|
|
60
|
-
fail(missingValueError);
|
|
61
|
-
return { rest, pattern: raw };
|
|
105
|
+
const { rest, value } = takeValuedFlag(args, "--grep", missingValueError);
|
|
106
|
+
return { rest, pattern: value };
|
|
62
107
|
}
|
|
63
108
|
/** Parse an optional `--type <eventType>` exact-type filter flag for the event feed view
|
|
64
109
|
* (logs): the exact type id, or null when absent, returned alongside `rest` — the args with
|
|
@@ -69,14 +114,24 @@ export function parseGrepFlag(args, missingValueError) {
|
|
|
69
114
|
* caller's wording (each view names its own command) — the same error the `--type` gate spec
|
|
70
115
|
* (typeFlagSpec) reports earlier for the trailing-no-value case. */
|
|
71
116
|
export function parseTypeFlag(args, missingValueError) {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
117
|
+
const { rest, value } = takeValuedFlag(args, "--type", missingValueError);
|
|
118
|
+
return { rest, type: value };
|
|
119
|
+
}
|
|
120
|
+
/** Parse an optional `--result <class>[,...]` flag for the history trail form: the raw value
|
|
121
|
+
* (null when absent) alongside `rest`, the args with the value token removed so a class name
|
|
122
|
+
* cannot be read as a positional. Validation of the classes belongs to the caller
|
|
123
|
+
* (parseHistoryResultList); a valueless or empty value fails with `missingValueError`. */
|
|
124
|
+
export function parseResultFlag(args, missingValueError) {
|
|
125
|
+
const { rest, value } = takeValuedFlag(args, "--result", missingValueError, true);
|
|
126
|
+
return { rest, raw: value };
|
|
127
|
+
}
|
|
128
|
+
/** Parse an optional `--model <selector>[,...]` flag for the history trail form: the raw value
|
|
129
|
+
* (null when absent) alongside `rest`, the args with the value token removed so a selector
|
|
130
|
+
* cannot be read as a positional. Validation belongs to the caller (parseHistoryModelList); a
|
|
131
|
+
* valueless or empty value fails with `missingValueError`. */
|
|
132
|
+
export function parseModelFlag(args, missingValueError) {
|
|
133
|
+
const { rest, value } = takeValuedFlag(args, "--model", missingValueError, true);
|
|
134
|
+
return { rest, raw: value };
|
|
80
135
|
}
|
|
81
136
|
/** Parse a `-n`-style count flag value: a positive integer, or fail with a clear message.
|
|
82
137
|
* Unvalidated, NaN/0/negative limits make readEvents' `slice(-limit)` dump the whole log
|
|
@@ -111,18 +166,47 @@ export function parsePositionFlag(flag, raw, example) {
|
|
|
111
166
|
return n;
|
|
112
167
|
}
|
|
113
168
|
/** Resolve a read-only command's `--role <id>` scope: the role id, or null when the flag is
|
|
114
|
-
* absent. The id is validated against built-ins PLUS user-defined
|
|
169
|
+
* absent. The id is validated against built-ins PLUS user-defined roles, read through
|
|
115
170
|
* loadConfigCached (which never throws) so a transiently broken tumwater.json cannot take a
|
|
116
171
|
* read-only view down — a broken file falls back to the built-in catalog rather than refusing
|
|
117
172
|
* every id. Without --role no config is read. (State-changing commands instead resolve --role
|
|
118
173
|
* against loadConfig and fail loudly on a broken file, as operator/operator-commands.ts and
|
|
119
174
|
* prompt-commands.ts do.) The id
|
|
120
175
|
* set comes from config.knownRoleIdsCached, the one home of the cached-with-built-in-fallback
|
|
121
|
-
* rule. Shared by the tail views that scope their output to one
|
|
122
|
-
export function parseRoleScope(root, args) {
|
|
123
|
-
if (!args.includes(
|
|
176
|
+
* rule. Shared by the tail views that scope their output to one role (cmdLogs, cmdHistory). */
|
|
177
|
+
export function parseRoleScope(root, args, flag = "--role", missingValue = ROLE_VALUE_ERROR) {
|
|
178
|
+
if (!args.includes(flag))
|
|
124
179
|
return null;
|
|
125
|
-
return parseRoleFlag(args, knownRoleIdsCached(root));
|
|
180
|
+
return parseRoleFlag(args, knownRoleIdsCached(root), flag, missingValue);
|
|
181
|
+
}
|
|
182
|
+
/** Resolve `history --role <id>[,<id>...]`: the listed role ids (canonical, deduplicated,
|
|
183
|
+
* first-seen order), or null when the flag is absent (no config read then, as parseRoleScope).
|
|
184
|
+
* Each piece is validated like parseRoleScope's id; empty pieces are dropped, and a value with
|
|
185
|
+
* no piece left fails with ROLE_VALUE_ERROR. */
|
|
186
|
+
export function parseRoleListScope(root, args) {
|
|
187
|
+
return args.includes("--role") ? parseRoleListFlag(args, knownRoleIdsCached(root)) : null;
|
|
188
|
+
}
|
|
189
|
+
/** Parse `--role <id>[,<id>...]`: the listed role ids (canonical, deduplicated, first-seen
|
|
190
|
+
* order), or null when the flag is absent. Empty pieces are dropped, and a value with no piece
|
|
191
|
+
* left fails with ROLE_VALUE_ERROR. `validIds` defaults to the built-in catalog, as
|
|
192
|
+
* parseRoleFlag. */
|
|
193
|
+
export function parseRoleListFlag(args, validIds) {
|
|
194
|
+
const typed = flagValue(args, "--role");
|
|
195
|
+
if (typed === null)
|
|
196
|
+
return null;
|
|
197
|
+
const pieces = splitCommaList(typed ?? "");
|
|
198
|
+
if (pieces.length === 0)
|
|
199
|
+
fail(ROLE_VALUE_ERROR);
|
|
200
|
+
const ids = validIds ?? allRoleIds();
|
|
201
|
+
const out = [];
|
|
202
|
+
for (const piece of pieces) {
|
|
203
|
+
const role = canonicalRoleId(piece);
|
|
204
|
+
if (!ids.includes(role))
|
|
205
|
+
fail(unknownRoleMessage(role, ids));
|
|
206
|
+
if (!out.includes(role))
|
|
207
|
+
out.push(role);
|
|
208
|
+
}
|
|
209
|
+
return out;
|
|
126
210
|
}
|
|
127
211
|
/** Parse the `--port` flag value: an integer in 1..65535, or fail with a clear message.
|
|
128
212
|
* Port 0 would make Node pick an ephemeral port while the CLI prints :0 — a URL that
|
|
@@ -241,9 +325,10 @@ export function failRivalShapes(subject, rival, why) {
|
|
|
241
325
|
* "logs --since …" instead of the malformed and missing-value forms naming a bare "--since".
|
|
242
326
|
* Rival-flag rules stay in each command body, checked on the returned non-null value — so a
|
|
243
327
|
* malformed or over-cap `--since` fails on its own wording before a rival-flag check fires,
|
|
244
|
-
* the same precedence a command with only --since shows.
|
|
245
|
-
|
|
246
|
-
|
|
328
|
+
* the same precedence a command with only --since shows. `flag` defaults to `--since`; logs,
|
|
329
|
+
* history and report read their `--until` bound through the same idiom. */
|
|
330
|
+
export function parseSinceFlag(args, label, maxMs, flag = "--since") {
|
|
331
|
+
const raw = flagValue(args, flag);
|
|
247
332
|
if (raw === null)
|
|
248
333
|
return null;
|
|
249
334
|
const ms = parseDurationFlag(label, raw);
|
|
@@ -251,17 +336,17 @@ export function parseSinceFlag(args, label, maxMs) {
|
|
|
251
336
|
return ms;
|
|
252
337
|
}
|
|
253
338
|
/** Parse an optional `--role <id>` flag: the validated role id, or null when absent.
|
|
254
|
-
* Shared by every command that scopes to one
|
|
339
|
+
* Shared by every command that scopes to one role so their validation and error messages
|
|
255
340
|
* cannot drift. `validIds` is the set of ids this command accepts — callers pass
|
|
256
|
-
* knownRoleIds(config) so user-defined
|
|
341
|
+
* knownRoleIds(config) so user-defined roles are accepted like built-ins; it defaults to the
|
|
257
342
|
* catalog alone, which keeps in-process callers (and tests) that have no config working.
|
|
258
343
|
*/
|
|
259
|
-
export function parseRoleFlag(args, validIds) {
|
|
260
|
-
const typed = flagValue(args,
|
|
344
|
+
export function parseRoleFlag(args, validIds, flag = "--role", missingValue = ROLE_VALUE_ERROR) {
|
|
345
|
+
const typed = flagValue(args, flag);
|
|
261
346
|
if (typed === null)
|
|
262
347
|
return null;
|
|
263
348
|
if (!typed)
|
|
264
|
-
fail(
|
|
349
|
+
fail(missingValue);
|
|
265
350
|
const role = canonicalRoleId(typed);
|
|
266
351
|
const ids = validIds ?? allRoleIds();
|
|
267
352
|
if (!ids.includes(role))
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
// vocabulary: plain
|
|
2
1
|
/** The free-form-prompt commands' bespoke argument parsers: `tumwater init` and
|
|
3
2
|
* `tumwater prompt`, whose positionals are prompt TEXT rather than a token list. Every
|
|
4
3
|
* shared helper in cli/cli-args.ts assumes flags claim their tokens and rejects whatever is
|
|
5
4
|
* left over — exactly wrong here, where a misspelled flag must fail instead of being
|
|
6
|
-
* silently baked into the prompt that every
|
|
5
|
+
* silently baked into the prompt that every role then runs from. Both parsers therefore
|
|
7
6
|
* hand-roll the same discipline (a double-dash token must be a known flag, given at most
|
|
8
7
|
* once; single-dash tokens are content) and share failStrayArg, so they live together
|
|
9
8
|
* apart from cli/cli-args.ts's generic machinery — which also keeps that module, minus these
|
|
@@ -13,14 +12,16 @@ import { failOverDurationCap, parseBranchFlag, parseDurationFlag, parsePositionF
|
|
|
13
12
|
import { PAUSE_FOR_MAX_MS } from "../operator/operator-intent.js";
|
|
14
13
|
import { JSON_FLAG, ROLE_FLAG, ROLE_VALUE_ERROR, rejectUnknownDoubleDash, } from "./cli-flag-specs.js";
|
|
15
14
|
import { fail } from "./cli-output.js";
|
|
15
|
+
import { DOCTOR_CHECK_NAMES } from "../doctor/doctor-check-names.js";
|
|
16
|
+
import { typoSuffix } from "../text/suggest.js";
|
|
16
17
|
import { templateIds, unknownTemplateError } from "../init/init-templates.js";
|
|
17
18
|
import { errorMessage } from "../text/text.js";
|
|
18
19
|
/** Peel a positional-first command's bare tokens off the argument list: every flag-shaped
|
|
19
20
|
* token rides in rest for rejectUnknownArgs, every bare token is a positional. For commands
|
|
20
|
-
* with no valued flags (
|
|
21
|
-
* prefix test — a negative
|
|
21
|
+
* with no valued flags (history: `--json` alone; bug/plan via fileAndAnnounce) the split is a
|
|
22
|
+
* prefix test — a negative run number (`history bugfix -3`) arrives flag-shaped and fails the
|
|
22
23
|
* unknown-arg gate, which is the right answer for a non-positive n anyway. Lives here with
|
|
23
|
-
* the CLI's other argument helpers, shared by cli.ts's
|
|
24
|
+
* the CLI's other argument helpers, shared by cli.ts's history case and
|
|
24
25
|
* backlog-cli.ts's fileAndAnnounce. */
|
|
25
26
|
export function peelPositionals(args) {
|
|
26
27
|
const positionals = [];
|
|
@@ -29,17 +30,34 @@ export function peelPositionals(args) {
|
|
|
29
30
|
(arg.startsWith("-") ? rest : positionals).push(arg);
|
|
30
31
|
return { positionals, rest };
|
|
31
32
|
}
|
|
33
|
+
/** Map `tumwater doctor`'s bare tokens to check names (case-insensitive, deduplicated, in the
|
|
34
|
+
* order named); undefined for none, which runs every check. An unknown name fails with the
|
|
35
|
+
* closest check as a hint. */
|
|
36
|
+
export function parseDoctorChecks(positionals) {
|
|
37
|
+
if (positionals.length === 0)
|
|
38
|
+
return undefined;
|
|
39
|
+
const names = new Set();
|
|
40
|
+
for (const token of positionals) {
|
|
41
|
+
const name = DOCTOR_CHECK_NAMES.find((n) => n.toLowerCase() === token.toLowerCase());
|
|
42
|
+
if (name === undefined)
|
|
43
|
+
fail(`tumwater doctor: unknown check "${token}"${typoSuffix(token, DOCTOR_CHECK_NAMES)} (\`tumwater doctor\` lists every check by name)`);
|
|
44
|
+
else
|
|
45
|
+
names.add(name);
|
|
46
|
+
}
|
|
47
|
+
return [...names];
|
|
48
|
+
}
|
|
32
49
|
/** The `history` listing flags that take a separate value token. */
|
|
33
|
-
const HISTORY_LISTING_VALUED_FLAGS = ["-n", "--since", "--grep", "--result", "--role"];
|
|
50
|
+
const HISTORY_LISTING_VALUED_FLAGS = ["-n", "--since", "--until", "--grep", "--result", "--role", "--model", "--by"];
|
|
34
51
|
/** True when `history`'s args are the one-run trail form (`history <role> <n>`, `history
|
|
35
|
-
* <role> --last`): a token that is neither a flag nor the
|
|
36
|
-
* A valued flag's value is skipped by position, so
|
|
52
|
+
* <role> --last`, bare `history --last`): `--last`, or a token that is neither a flag nor the
|
|
53
|
+
* value of a listing-form valued flag. A valued flag's value is skipped by position, so
|
|
54
|
+
* `--grep -x` stays a listing. */
|
|
37
55
|
export function historyTrailForm(args) {
|
|
38
56
|
for (let i = 0; i < args.length; i++) {
|
|
39
57
|
const arg = args[i];
|
|
40
58
|
if (HISTORY_LISTING_VALUED_FLAGS.includes(arg))
|
|
41
59
|
i++;
|
|
42
|
-
else if (!arg.startsWith("-"))
|
|
60
|
+
else if (!arg.startsWith("-") || arg === "--last")
|
|
43
61
|
return true;
|
|
44
62
|
}
|
|
45
63
|
return false;
|
|
@@ -69,9 +87,10 @@ function readPromptFile(file) {
|
|
|
69
87
|
}
|
|
70
88
|
}
|
|
71
89
|
/** A `--file <path>` value that must be present: the one home of the missing-value refusal
|
|
72
|
-
* shared by
|
|
73
|
-
*
|
|
74
|
-
* claimed by each parser's stray-argument
|
|
90
|
+
* shared by every `--file`-taking parser — init, prompt's edit and enqueue branches, plan/bug
|
|
91
|
+
* add and edit (fileAndAnnounce / editAndAnnounce), and the questions command — so the wording
|
|
92
|
+
* cannot drift between them. The flag token itself is claimed by each parser's stray-argument
|
|
93
|
+
* accounting; this helper only owns the value. */
|
|
75
94
|
export function promptFileValue(file) {
|
|
76
95
|
if (!file)
|
|
77
96
|
fail("--file needs a path");
|
|
@@ -90,7 +109,7 @@ function readPromptFileChecked(file) {
|
|
|
90
109
|
/** Fail when a read `--file` prompt holds no text: an empty (or whitespace-only) file reads
|
|
91
110
|
* as an empty prompt, which the bare-init path would then treat as "re-seed from README.md"
|
|
92
111
|
* (the operator's --file argument silently ignored on an initialized repo), and a generic
|
|
93
|
-
* "
|
|
112
|
+
* "a brief is required" (which never names the file) on a fresh one; the prompt
|
|
94
113
|
* queue would enqueue nothing. Names the file, like every other bad --file shape. Shared by
|
|
95
114
|
* the init and prompt parsers, so the message cannot drift between them. */
|
|
96
115
|
function failEmptyPromptFile(file, contents) {
|
|
@@ -129,7 +148,7 @@ function rejectDuplicateFlags(args, flags) {
|
|
|
129
148
|
* once; with `--file` present nothing but the other flags may accompany it; a `--branch
|
|
130
149
|
* <name>` pair and the valueless flags are never prompt content; single-dash positionals are
|
|
131
150
|
* prompt content, not flags. Without these checks a misspelled --file would be baked into the
|
|
132
|
-
*
|
|
151
|
+
* brief text — injected into every run of every role until someone edits the project
|
|
133
152
|
* brief. */
|
|
134
153
|
export function parseInitArgs(args) {
|
|
135
154
|
const known = INIT_FLAG_SPECS.flatMap((s) => s.names);
|
|
@@ -226,11 +245,12 @@ const PROMPT_FLAG_SPECS = [
|
|
|
226
245
|
{ names: ["--file"], value: true, valueName: "<path>" },
|
|
227
246
|
{ names: ["--at"], value: true, valueName: "<duration>" },
|
|
228
247
|
{ names: ["--attach"], value: true, valueName: "<path>" },
|
|
248
|
+
{ names: ["--grep"], value: true, valueName: "<text>" },
|
|
229
249
|
];
|
|
230
250
|
/** `tumwater prompt` argument handling, following parseInitArgs' pattern. Like init's,
|
|
231
251
|
* positionals are free-form prompt content — but a double-dash token must be a real flag
|
|
232
|
-
* (`--role <id>`, `--list`, `--json`, `--
|
|
233
|
-
* `--at <duration>`), or
|
|
252
|
+
* (`--role <id>`, `--list`, `--json`, `--grep <text>`, `--cancel <n>`, `--edit <n>`,
|
|
253
|
+
* `--top <n>`, `--file <path>`, `--at <duration>`), or
|
|
234
254
|
* it would be baked into the queued prompt (the same class of bug parseInitArgs fixed: today
|
|
235
255
|
* `tumwater prompt --foo text` enqueues "--foo text"). Single-dash positionals remain prompt
|
|
236
256
|
* content. `--list`, `--cancel`, `--edit` and `--top` are mutually exclusive and may
|
|
@@ -252,6 +272,7 @@ export function parsePromptArgs(args) {
|
|
|
252
272
|
const topFlag = args.indexOf("--top");
|
|
253
273
|
const fileFlag = args.indexOf("--file");
|
|
254
274
|
const atFlag = args.indexOf("--at");
|
|
275
|
+
const grepFlag = args.indexOf("--grep");
|
|
255
276
|
// --attach is repeatable: every occurrence claims itself and its value token, like --role's
|
|
256
277
|
// single pair, so the pairs ride out of the prompt text in every mode.
|
|
257
278
|
const attachFlags = args.flatMap((a, i) => (a === "--attach" ? [i] : []));
|
|
@@ -281,6 +302,13 @@ export function parsePromptArgs(args) {
|
|
|
281
302
|
// prompt text (or beside a state change), so it is refused before either branch runs.
|
|
282
303
|
if (jsonFlags.length > 0 && listFlag < 0)
|
|
283
304
|
fail("--json only applies to --list");
|
|
305
|
+
if (grepFlag >= 0 && listFlag < 0)
|
|
306
|
+
fail("--grep only applies to --list");
|
|
307
|
+
const grepRaw = grepFlag >= 0 ? args[grepFlag + 1] : undefined;
|
|
308
|
+
if (grepFlag >= 0 && (!grepRaw || grepRaw.startsWith("--"))) {
|
|
309
|
+
fail("--grep needs text (usage: tumwater prompt --list --grep <text>)");
|
|
310
|
+
}
|
|
311
|
+
const grepClaim = grepFlag >= 0 ? [grepFlag, grepFlag + 1] : [];
|
|
284
312
|
// The queue-only flags --file and --at have nothing to mean in the read-only and destructive
|
|
285
313
|
// modes (--list and --cancel): --file is the file-shaped twin of free-form text (--edit
|
|
286
314
|
// accepts it as its replacement text, so the editFlag test below exempts that one mode), and
|
|
@@ -317,8 +345,8 @@ export function parsePromptArgs(args) {
|
|
|
317
345
|
failOverDurationCap("--at", atDelayMs, PAUSE_FOR_MAX_MS);
|
|
318
346
|
}
|
|
319
347
|
if (listFlag >= 0) {
|
|
320
|
-
failStrayArg(args, "with --list there is no prompt text", listFlag, ...jsonFlags, ...roleClaim);
|
|
321
|
-
return { mode: "list", role, json: jsonFlags.length > 0 };
|
|
348
|
+
failStrayArg(args, "with --list there is no prompt text", listFlag, ...jsonFlags, ...roleClaim, ...grepClaim);
|
|
349
|
+
return { mode: "list", role, json: jsonFlags.length > 0, grep: grepRaw ?? null };
|
|
322
350
|
}
|
|
323
351
|
if (cancelFlag >= 0) {
|
|
324
352
|
const n = parsePositionFlag("--cancel", args[cancelFlag + 1], "--cancel 2");
|
|
@@ -4,6 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { spawnSync } from "node:child_process";
|
|
6
6
|
import { fail } from "./cli-output.js";
|
|
7
|
+
import { removeTree } from "../files/files.js";
|
|
7
8
|
/** Signal number → name, for the shell's 128+n convention: a shell that does not re-raise a
|
|
8
9
|
* signal-killed child (dash on Linux) exits with 128+signo, so node sees an exit status where
|
|
9
10
|
* bash on macOS lets it see the signal. Keyed by number, so a later alias (SIGABRT over SIGIOT)
|
|
@@ -55,7 +56,7 @@ export function editInEditor(initial, fileName, fallback = "pass the new text or
|
|
|
55
56
|
}
|
|
56
57
|
}
|
|
57
58
|
finally {
|
|
58
|
-
|
|
59
|
+
removeTree(dir);
|
|
59
60
|
}
|
|
60
61
|
// fail() exits the process, which would skip the finally above, so it runs after cleanup.
|
|
61
62
|
if (failure !== undefined)
|