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
package/dist/src/inbox/inbox.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
// vocabulary: plain
|
|
2
|
-
import fs from "node:fs";
|
|
3
1
|
import path from "node:path";
|
|
4
|
-
import { ensureParentDir, readTextIfExists, writeTextAtomic } from "../files/files.js";
|
|
2
|
+
import { dirEntryNames, ensureParentDir, readTextIfExists, writeTextAtomic } from "../files/files.js";
|
|
5
3
|
import { listQueueFiles, queueFileName, queueFileStamp, removeQueueFile } from "../files/file-queue.js";
|
|
6
4
|
import { cachedByStat } from "../files/stat-cache.js";
|
|
7
5
|
import { roleInboxDir } from "../paths.js";
|
|
8
6
|
import { DIRECTOR_ROLE } from "../roles/roles.js";
|
|
9
7
|
import { knownRoleIdsCached } from "../config/config.js";
|
|
10
|
-
import {
|
|
8
|
+
import { humanAgo, humanSeconds, secondsUntil } from "../text/datetime.js";
|
|
11
9
|
import { errorMessage, truncate } from "../text/text.js";
|
|
12
10
|
import { warnEvent } from "../events/events.js";
|
|
13
11
|
import { isPromptImageSibling } from "./inbox-attachments.js";
|
|
14
12
|
/** File-based queues of user prompts. Any process can enqueue; the orchestrator pops. Ordering
|
|
15
13
|
* comes from the timestamped filenames. The director's queue is the historical one at the inbox
|
|
16
|
-
* root; every other
|
|
17
|
-
* queues a request only that
|
|
14
|
+
* root; every other role has its own subdirectory (roleInboxDir), so `tumwater prompt --role <id>`
|
|
15
|
+
* queues a request only that role's next run sees.
|
|
18
16
|
*
|
|
19
17
|
* This module is the store: enqueueing, listing, peeking, and dequeuing, plus the shared
|
|
20
18
|
* takeQueuedFile race policy. The cancel half — position-, list-, and file-addressed removal
|
|
@@ -41,14 +39,14 @@ export function promptPreview(text) {
|
|
|
41
39
|
return truncate(stripNotBeforeMarker(text), PROMPT_PREVIEW_MAX);
|
|
42
40
|
}
|
|
43
41
|
let seq = 0;
|
|
44
|
-
/** Append a prompt to a
|
|
42
|
+
/** Append a prompt to a role's queue as one timestamped file (creating the queue dir if needed)
|
|
45
43
|
* and return its path. The filename orders prompts across processes by wall-clock time; the
|
|
46
44
|
* per-process counter and pid break ties within one process. No event is logged —
|
|
47
45
|
* inbox-submit.ts's submitPrompt and submitRolePrompt are the user-facing wrappers that add the
|
|
48
46
|
* prompt_enqueued line, and PendingPrompt's re-queue of an unfulfilled prompt calls this directly.
|
|
49
47
|
* The write is atomic (writeTextAtomic) because the queue's readers — the dashboards' 1 s poll,
|
|
50
|
-
* `tumwater prompt --list`, and the dequeuing
|
|
51
|
-
* raced a plain writeFileSync could see a truncated prompt and run a
|
|
48
|
+
* `tumwater prompt --list`, and the dequeuing role — run in other processes, and a read that
|
|
49
|
+
* raced a plain writeFileSync could see a truncated prompt and run a run on a half user request.
|
|
52
50
|
* The optional decorate hook runs before that one write with the file's path and may return the
|
|
53
51
|
* final text instead — submitPromptWithImages uses it to save the prompt's images beside the
|
|
54
52
|
* queue file and append their reference lines, so the queue file is born complete and no
|
|
@@ -69,15 +67,15 @@ export function enqueueRolePrompt(root, role, prompt, notBeforeMs, decorate) {
|
|
|
69
67
|
writeTextAtomic(file, text);
|
|
70
68
|
return file;
|
|
71
69
|
}
|
|
72
|
-
/** Every queued prompt file for one
|
|
73
|
-
* first (listQueueFiles over the
|
|
70
|
+
/** Every queued prompt file for one role as a path joined onto the role's inbox dir, oldest
|
|
71
|
+
* first (listQueueFiles over the role's inbox dir, .md entries only). Prompts still deferred by
|
|
74
72
|
* a not-before marker are included — deliverability filtering is the callers' job
|
|
75
73
|
* (deliverablePredicate, deliverablePromptCount) — and a missing inbox dir reads as an empty
|
|
76
74
|
* queue. */
|
|
77
75
|
export function queuedFiles(root, role) {
|
|
78
76
|
return listQueueFiles(roleInboxDir(root, role), ".md");
|
|
79
77
|
}
|
|
80
|
-
/** Resolve the 1-based position `tumwater prompt --list`'s per-
|
|
78
|
+
/** Resolve the 1-based position `tumwater prompt --list`'s per-role numbering shows into one
|
|
81
79
|
* queue file — the shared range-check-and-pick half of cancelRolePrompt (inbox-cancel.ts)
|
|
82
80
|
* and editRolePrompt (inbox-edit.ts), so the two cannot drift on the error or the numbering.
|
|
83
81
|
* Throws for out-of-range positions with no side effects. The undefined-pick check folds into
|
|
@@ -94,12 +92,12 @@ export function queuedFileAtPosition(root, role, position) {
|
|
|
94
92
|
}
|
|
95
93
|
return file;
|
|
96
94
|
}
|
|
97
|
-
/** Number of prompts currently queued for one
|
|
95
|
+
/** Number of prompts currently queued for one role and deliverable now — a directory listing
|
|
98
96
|
* plus, per file, one stat-cached content read (the prompt cache below; an unchanged file
|
|
99
|
-
* costs one stat). Defaults to the director's queue; a role argument counts that
|
|
100
|
-
* per-role queue (scheduling passes it so a queued prompt makes its
|
|
97
|
+
* costs one stat). Defaults to the director's queue; a role argument counts that role's own
|
|
98
|
+
* per-role queue (scheduling passes it so a queued prompt makes its role due by itself).
|
|
101
99
|
* A prompt deferred by the not-before marker (its time still in the future) stays excluded,
|
|
102
|
-
* so a deferred prompt alone never makes its
|
|
100
|
+
* so a deferred prompt alone never makes its role due; once due, the marker falls out of the
|
|
103
101
|
* count naturally. A missing inbox dir reads as 0, like queuedPrompts and dequeuePrompt. */
|
|
104
102
|
export function inboxSize(root, role = DIRECTOR_ROLE) {
|
|
105
103
|
return deliverablePromptCount(root, role);
|
|
@@ -132,7 +130,7 @@ const promptCache = new Map();
|
|
|
132
130
|
function cachedPromptText(file) {
|
|
133
131
|
return cachedByStat(promptCache, file, file, () => readTextIfExists(file), (t) => t);
|
|
134
132
|
}
|
|
135
|
-
/** The one read pass over a
|
|
133
|
+
/** The one read pass over a role's queue that serves every list-shaped consumer: each queued
|
|
136
134
|
* file paired with its basename, full text, and the enqueue stamp parsed from the filename
|
|
137
135
|
* (queueFileStamp; null for a hand-placed name). Same listing order and race policy as
|
|
138
136
|
* queuedRolePrompts (a file that vanishes mid-listing is skipped, not thrown), and the same
|
|
@@ -153,10 +151,10 @@ export function queuedRolePromptRecords(root, role) {
|
|
|
153
151
|
}
|
|
154
152
|
return out;
|
|
155
153
|
}
|
|
156
|
-
/** Full text of every prompt queued for one
|
|
154
|
+
/** Full text of every prompt queued for one role, in execution order (oldest first) — the same
|
|
157
155
|
* filename sort dequeueRolePrompt pops by. A not-yet-deliverable prompt (the not-before marker
|
|
158
156
|
* still in the future) is not part of the execution order: it is skipped here, so peek and
|
|
159
|
-
* dequeue can never hand a
|
|
157
|
+
* dequeue can never hand a run a prompt its time has not reached. A missing queue directory
|
|
160
158
|
* reads as an empty queue, like inboxSize and dequeueRolePrompt; a file that vanishes between
|
|
161
159
|
* listing and reading (a concurrent dequeue or cancel) is skipped rather than throwing, so a
|
|
162
160
|
* polled snapshot can never crash on it. Unchanged files are served from the stat-keyed cache
|
|
@@ -168,7 +166,7 @@ export function queuedRolePrompts(root, role) {
|
|
|
168
166
|
.filter((e) => deliverableAt(e.notBeforeMs, now))
|
|
169
167
|
.map((e) => e.text);
|
|
170
168
|
}
|
|
171
|
-
/** Every queued prompt of one
|
|
169
|
+
/** Every queued prompt of one role with the queue-file basename that addresses it and its
|
|
172
170
|
* enqueue stamp, in execution order — the snapshot's cancel-addressable payload
|
|
173
171
|
* (StatusSnapshot.inboxFiles and roleInboxPrompts). Same pass, order, race policy, and stat
|
|
174
172
|
* cache as queuedRolePrompts. */
|
|
@@ -180,14 +178,14 @@ export function queuedRolePromptEntries(root, role) {
|
|
|
180
178
|
notBeforeMs: e.notBeforeMs,
|
|
181
179
|
}));
|
|
182
180
|
}
|
|
183
|
-
/** The
|
|
184
|
-
* the director first, then the remaining cached catalog ids — the per-
|
|
181
|
+
/** The role order a list-wide position (`--cancel`/`--edit` with no `--role`) resolves across:
|
|
182
|
+
* the director first, then the remaining cached catalog ids — the per-role sections `prompt
|
|
185
183
|
* --list` and the TUI Queued pane print, each numbered from 1. The single home of that scope,
|
|
186
184
|
* shared by the cancel and edit branches so neither can drift from what the list showed. */
|
|
187
185
|
export function listWideScope(root) {
|
|
188
186
|
return [DIRECTOR_ROLE, ...knownRoleIdsCached(root).filter((r) => r !== DIRECTOR_ROLE)];
|
|
189
187
|
}
|
|
190
|
-
/** One traversal of the queues behind the list-shaped queue views: with `role`, that
|
|
188
|
+
/** One traversal of the queues behind the list-shaped queue views: with `role`, that role's
|
|
191
189
|
* queue alone; otherwise the director first (its queue is the shared pre-1/2 inbox), then the
|
|
192
190
|
* remaining catalog ids in order, empty queues skipped — exactly the sections the prose
|
|
193
191
|
* prints. */
|
|
@@ -195,7 +193,7 @@ export function queuedListRows(root, role, validIds) {
|
|
|
195
193
|
const prompts = [];
|
|
196
194
|
const record = (r, position, e) =>
|
|
197
195
|
// The marker is stripped from the text both shapes print (stripNotBeforeMarker): the
|
|
198
|
-
// prose and --json are the operator's view of what a
|
|
196
|
+
// prose and --json are the operator's view of what a role will run, and the marker is
|
|
199
197
|
// plumbing, not content. Full verbatim prompt text minus plumbing, still not a preview.
|
|
200
198
|
prompts.push({ role: r, position, file: e.file, text: stripNotBeforeMarker(e.text), queuedAtMs: e.queuedAtMs, notBeforeMs: e.notBeforeMs });
|
|
201
199
|
if (role !== null) {
|
|
@@ -224,11 +222,19 @@ function queuedAgeSuffix(queuedAtMs, notBeforeMs, now) {
|
|
|
224
222
|
}
|
|
225
223
|
if (queuedAtMs === null)
|
|
226
224
|
return "";
|
|
227
|
-
|
|
228
|
-
|
|
225
|
+
return ` (queued ${humanAgo(queuedAtMs, now)})`;
|
|
226
|
+
}
|
|
227
|
+
/** Keep the rows whose prompt text contains `grep`, case-insensitively, each row still carrying
|
|
228
|
+
* its unfiltered per-role `position`. A null grep keeps every row. The one filter `prompt --list
|
|
229
|
+
* --grep` and the TUI Inbox pane's `/` search share. */
|
|
230
|
+
export function queuedRowsMatching(rows, grep) {
|
|
231
|
+
if (grep === null)
|
|
232
|
+
return [...rows];
|
|
233
|
+
const needle = grep.toLowerCase();
|
|
234
|
+
return rows.filter((row) => row.text.toLowerCase().includes(needle));
|
|
229
235
|
}
|
|
230
236
|
/** Render the list-shaped queue view as the prose `prompt --list` prints and the TUI Queued
|
|
231
|
-
* pane shows: consecutive rows grouped by role, one `<role>:` section per
|
|
237
|
+
* pane shows: consecutive rows grouped by role, one `<role>:` section per role holding
|
|
232
238
|
* `"<position>. <text><queuedAgeSuffix>"` lines, sections joined by `\n`. Empty rows render
|
|
233
239
|
* the empty string, so each surface keeps its own empty-state note. One renderer so the CLI
|
|
234
240
|
* and the TUI cannot drift on order, numbering, or the age/countdown wording. */
|
|
@@ -249,7 +255,7 @@ export function renderQueuedList(rows, now) {
|
|
|
249
255
|
sections.push(`${currentRole}:\n${lines.join("\n")}`);
|
|
250
256
|
return sections.join("\n");
|
|
251
257
|
}
|
|
252
|
-
/** How many prompts are queued for one
|
|
258
|
+
/** How many prompts are queued for one role and deliverable now, without re-reading unchanged
|
|
253
259
|
* contents — the snapshot's per-role counts poll every role
|
|
254
260
|
* every second, so the count stays a listing plus one stat-cached read per file (the prompt
|
|
255
261
|
* cache above keeps an unchanged file at one stat). A deferred prompt (its not-before time
|
|
@@ -283,9 +289,9 @@ export function takeQueuedFile(file) {
|
|
|
283
289
|
* by a hyphen (`a-notes.md` beside `a.md`), and deleting it would take another prompt with
|
|
284
290
|
* this one — files like that are left alone. ENOENT-tolerant through removeQueueFile, and a
|
|
285
291
|
* queue directory that is already gone leaves nothing to clean. Called by the cancel paths
|
|
286
|
-
* (inbox-cancel.ts's takeCancelledPrompt) and by a fulfilled
|
|
292
|
+
* (inbox-cancel.ts's takeCancelledPrompt) and by a fulfilled run's settle sweep
|
|
287
293
|
* (src/inbox/pending-prompt.ts's settleImages): a cancelled or consumed prompt takes its
|
|
288
|
-
* attachments with it. A DEQUEUE does not call this — the
|
|
294
|
+
* attachments with it. A DEQUEUE does not call this — the run's agent still reads the
|
|
289
295
|
* referenced files, so they must survive until the prompt is fulfilled or cancelled, and a
|
|
290
296
|
* requeue first moves them to the new queue file's stem (movePromptImages) so this sweep
|
|
291
297
|
* finds them under the stem the requeued file actually names.
|
|
@@ -296,14 +302,7 @@ export function takeQueuedFile(file) {
|
|
|
296
302
|
export function removeSameStemSiblings(root, role, file) {
|
|
297
303
|
const dir = path.dirname(file);
|
|
298
304
|
const stem = path.basename(file, ".md");
|
|
299
|
-
|
|
300
|
-
try {
|
|
301
|
-
entries = fs.readdirSync(dir);
|
|
302
|
-
}
|
|
303
|
-
catch {
|
|
304
|
-
return; // The queue directory itself is gone — nothing to clean.
|
|
305
|
-
}
|
|
306
|
-
for (const entry of entries) {
|
|
305
|
+
for (const entry of dirEntryNames(dir)) {
|
|
307
306
|
if (entry === path.basename(file) || !isPromptImageSibling(stem, entry))
|
|
308
307
|
continue;
|
|
309
308
|
try {
|
|
@@ -324,11 +323,11 @@ export function removeSameStemSiblings(root, role, file) {
|
|
|
324
323
|
/** Remove and return the oldest queued prompt, or null when empty — including when a
|
|
325
324
|
* concurrent `tumwater prompt --cancel` removes it between listing and reading (or between
|
|
326
325
|
* reading and removal): the module's race policy is that a vanished file is skipped rather
|
|
327
|
-
* than throwing, so the director sees an empty inbox and skips its
|
|
326
|
+
* than throwing, so the director sees an empty inbox and skips its run instead of failing
|
|
328
327
|
* with a raw ENOENT. When the removal itself hits ENOENT the cancel won after our read —
|
|
329
328
|
* the prompt was cancelled, so it must not be executed: null (skip), never the text we
|
|
330
329
|
* already read. Non-ENOENT errors (e.g. EACCES) are rethrown — they are not a race with a
|
|
331
|
-
* cancel. A caller that must clean the prompt's attachments afterwards (a
|
|
330
|
+
* cancel. A caller that must clean the prompt's attachments afterwards (a run's
|
|
332
331
|
* pending-prompt bookkeeping) needs the file's stem too, so dequeueRolePromptEntry also
|
|
333
332
|
* returns the queue file it took. */
|
|
334
333
|
export function dequeueRolePromptEntry(root, role) {
|
|
@@ -338,15 +337,15 @@ export function dequeueRolePromptEntry(root, role) {
|
|
|
338
337
|
const text = takeQueuedFile(oldest);
|
|
339
338
|
return text === null ? null : { text, file: oldest };
|
|
340
339
|
}
|
|
341
|
-
/** Remove and return the oldest prompt queued for one
|
|
340
|
+
/** Remove and return the oldest prompt queued for one role; see dequeueRolePromptEntry. */
|
|
342
341
|
export function dequeueRolePrompt(root, role) {
|
|
343
342
|
return dequeueRolePromptEntry(root, role)?.text ?? null;
|
|
344
343
|
}
|
|
345
|
-
/** Full text of the oldest prompt queued for one
|
|
344
|
+
/** Full text of the oldest prompt queued for one role, read WITHOUT consuming it — the
|
|
346
345
|
* preview seam behind `tumwater role <id>`'s next-prompt view. Same reader, listing order,
|
|
347
346
|
* and race policy as queuedRolePrompts (a file that vanishes mid-listing is skipped, not
|
|
348
347
|
* thrown), but the queue file is never unlinked: a preview can never cost a queued prompt
|
|
349
|
-
* its
|
|
348
|
+
* its run, which is the property test/run-prompt.test.ts pins through the preview seam.
|
|
350
349
|
* A missing queue directory reads as null, like dequeueRolePrompt. */
|
|
351
350
|
export function peekRolePrompt(root, role) {
|
|
352
351
|
return queuedRolePrompts(root, role)[0] ?? null;
|
|
@@ -3,31 +3,31 @@ import { movePromptImages, stripVanishedImageReferences } from "./inbox-attachme
|
|
|
3
3
|
import { DIRECTOR_ROLE } from "../roles/roles.js";
|
|
4
4
|
import { warnEventBestEffort } from "../events/events.js";
|
|
5
5
|
/**
|
|
6
|
-
* The raw user prompt a director
|
|
7
|
-
* that leaves the request unfulfilled — extracted from
|
|
8
|
-
* (src/
|
|
6
|
+
* The raw user prompt a director run is executing, and the requeue policy for every outcome
|
|
7
|
+
* that leaves the request unfulfilled — extracted from RoleRunner's private methods
|
|
8
|
+
* (src/runner/runner.ts) so the subtle fresh-vs-resume requeue semantics have one named home beside
|
|
9
9
|
* the queue mechanics they ride on (src/inbox/inbox.ts).
|
|
10
10
|
*/
|
|
11
11
|
export class PendingPrompt {
|
|
12
12
|
root;
|
|
13
13
|
role;
|
|
14
14
|
/** The dequeued request, memory-only: the queue file is the durable store, and every
|
|
15
|
-
* unfulfilled outcome hands the request back to it before the
|
|
15
|
+
* unfulfilled outcome hands the request back to it before the run ends. */
|
|
16
16
|
value = null;
|
|
17
|
-
/** The queue file the recorded request was dequeued from, so a fulfilled
|
|
17
|
+
/** The queue file the recorded request was dequeued from, so a fulfilled run sweeps the
|
|
18
18
|
* request's same-stem image attachments by that file's stem (settleImages). Null when the
|
|
19
19
|
* request was recorded without one (tests) or carried no file. */
|
|
20
20
|
queueFile = null;
|
|
21
21
|
/** Whether the current request's images were handed back to a queue (requeue*), so a
|
|
22
|
-
* settle must keep them for the next
|
|
22
|
+
* settle must keep them for the next run instead of removing them. */
|
|
23
23
|
retain = false;
|
|
24
24
|
constructor(root, role) {
|
|
25
25
|
this.root = root;
|
|
26
26
|
this.role = role;
|
|
27
27
|
}
|
|
28
|
-
/** Record the user request a just-dequeued
|
|
28
|
+
/** Record the user request a just-dequeued run prompt carries (assembleRunPrompt's
|
|
29
29
|
* userPrompt) together with the queue file it came from (userPromptFile), so an unfulfilled
|
|
30
|
-
*
|
|
30
|
+
* run can re-queue it instead of losing the request and a fulfilled one can clean its
|
|
31
31
|
* attachments. */
|
|
32
32
|
record(userPrompt, queueFile = null) {
|
|
33
33
|
if (userPrompt === null)
|
|
@@ -36,23 +36,23 @@ export class PendingPrompt {
|
|
|
36
36
|
this.queueFile = queueFile;
|
|
37
37
|
this.retain = false;
|
|
38
38
|
}
|
|
39
|
-
/** The raw user prompt this
|
|
39
|
+
/** The raw user prompt this run is executing (null for roles), so an unfulfilled
|
|
40
40
|
* outcome below can re-queue it. */
|
|
41
41
|
get() {
|
|
42
42
|
return this.value;
|
|
43
43
|
}
|
|
44
44
|
/** Drop the recorded request without re-queueing it — the explicit-stop arm of
|
|
45
|
-
*
|
|
45
|
+
* finishAbortedRun and every fulfilled path. Leaves the image files for settleImages:
|
|
46
46
|
* the same clear runs before the requeue branches, whose requeue* methods mark the images
|
|
47
47
|
* retained, so only a genuinely unrequeued request loses them. */
|
|
48
48
|
clear() {
|
|
49
49
|
this.value = null;
|
|
50
50
|
}
|
|
51
|
-
/** The end-of-
|
|
51
|
+
/** The end-of-run half of the attachment lifetime: sweep the fulfilled request's same-stem
|
|
52
52
|
* image files (removeSameStemSiblings, keyed on the dequeued file's stem — never on paths
|
|
53
53
|
* named by prompt text) UNLESS an unfulfilled outcome handed the request back to a queue
|
|
54
54
|
* (retain), then the files must survive for the requeued prompt to read. Always forgets the
|
|
55
|
-
* request afterwards, so a fresh
|
|
55
|
+
* request afterwards, so a fresh run starts clean. */
|
|
56
56
|
settleImages() {
|
|
57
57
|
if (!this.retain && this.queueFile !== null)
|
|
58
58
|
removeSameStemSiblings(this.root, this.role, this.queueFile);
|
|
@@ -60,17 +60,17 @@ export class PendingPrompt {
|
|
|
60
60
|
this.retain = false;
|
|
61
61
|
this.value = null;
|
|
62
62
|
}
|
|
63
|
-
/** Put an unfulfilled user prompt back in the queue it came from so the next
|
|
63
|
+
/** Put an unfulfilled user prompt back in the queue it came from so the next run retries it
|
|
64
64
|
* — the one place that policy lives, shared by every outcome that leaves the request undone
|
|
65
65
|
* (abort, timeout, failure without changes, review abort, context-ceiling cut-off, red-main
|
|
66
66
|
* gate). The queue is the role's own (the director's historical inbox for the director), so a
|
|
67
|
-
* re-queued per-role request never leaks across
|
|
67
|
+
* re-queued per-role request never leaks across roles. A fulfilled no_change never reaches
|
|
68
68
|
* here: re-queueing it would loop the prompt forever. Image attachments ride along: the
|
|
69
69
|
* re-queue moves them to the new queue file's stem so a later cancel or fulfilling sweep
|
|
70
70
|
* finds them, and a reference whose file is genuinely gone (removed out of band) is dropped
|
|
71
71
|
* and replaced by one note naming the loss — a re-queued prompt must never send the next
|
|
72
|
-
*
|
|
73
|
-
* retained, so settleImages keeps them for the next
|
|
72
|
+
* run's agent after files that are no longer there. Either way the images are marked
|
|
73
|
+
* retained, so settleImages keeps them for the next run. */
|
|
74
74
|
requeueUnfulfilled(userPrompt) {
|
|
75
75
|
if (!userPrompt)
|
|
76
76
|
return;
|
|
@@ -79,21 +79,21 @@ export class PendingPrompt {
|
|
|
79
79
|
}
|
|
80
80
|
/** Re-queue whatever request is still recorded and drop it from memory: an exception between
|
|
81
81
|
* the dequeue/reclaim and the pi run leaves the request only in this field — memory the
|
|
82
|
-
* failed
|
|
83
|
-
* run inside
|
|
82
|
+
* failed run is about to drop, with no outcome handler left to re-queue it (the handlers
|
|
83
|
+
* run inside runOnce, after the pi run). The queue is the durable store, so the catch
|
|
84
84
|
* re-queues whatever is still pending, like every unfulfilled outcome does; it is always
|
|
85
85
|
* null once a pi run has been accounted for. */
|
|
86
86
|
requeuePendingUnfulfilled() {
|
|
87
87
|
this.requeueUnfulfilled(this.value);
|
|
88
88
|
this.value = null;
|
|
89
89
|
}
|
|
90
|
-
/** Re-queue an unfulfilled prompt whose pi session the next
|
|
90
|
+
/** Re-queue an unfulfilled prompt whose pi session the next run will resume: the resumed
|
|
91
91
|
* session still owns the request in its (compacted) context, so the re-queued copy is only
|
|
92
92
|
* the durable store for a restart — the resume must reclaim exactly it as its own user
|
|
93
93
|
* prompt (the resume's fulfillment consumes it; only its failure paths re-queue it) instead
|
|
94
|
-
* of leaving it queued for a later fresh
|
|
94
|
+
* of leaving it queued for a later fresh run to run the same request twice. The queue file
|
|
95
95
|
* is recorded so the reclaim takes that exact prompt whatever else was enqueued meanwhile.
|
|
96
|
-
* Director
|
|
96
|
+
* Director runs never resume — their re-queued prompt always reruns fresh — so they take
|
|
97
97
|
* the plain path. */
|
|
98
98
|
requeueForResume(state, userPrompt) {
|
|
99
99
|
if (!userPrompt)
|
|
@@ -105,13 +105,13 @@ export class PendingPrompt {
|
|
|
105
105
|
state.resumePromptFile = this.enqueueCarryingImages(userPrompt);
|
|
106
106
|
this.retain = true;
|
|
107
107
|
}
|
|
108
|
-
/** Reclaim the prompt the interrupted
|
|
109
|
-
* still owns that request in its context, so this
|
|
108
|
+
/** Reclaim the prompt the interrupted run re-queued (requeueForResume): the resumed session
|
|
109
|
+
* still owns that request in its context, so this run's outcome bookkeeping — re-queue on
|
|
110
110
|
* unfulfilled, clear on fulfillment — must operate on the queue's copy, or a fulfilling
|
|
111
|
-
* resume leaves it queued for a later fresh
|
|
111
|
+
* resume leaves it queued for a later fresh run to run the same request twice. The exact
|
|
112
112
|
* recorded file is taken, so an enqueue or cancel meanwhile cannot divert the reclaim; a
|
|
113
|
-
* vanished file (cancelled) reclaims nothing. The flag is consumed even when this
|
|
114
|
-
* not resume: a fresh fallback re-derives its prompt from the queue like any other
|
|
113
|
+
* vanished file (cancelled) reclaims nothing. The flag is consumed even when this run does
|
|
114
|
+
* not resume: a fresh fallback re-derives its prompt from the queue like any other run, and
|
|
115
115
|
* a stale record must never survive into a later resume. */
|
|
116
116
|
reclaimForResume(state, resuming) {
|
|
117
117
|
const reclaimFile = state.resumePromptFile;
|