tumwater 0.4.0 → 0.4.2
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 +4 -6
- package/dist/build-info.json +2 -2
- package/dist/src/agent/agent-backend.js +5 -2
- package/dist/src/agent/backend-traits.js +21 -0
- package/dist/src/agent/claude/claude-backend.js +1 -1
- package/dist/src/agent/claude/claude-stream.js +181 -182
- package/dist/src/agent/claude/{write-guard-hook.js → claude-write-guard-hook.js} +1 -1
- package/dist/src/agent/claude/claude-write-guard.js +5 -4
- package/dist/src/agent/codex/codex-backend.js +1 -1
- package/dist/src/agent/codex/codex-rollout.js +48 -45
- package/dist/src/agent/codex/codex-stream.js +269 -215
- package/dist/src/agent/codex/{write-guard-hook.js → codex-write-guard-hook.js} +2 -1
- package/dist/src/agent/codex/codex-write-guard.js +3 -3
- package/dist/src/agent/image-input.js +18 -87
- package/dist/src/agent/notes-shim.js +2 -2
- package/dist/src/agent/opencode/opencode-backend.js +2 -2
- package/dist/src/agent/opencode/opencode-catalog.js +2 -2
- package/dist/src/agent/opencode/opencode-config.js +2 -2
- package/dist/src/agent/opencode/opencode-stream.js +101 -92
- package/dist/src/agent/run-agent.js +76 -382
- package/dist/src/agent/run-settle.js +25 -15
- package/dist/src/agent/run-spawn.js +226 -0
- package/dist/src/agent/run-stream.js +185 -0
- package/dist/src/agent/session-ledger.js +16 -0
- package/dist/src/agent/write-guard.js +5 -3
- package/dist/src/backlog/backlog-archive.js +86 -170
- package/dist/src/backlog/backlog-cli-view.js +89 -70
- package/dist/src/backlog/backlog-eligibility.js +51 -59
- package/dist/src/backlog/backlog-file-bugs.js +133 -0
- package/dist/src/backlog/backlog-index-data.js +159 -0
- package/dist/src/backlog/backlog-index.js +7 -5
- package/dist/src/backlog/backlog-md.js +39 -28
- package/dist/src/backlog/backlog-release.js +21 -36
- package/dist/src/backlog/backlog-render.js +1 -1
- package/dist/src/backlog/backlog-structure.js +14 -145
- package/dist/src/backlog/backlog-write.js +31 -18
- package/dist/src/backlog/backlog.js +14 -4
- package/dist/src/backlog/question-answer.js +33 -15
- package/dist/src/baseline/main-baseline.js +71 -26
- package/dist/src/baseline/main-guardrails.js +76 -15
- package/dist/src/baseline/main-red.js +45 -94
- package/dist/src/baseline/main-watch.js +9 -3
- package/dist/src/brief/brief.js +40 -0
- package/dist/src/budget/budget-fallback-view.js +50 -8
- package/dist/src/budget/budget-wiring.js +15 -11
- package/dist/src/budget/budget.js +3 -2
- package/dist/src/build/build-check-events.js +4 -2
- package/dist/src/build/build-check-report.js +2 -1
- package/dist/src/build/build-check-scoped.js +70 -41
- package/dist/src/change/change-data.js +4 -2
- package/dist/src/cli/cli-args.js +9 -0
- package/dist/src/cli/cli-command-args.js +199 -98
- package/dist/src/cli/cli-flag-specs.js +6 -4
- package/dist/src/cli/cli-marker-commands.js +2 -2
- package/dist/src/cli/cli-query-commands.js +41 -6
- package/dist/src/cli/cli-review-commands.js +2 -1
- package/dist/src/cli/cli-role-command.js +46 -92
- package/dist/src/cli/cli-start.js +123 -47
- package/dist/src/cli/follow-view.js +3 -1
- package/dist/src/cli/help.js +19 -12
- package/dist/src/cli/log-commands.js +128 -107
- package/dist/src/cli/question-commands.js +82 -63
- package/dist/src/cli.js +396 -343
- package/dist/src/collections.js +46 -9
- package/dist/src/config/config-fallbacks.js +0 -4
- package/dist/src/config/config-live.js +179 -147
- package/dist/src/config/config-request.js +176 -51
- package/dist/src/config/config-validation-roles.js +271 -0
- package/dist/src/config/config-validation.js +10 -205
- package/dist/src/config/config-views.js +2 -7
- package/dist/src/config/config-write.js +205 -175
- package/dist/src/config/config.js +2 -1
- package/dist/src/doctor/doctor-backlog-bugs.js +24 -122
- package/dist/src/doctor/doctor-backlog-plans.js +24 -25
- package/dist/src/doctor/doctor-backlog.js +34 -42
- package/dist/src/doctor/doctor-check-names.js +4 -2
- package/dist/src/doctor/doctor-checks.js +16 -4
- package/dist/src/doctor/doctor-claude-checks.js +2 -2
- package/dist/src/doctor/doctor-codex-checks.js +9 -20
- package/dist/src/doctor/doctor-contention-checks.js +52 -19
- package/dist/src/doctor/doctor-holds.js +22 -20
- package/dist/src/doctor/doctor-model-checks.js +8 -184
- package/dist/src/doctor/doctor-notify.js +2 -5
- package/dist/src/doctor/doctor-opencode-checks.js +90 -41
- package/dist/src/doctor/doctor-principles.js +26 -0
- package/dist/src/doctor/doctor-project-checks.js +69 -19
- package/dist/src/doctor/doctor-role-notes.js +33 -0
- package/dist/src/doctor/doctor.js +13 -6
- package/dist/src/doctor/probe.js +1 -1
- package/dist/src/events/event-format.js +307 -162
- package/dist/src/events/event-labels.js +0 -1
- package/dist/src/events/event-legacy.js +1 -1
- package/dist/src/events/event-window.js +1 -1
- package/dist/src/events/events.js +15 -2
- package/dist/src/events/notify.js +1 -1
- package/dist/src/failure/failure-cluster.js +4 -3
- package/dist/src/failure/failure-data.js +126 -94
- package/dist/src/failure/failure-render.js +58 -17
- package/dist/src/failure/failure-state-change.js +308 -27
- package/dist/src/failure/time-spend.js +139 -106
- package/dist/src/files/files.js +7 -0
- package/dist/src/files/json-object.js +15 -2
- package/dist/src/gates/budget-gates.js +90 -68
- package/dist/src/gates/gate-polls.js +92 -61
- package/dist/src/gates/role-cap-gates.js +1 -1
- package/dist/src/gates/startup-gate.js +28 -28
- package/dist/src/gates/streak-gate.js +1 -1
- package/dist/src/git/git.js +1 -1
- package/dist/src/git/slot-salvage.js +9 -9
- package/dist/src/git/slots-state.js +12 -3
- package/dist/src/git/worktree-pool-startup.js +127 -0
- package/dist/src/git/worktree-pool.js +1 -120
- package/dist/src/gui/gui-admin-endpoints.js +3 -4
- package/dist/src/gui/gui-args.js +1 -1
- package/dist/src/gui/gui-backlog-commands.js +20 -11
- package/dist/src/gui/gui-backlog-endpoints.js +2 -8
- package/dist/src/gui/gui-config-commands.js +51 -76
- package/dist/src/gui/gui-endpoint-commands.js +4 -2
- package/dist/src/gui/gui-endpoint-common.js +4 -3
- package/dist/src/gui/gui-history-endpoints.js +36 -27
- package/dist/src/gui/gui-operator-commands.js +43 -17
- package/dist/src/gui/gui-prompt-commands.js +27 -21
- package/dist/src/gui/gui-quarantine-commands.js +30 -0
- package/dist/src/gui/gui-report-endpoints.js +13 -9
- package/dist/src/gui/gui-server.js +5 -3
- package/dist/src/gui/gui-team-commands.js +1 -1
- package/dist/src/history/history-data.js +7 -1
- package/dist/src/history/history-render.js +15 -10
- package/dist/src/history/history.js +103 -68
- package/dist/src/inbox/inbox-submit.js +1 -5
- package/dist/src/inbox/pending-prompt.js +3 -2
- package/dist/src/inbox/prompt-commands.js +194 -161
- package/dist/src/init/init.js +104 -25
- package/dist/src/merge/merge-core.js +1 -1
- package/dist/src/merge/merge-drain.js +1 -1
- package/dist/src/merge/merge-git.js +5 -5
- package/dist/src/merge/{merge-post-review.js → merge-post-review-drain.js} +1 -1
- package/dist/src/merge/merge-queue.js +2 -1
- package/dist/src/merge/merge-to-main.js +1 -1
- package/dist/src/merge/merge-verify.js +3 -2
- package/dist/src/operator/operator-commands.js +84 -52
- package/dist/src/operator/operator-intent.js +26 -3
- package/dist/src/operator/retire.js +2 -1
- package/dist/src/operator/revert.js +18 -12
- package/dist/src/orchestrator/orchestrator-poll.js +2 -2
- package/dist/src/orchestrator/orchestrator.js +1 -1
- package/dist/src/orchestrator/retention.js +6 -5
- package/dist/src/paths.js +10 -10
- package/dist/src/pi/pi-bin.js +2 -2
- package/dist/src/pi/pi-models.js +9 -0
- package/dist/src/pi/pi-stream.js +63 -41
- package/dist/src/pi/pi-watchdogs.js +84 -49
- package/dist/src/pi-extension/context-shake.js +55 -31
- package/dist/src/pi-extension/full-output.js +2 -3
- package/dist/src/process/process.js +24 -1
- package/dist/src/process/run-marker.js +2 -2
- package/dist/src/process/supervisor.js +24 -5
- package/dist/src/prompt/gate-notes.js +41 -16
- package/dist/src/prompt/notes-backlog.js +22 -29
- package/dist/src/prompt/principles.js +11 -0
- package/dist/src/prompt/prompt-followup.js +4 -12
- package/dist/src/prompt/prompt.js +15 -12
- package/dist/src/redeploy/redeploy-probes.js +11 -1
- package/dist/src/redeploy/redeployer.js +54 -7
- package/dist/src/redeploy/self-reload.js +7 -2
- package/dist/src/report/report-data.js +224 -320
- package/dist/src/report/report-fold.js +23 -231
- package/dist/src/report/report-main-red.js +70 -3
- package/dist/src/report/report-render.js +181 -48
- package/dist/src/report/report-since-data.js +218 -0
- package/dist/src/report/report-usage-fold.js +288 -0
- package/dist/src/report/report.js +2 -1
- package/dist/src/review/known-flakes.js +22 -3
- package/dist/src/review/post-merge-review-accept.js +3 -2
- package/dist/src/review/post-merge-review.js +16 -14
- package/dist/src/review/quarantine-render.js +29 -11
- package/dist/src/review/review-precheck.js +2 -1
- package/dist/src/roles/role-catalog.js +30 -29
- package/dist/src/roles/role-guidance.js +26 -43
- package/dist/src/roles/role-render.js +19 -0
- package/dist/src/roles/role-view.js +19 -5
- package/dist/src/roles/roles.js +2 -22
- package/dist/src/run/ci-parity.js +5 -6
- package/dist/src/run/feedback-filings.js +10 -1
- package/dist/src/run/qa-coverage.js +4 -4
- package/dist/src/run/run-apply.js +14 -2
- package/dist/src/run/run-detail-data.js +50 -10
- package/dist/src/run/run-detail-render.js +32 -1
- package/dist/src/run/run-detail.js +44 -22
- package/dist/src/run/run-dismiss.js +43 -0
- package/dist/src/run/run-finalize.js +75 -46
- package/dist/src/run/run-prompt.js +271 -187
- package/dist/src/run/run-resume.js +32 -31
- package/dist/src/run/run-stage.js +116 -64
- package/dist/src/run/run-timing.js +18 -4
- package/dist/src/run/run-verdict.js +119 -83
- package/dist/src/run/stage-backlog-checks.js +4 -31
- package/dist/src/run/stage-check.js +4 -12
- package/dist/src/run/stage-checks-shared.js +15 -0
- package/dist/src/run/stage-name-checks.js +3 -13
- package/dist/src/run/stage-path-checks.js +26 -29
- package/dist/src/runner/leftover.js +13 -4
- package/dist/src/runner/revision.js +2 -2
- package/dist/src/runner/runner-fallback.js +1 -1
- package/dist/src/runner/runner-outcome.js +0 -5
- package/dist/src/runner/runner-pi.js +72 -49
- package/dist/src/runner/runner-run.js +19 -102
- package/dist/src/runner/runner-state-load.js +0 -10
- package/dist/src/runner/runner.js +1 -32
- package/dist/src/scheduling/claims.js +4 -11
- package/dist/src/status/status-data.js +140 -91
- package/dist/src/status/status-polls.js +41 -5
- package/dist/src/status/status-role-notes.js +53 -0
- package/dist/src/status/status-roles.js +10 -37
- package/dist/src/text/datetime.js +8 -1
- package/dist/src/text/format.js +13 -1
- package/dist/src/text/phrases.js +16 -2
- package/dist/src/text/text.js +12 -0
- package/dist/src/ui/alert-feeds.js +115 -0
- package/dist/src/ui/badges.js +3 -4
- package/dist/src/ui/gui/gui-client-boot.js +78 -57
- package/dist/src/ui/gui/gui-client-drawer-config.js +8 -3
- package/dist/src/ui/gui/gui-client-drawer.js +18 -2
- package/dist/src/ui/gui/gui-client-feed.js +3 -8
- package/dist/src/ui/gui/gui-client-history.js +16 -16
- package/dist/src/ui/gui/gui-client-model.js +9 -9
- package/dist/src/ui/gui/gui-client-operator.js +6 -10
- package/dist/src/ui/gui/gui-client-pending.js +4 -4
- package/dist/src/ui/gui/gui-client-report-chart.js +111 -10
- package/dist/src/ui/gui/gui-client-report.js +70 -11
- package/dist/src/ui/gui/gui-client-roles.js +52 -12
- package/dist/src/ui/gui/gui-client-settings.js +31 -26
- package/dist/src/ui/gui/gui-client-team.js +28 -2
- package/dist/src/ui/gui/gui-client.js +33 -4
- package/dist/src/ui/gui/gui-icons.js +7 -1
- package/dist/src/ui/progress-data.js +2 -2
- package/dist/src/ui/run-progress-model.js +2 -2
- package/dist/src/ui/status-model.js +26 -16
- package/dist/src/ui/status-payload.js +149 -326
- package/dist/src/ui/status-render.js +131 -80
- package/dist/src/ui/team-alert-backlog.js +236 -0
- package/dist/src/ui/team-alert-shared.js +92 -0
- package/dist/src/ui/team-alert-status.js +326 -0
- package/dist/src/ui/team-alert-tail.js +238 -0
- package/dist/src/ui/team-alerts.js +16 -984
- package/dist/src/ui/transcript-tail.js +137 -94
- package/dist/src/ui/tui/tui-backlog.js +1 -1
- package/dist/src/ui/tui/tui-editor-answer.js +54 -44
- package/dist/src/ui/tui/tui-editor-attach.js +74 -63
- package/dist/src/ui/tui/tui-editor-backends.js +62 -56
- package/dist/src/ui/tui/tui-editor-brief.js +64 -54
- package/dist/src/ui/tui/tui-editor-budget.js +106 -89
- package/dist/src/ui/tui/tui-editor-config.js +2 -4
- package/dist/src/ui/tui/tui-editor-ctx.js +12 -1
- package/dist/src/ui/tui/tui-editor-entry.js +171 -153
- package/dist/src/ui/tui/tui-editor-instances.js +2 -1
- package/dist/src/ui/tui/tui-editor-instructions.js +50 -107
- package/dist/src/ui/tui/tui-editor-interval.js +39 -112
- package/dist/src/ui/tui/tui-editor-notes.js +28 -84
- package/dist/src/ui/tui/tui-editor-pause.js +210 -183
- package/dist/src/ui/tui/tui-editor-prompt.js +46 -35
- package/dist/src/ui/tui/tui-editor-queued.js +74 -64
- package/dist/src/ui/tui/tui-editor-quiet.js +122 -108
- package/dist/src/ui/tui/tui-editor-release.js +85 -0
- package/dist/src/ui/tui/tui-editor-retire.js +57 -46
- package/dist/src/ui/tui/tui-editor-role-enabled.js +90 -80
- package/dist/src/ui/tui/tui-editor-role-file.js +87 -0
- package/dist/src/ui/tui/tui-editor-role-key.js +50 -42
- package/dist/src/ui/tui/tui-editor-search.js +70 -58
- package/dist/src/ui/tui/tui-editor-session.js +3 -0
- package/dist/src/ui/tui/tui-editors.js +4 -1
- package/dist/src/ui/tui/tui-frame.js +7 -3
- package/dist/src/ui/tui/tui-history.js +12 -10
- package/dist/src/ui/tui/tui-keys.js +6 -1
- package/dist/src/ui/tui/tui-pane-activity.js +62 -50
- package/dist/src/ui/tui/tui-pane-backlog.js +4 -4
- package/dist/src/ui/tui/tui-pane-ctx.js +1 -1
- package/dist/src/ui/tui/tui-pane-health.js +45 -26
- package/dist/src/ui/tui/tui-pane-history.js +296 -264
- package/dist/src/ui/tui/tui-pane-report.js +74 -57
- package/dist/src/ui/tui/tui-pane-session.js +6 -2
- package/dist/src/ui/tui/tui-pane-transcript.js +158 -131
- package/dist/src/ui/tui/tui-pane.js +201 -174
- package/dist/src/ui/tui/tui-panes.js +211 -148
- package/dist/src/ui/tui/tui.js +4 -4
- package/dist/src/verdict/fix-claim.js +18 -6
- package/dist/src/verdict/refusal.js +32 -7
- package/package.json +1 -1
- package/dist/src/doctor/image-probe.js +0 -257
- /package/dist/src/gui/{http-body.js → gui-http-body.js} +0 -0
- /package/dist/src/merge/{backlog-conflicts.js → merge-backlog-conflicts.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fail, say, sayJson, sayJsonLine } from "../cli/cli-output.js";
|
|
2
|
-
import { durationLabel, failRivalShapes, failUntilShorterThanSince, flagValue, parseCountFlag, parseGrepFlag, parseRoleListScope, parseSinceFlag, rejectFlagLookingValue } from "../cli/cli-args.js";
|
|
2
|
+
import { betweenWindow, durationLabel, failRivalShapes, failUntilShorterThanSince, flagValue, parseCountFlag, parseGrepFlag, parseRoleListScope, parseSinceFlag, rejectFlagLookingValue } from "../cli/cli-args.js";
|
|
3
3
|
import { HISTORY_DEFAULT_RUNS, HISTORY_MAX_RUNS, HISTORY_RESULT_FLAG_NAMES, HISTORY_SUMMARY_GROUPS, historyClass, parseHistoryResultClass, readRunRows, readRunRowsSince, runRows, summarizeRunRows, summarizeRunRowsByModel, runRowsMatchingGrep, runRowsOnModels } from "./history-data.js";
|
|
4
4
|
import { renderModelSummary, renderRow, renderSummary, widenWidths, widestWidths } from "./history-render.js";
|
|
5
5
|
import { LOGS_SINCE_MAX_MS, SPARSE_WINDOW_NOTE } from "../events/event-window.js";
|
|
@@ -69,16 +69,12 @@ export function parseHistoryResultList(raw) {
|
|
|
69
69
|
}
|
|
70
70
|
return parsed;
|
|
71
71
|
}
|
|
72
|
-
/** `
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
|
|
78
|
-
* filter's buckets) and `--model` keeps runs that started on the listed models; all compose
|
|
79
|
-
* with --role, -n, and --since. Read-only: stdout only, no state file created — a missing or empty
|
|
80
|
-
* event log prints `no runs yet` and exits 0. */
|
|
81
|
-
export async function cmdHistory(root, args, seams = {}) {
|
|
72
|
+
/** Scan `history`'s flags: the `--grep` pattern, the raw `-n` value, the `-f`/`--since`
|
|
73
|
+
* rival shape checks, and the `--since`/`--until` window. These failures all fire here in
|
|
74
|
+
* the same order as before, so a bad value names the same command and flag; only the `-n`
|
|
75
|
+
* count is left raw (see collectHistoryRows), so its own parse and failure live there, in
|
|
76
|
+
* the deliberate spot after the `--since` rival check and before `--result`. */
|
|
77
|
+
function parseHistoryQuery(root, args) {
|
|
82
78
|
// `--grep <text>` filters the row set case-insensitively against the WYSIWYG row line (plus a
|
|
83
79
|
// `run_end` prefix, the same haystack rule logs --grep applies to its rendered lines), so
|
|
84
80
|
// both observing views answer substring questions the same way. The flag scan itself — the
|
|
@@ -94,8 +90,6 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
94
90
|
// value) through parseSinceFlag, so the error wordings cannot drift. `--role` composes with
|
|
95
91
|
// --since here: history's --role is a row filter, not the rival transcript view logs guards
|
|
96
92
|
// against.
|
|
97
|
-
let rows;
|
|
98
|
-
let covered = true;
|
|
99
93
|
const follow = hasFollowFlag(rest);
|
|
100
94
|
if (follow) {
|
|
101
95
|
if (rest.includes("--since"))
|
|
@@ -107,47 +101,48 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
107
101
|
const sinceMs = parseSinceFlag(rest, "history --since", LOGS_SINCE_MAX_MS);
|
|
108
102
|
const untilMs = parseSinceFlag(rest, "history --until", LOGS_SINCE_MAX_MS, "--until");
|
|
109
103
|
failUntilShorterThanSince("history", untilMs, sinceMs);
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
return { rest, grepPattern, nRaw, followTail, sinceMs, untilMs };
|
|
105
|
+
}
|
|
106
|
+
/** Collect the row set the query names: the `-f` seed, the `--since` window, or the plain `-n`
|
|
107
|
+
* scan. The `-n` and `--since` rival checks live here so a bad count still fails after the
|
|
108
|
+
* `--since` check and before `--result` filtering. Returns the rows plus whether the scan
|
|
109
|
+
* covered the whole log (false when a bounded window hit the retained buffer's edge). */
|
|
110
|
+
function collectHistoryRows(root, q) {
|
|
111
|
+
let rows;
|
|
112
|
+
let covered = true;
|
|
113
|
+
if (q.followTail !== null) {
|
|
114
|
+
const limit = q.nRaw !== null ? parseCountFlag("-n", q.nRaw, HISTORY_MAX_RUNS) : HISTORY_DEFAULT_RUNS;
|
|
112
115
|
// The seed goes through readRunRows, which widens its window until it finds `limit` rows;
|
|
113
116
|
// the tail buffer only feeds the live follow.
|
|
114
|
-
rows = readRunRows(root, limit, parseRoleListScope(root, rest));
|
|
117
|
+
rows = readRunRows(root, limit, parseRoleListScope(root, q.rest));
|
|
115
118
|
}
|
|
116
|
-
else if (sinceMs !== null) {
|
|
117
|
-
if (nRaw !== null)
|
|
119
|
+
else if (q.sinceMs !== null) {
|
|
120
|
+
if (q.nRaw !== null)
|
|
118
121
|
failRivalShapes("history --since", "-n", "a count and a window are rival shapes");
|
|
119
|
-
const role = parseRoleListScope(root, rest);
|
|
120
|
-
const windowed = readRunRowsSince(root, sinceMs, role, untilMs);
|
|
122
|
+
const role = parseRoleListScope(root, q.rest);
|
|
123
|
+
const windowed = readRunRowsSince(root, q.sinceMs, role, q.untilMs);
|
|
121
124
|
rows = windowed.rows;
|
|
122
125
|
covered = windowed.covered;
|
|
123
126
|
}
|
|
124
127
|
else {
|
|
125
128
|
// parseCountFlag's max caps the scan window: a typo'd "999999" must not build a
|
|
126
129
|
// HISTORY_MAX_RUNS-sized slice scan from a huge limit.
|
|
127
|
-
const limit = nRaw !== null ? parseCountFlag("-n", nRaw, HISTORY_MAX_RUNS) : HISTORY_DEFAULT_RUNS;
|
|
130
|
+
const limit = q.nRaw !== null ? parseCountFlag("-n", q.nRaw, HISTORY_MAX_RUNS) : HISTORY_DEFAULT_RUNS;
|
|
128
131
|
// The config is read (through loadConfigCached, never throwing) only when --role is present:
|
|
129
132
|
// a read-only view must not refuse a transiently broken tumwater.json.
|
|
130
|
-
const role = parseRoleListScope(root, rest);
|
|
133
|
+
const role = parseRoleListScope(root, q.rest);
|
|
131
134
|
rows = readRunRows(root, limit, role);
|
|
132
135
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// `--result <class>[,<class>...]` narrows to the listed outcome buckets, reading the same
|
|
144
|
-
// canonical historyClass rule the dashboard's History filter applies (shared from
|
|
145
|
-
// history-data.ts, not copied). It composes with --role, -n, --since, and --grep, so no
|
|
146
|
-
// rival-shape rule: a missing or empty value fails with its own wording, and an unknown
|
|
147
|
-
// class names the accepted ones (the gotSuffix shape the other flag validators use, plus a
|
|
148
|
-
// did-you-mean hint for a near-miss of a real result — the same typoSuffix treatment
|
|
149
|
-
// `logs --type` gives its codes). Applied after --grep, over the same rows both the table
|
|
150
|
-
// and --json serialize.
|
|
136
|
+
return { rows, covered };
|
|
137
|
+
}
|
|
138
|
+
/** `--result <class>[,<class>...]` narrows the rows to the listed outcome buckets, reading the
|
|
139
|
+
* same canonical historyClass rule the dashboard's History filter applies (shared from
|
|
140
|
+
* history-data.ts, not copied). It composes with --role, -n, --since, and --grep, so no
|
|
141
|
+
* rival-shape rule: a missing or empty value fails with its own wording, and an unknown class
|
|
142
|
+
* names the accepted ones (the gotSuffix shape the other flag validators use, plus a did-you-mean
|
|
143
|
+
* hint for a near-miss of a real result — the same typoSuffix treatment `logs --type` gives its
|
|
144
|
+
* codes). Applied after --grep, over the same rows both the table and --json serialize. */
|
|
145
|
+
function applyHistoryResultFilter(rows, rest) {
|
|
151
146
|
const resultRaw = rejectFlagLookingValue("history --result", flagValue(rest, "--result"));
|
|
152
147
|
let resultClasses = null;
|
|
153
148
|
if (resultRaw !== null) {
|
|
@@ -155,11 +150,13 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
155
150
|
resultClasses = wanted;
|
|
156
151
|
rows = rows.filter((r) => wanted.includes(historyClass(r.result)));
|
|
157
152
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
return { rows, classes: resultClasses };
|
|
154
|
+
}
|
|
155
|
+
/** `--model <selector>[,...]` keeps the rows whose run_start named exactly one of the listed
|
|
156
|
+
* selectors (case-sensitive, the strings `--summary --by model` prints); a null-model row never
|
|
157
|
+
* matches. An unknown selector is not an error: models have no closed vocabulary and an old log
|
|
158
|
+
* holds models the config has since dropped, so it simply keeps no rows. */
|
|
159
|
+
function applyHistoryModelFilter(rows, rest) {
|
|
163
160
|
const modelRaw = rejectFlagLookingValue("history --model", flagValue(rest, "--model"));
|
|
164
161
|
let models = null;
|
|
165
162
|
if (modelRaw !== null) {
|
|
@@ -167,29 +164,32 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
167
164
|
models = pieces;
|
|
168
165
|
rows = runRowsOnModels(rows, pieces);
|
|
169
166
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
// the report --json precedent: the flag's output must be parseable in every exit-0 case).
|
|
167
|
+
return { rows, models };
|
|
168
|
+
}
|
|
169
|
+
/** Render the collected-and-filtered rows: the `--by`/`--summary` summary grouping, the `--json`
|
|
170
|
+
* document, the empty-state wording (blaming the filter that emptied the set, else the log or
|
|
171
|
+
* window), the aligned table, and the sparse-window note. A bad `--by` value fails here, after
|
|
172
|
+
* row collection and filtering and before `--json`. */
|
|
173
|
+
function sayHistory(rows, q, covered, filtered) {
|
|
178
174
|
// `--by role|model` picks how --summary groups its lines (role by default).
|
|
179
|
-
const byRaw = flagValue(rest, "--by");
|
|
175
|
+
const byRaw = flagValue(q.rest, "--by");
|
|
180
176
|
let byModel = false;
|
|
181
|
-
if (rest.includes("--by")) {
|
|
177
|
+
if (q.rest.includes("--by")) {
|
|
182
178
|
if (!byRaw)
|
|
183
179
|
return fail(HISTORY_BY_VALUE_ERROR);
|
|
184
180
|
if (!HISTORY_SUMMARY_GROUPS.includes(byRaw)) {
|
|
185
181
|
fail(`history --by must be one of ${HISTORY_SUMMARY_GROUPS.join(", ")}${gotSuffix(byRaw)}${typoSuffix(byRaw, [...HISTORY_SUMMARY_GROUPS])}`);
|
|
186
182
|
}
|
|
187
|
-
if (!rest.includes("--summary"))
|
|
183
|
+
if (!q.rest.includes("--summary"))
|
|
188
184
|
fail("history --by needs --summary (it picks how the summary groups runs)");
|
|
189
185
|
byModel = byRaw === "model";
|
|
190
186
|
}
|
|
191
|
-
const summary = rest.includes("--summary") && rows.length > 0;
|
|
192
|
-
|
|
187
|
+
const summary = q.rest.includes("--summary") && rows.length > 0;
|
|
188
|
+
// --json swaps the renderer for the collector's own payload, exactly as status --json and
|
|
189
|
+
// report --json: the same rows the table prints, each with ts/tokens/costUsd kept raw. A
|
|
190
|
+
// JSON document even when the log is empty ({"rows":[]} — never the prose `no runs yet`,
|
|
191
|
+
// the report --json precedent: the flag's output must be parseable in every exit-0 case).
|
|
192
|
+
if (q.rest.includes("--json")) {
|
|
193
193
|
sayJson(summary ? (byModel ? summarizeRunRowsByModel(rows) : summarizeRunRows(rows)) : { rows });
|
|
194
194
|
return;
|
|
195
195
|
}
|
|
@@ -205,17 +205,17 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
205
205
|
// empty log or window scanned no rows, so the result filter removed nothing and the
|
|
206
206
|
// empty-log/window prose is the true one — the dashboard's History view draws the same
|
|
207
207
|
// line. A grep that admitted nothing keeps its own wording regardless of --result.
|
|
208
|
-
say(models !== null && afterResult > 0
|
|
209
|
-
? `no runs on model "${models.join(",")}"`
|
|
210
|
-
:
|
|
211
|
-
? `no runs with result "${
|
|
212
|
-
: grepPattern !== null
|
|
213
|
-
? `no runs matching "${grepPattern}"`
|
|
214
|
-
: sinceMs === null
|
|
208
|
+
say(filtered.models !== null && filtered.afterResult > 0
|
|
209
|
+
? `no runs on model "${filtered.models.join(",")}"`
|
|
210
|
+
: filtered.classes !== null && filtered.afterGrep > 0
|
|
211
|
+
? `no runs with result "${filtered.classes.join(",")}"`
|
|
212
|
+
: q.grepPattern !== null
|
|
213
|
+
? `no runs matching "${q.grepPattern}"`
|
|
214
|
+
: q.sinceMs === null
|
|
215
215
|
? "no runs yet"
|
|
216
|
-
: untilMs === null
|
|
217
|
-
? `no runs in ${durationLabel(sinceMs)}`
|
|
218
|
-
: `no runs
|
|
216
|
+
: q.untilMs === null
|
|
217
|
+
? `no runs in ${durationLabel(q.sinceMs)}`
|
|
218
|
+
: `no runs ${betweenWindow(q.sinceMs, q.untilMs)}`);
|
|
219
219
|
return;
|
|
220
220
|
}
|
|
221
221
|
if (summary)
|
|
@@ -231,6 +231,41 @@ export async function cmdHistory(root, args, seams = {}) {
|
|
|
231
231
|
if (!covered)
|
|
232
232
|
say(SPARSE_WINDOW_NOTE);
|
|
233
233
|
}
|
|
234
|
+
/** `tumwater history [--role <id>[,<id>...]] [-n N] [-f] [--since <duration>]
|
|
235
|
+
* [--until <duration>] [--grep <text>] [--result <class>] [--model <selector>[,...]]`: print the
|
|
236
|
+
* last N completed runs, newest first — or,
|
|
237
|
+
* with `--since`, the runs of a bounded past window over the same record, the same shape
|
|
238
|
+
* `logs --since` and `report --since` speak. `--grep` keeps rows whose rendered line matches,
|
|
239
|
+
* `--result` narrows to the listed outcome classes (changes/none/problems, the dashboard History
|
|
240
|
+
* filter's buckets) and `--model` keeps runs that started on the listed models; all compose
|
|
241
|
+
* with --role, -n, and --since. Read-only: stdout only, no state file created — a missing or empty
|
|
242
|
+
* event log prints `no runs yet` and exits 0. */
|
|
243
|
+
export async function cmdHistory(root, args, seams = {}) {
|
|
244
|
+
const q = parseHistoryQuery(root, args);
|
|
245
|
+
let { rows, covered } = collectHistoryRows(root, q);
|
|
246
|
+
// The filter runs on the collected rows, before rendering and before --json serialization:
|
|
247
|
+
// the same rows the table would print, filtered the same way in both forms (the logs --grep
|
|
248
|
+
// rule: -n bounds the scanned window, not the printed rows).
|
|
249
|
+
if (q.grepPattern !== null)
|
|
250
|
+
rows = runRowsMatchingGrep(rows, q.grepPattern);
|
|
251
|
+
// The set --grep admitted, saved so the empty-state wording blames the filter that actually
|
|
252
|
+
// emptied it: if the result filter below removes rows grep matched, naming the pattern would
|
|
253
|
+
// be false (`no runs matching "widget"` when feature #7 does match). The GUI draws the same
|
|
254
|
+
// line between a search and its outcome filter.
|
|
255
|
+
const afterGrep = rows.length;
|
|
256
|
+
// --result and --model each narrow the set further, and the counts saved here let the
|
|
257
|
+
// empty-state wording blame whichever filter actually emptied it.
|
|
258
|
+
const result = applyHistoryResultFilter(rows, q.rest);
|
|
259
|
+
rows = result.rows;
|
|
260
|
+
const afterResult = rows.length;
|
|
261
|
+
const model = applyHistoryModelFilter(rows, q.rest);
|
|
262
|
+
rows = model.rows;
|
|
263
|
+
if (q.followTail !== null) {
|
|
264
|
+
await followHistory(root, q.rest, rows, q.followTail, (r) => rowKept(r, q.grepPattern, result.classes, model.models), seams, q.rest.includes("--json"));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
sayHistory(rows, q, covered, { afterGrep, afterResult, classes: result.classes, models: model.models });
|
|
268
|
+
}
|
|
234
269
|
/** The row filters `--grep`, `--result` and `--model` apply, as one predicate for followed rows. */
|
|
235
270
|
function rowKept(row, grep, classes, models) {
|
|
236
271
|
if (grep !== null && runRowsMatchingGrep([row], grep).length === 0)
|
|
@@ -8,7 +8,6 @@ import { tooLongMessage } from "../text/text.js";
|
|
|
8
8
|
import { defaultConfig, loadConfigSafe } from "../config/config.js";
|
|
9
9
|
import { roleImageInfo } from "../agent/image-input.js";
|
|
10
10
|
import { readPiListedModels } from "../pi/pi-listed-models.js";
|
|
11
|
-
import { readImageProbeCache } from "../doctor/image-probe.js";
|
|
12
11
|
import { roleLabel } from "../roles/role-labels.js";
|
|
13
12
|
/** The user-facing submission pipeline for the prompt queues (the store's mechanics —
|
|
14
13
|
* listing, peeking, dequeuing, cancelling, and their race policy — live in src/inbox/inbox.ts,
|
|
@@ -46,10 +45,7 @@ export function promptLengthProblem(text, role = DIRECTOR_ROLE) {
|
|
|
46
45
|
export function imagePromptGuidance(root, role) {
|
|
47
46
|
const { config } = loadConfigSafe(root);
|
|
48
47
|
const cfg = config ?? defaultConfig();
|
|
49
|
-
|
|
50
|
-
// fourth argument): a claimed pi model whose doctor probe failed reads text-only here too,
|
|
51
|
-
// so the gate never grants image capability that the surfaces report as absent.
|
|
52
|
-
const { imageInput, imageReroute } = roleImageInfo(cfg, role, undefined, readImageProbeCache(root), readPiListedModels(root));
|
|
48
|
+
const { imageInput, imageReroute } = roleImageInfo(cfg, role, undefined, readPiListedModels(root));
|
|
53
49
|
if (imageInput !== false)
|
|
54
50
|
return {};
|
|
55
51
|
if (imageReroute) {
|
|
@@ -62,8 +62,9 @@ export class PendingPrompt {
|
|
|
62
62
|
}
|
|
63
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
|
-
* (abort, timeout, failure without changes, review abort, context-ceiling cut-off,
|
|
66
|
-
*
|
|
65
|
+
* (abort, timeout, failure without changes, review abort, context-ceiling cut-off, a
|
|
66
|
+
* merge-side `main_red` pin). The queue is the role's own (the director's historical
|
|
67
|
+
* inbox for the director), so a
|
|
67
68
|
* re-queued per-role request never leaks across roles. A fulfilled no_change never reaches
|
|
68
69
|
* here: re-queueing it would loop the prompt forever. Image attachments ride along: the
|
|
69
70
|
* re-queue moves them to the new queue file's stem so a later cancel or fulfilling sweep
|