@gobing-ai/spur 0.4.22 → 0.4.23
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/.claude-plugin/marketplace.json +1 -1
- package/config/pipeline-budgets.json +1 -1
- package/config/rules/boundary/config-loading-ownership.yaml +1 -1
- package/config/rules/strict/runtime-boundaries.yaml +3 -3
- package/config/rules/surface/check-cli-surface.yaml +1 -1
- package/config/workflow-candidates.json +1 -1
- package/config/workflows/history-anatomy.yaml +11 -11
- package/package.json +1 -1
- package/plugins/sp/commands/dev-runall.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/dogfood-testing/SKILL.md +7 -7
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +1 -1
- package/plugins/sp/skills/history-anatomy/references/modes.md +1 -1
- package/plugins/sp/skills/spur-cli/references/agent.md +6 -5
- package/plugins/sp/skills/spur-cli/references/builder.md +1 -8
- package/plugins/sp/skills/spur-cli/references/history.md +8 -1
- package/plugins/sp/skills/spur-cli/references/tasks.md +2 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +6 -2
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +3 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +3 -3
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +2 -2
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
- package/spur.js +96 -104
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"modelQueries": 3,
|
|
33
33
|
"wallClockMs": null,
|
|
34
34
|
"tokenCostUsd": null,
|
|
35
|
-
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0. 0920 recount 2026-09-23: 4 -> 3 — the resolve-scope model hop was removed; scope/window validation is deterministic in the `spur history anatomy
|
|
35
|
+
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0. 0920 recount 2026-09-23: 4 -> 3 — the resolve-scope model hop was removed; scope/window validation is deterministic in the `spur history anatomy-paths` op (history-anatomy-cache before script-absorption PR-6).",
|
|
36
36
|
"decision": null
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -67,7 +67,7 @@ rules:
|
|
|
67
67
|
exclude:
|
|
68
68
|
- "packages/config/src/**"
|
|
69
69
|
- "apps/cli/src/index.ts"
|
|
70
|
-
- "apps/cli/src/workflow-transport.ts" # boot-free composition root of `spur workflow commit-guard
|
|
70
|
+
- "apps/cli/src/workflow-transport.ts" # boot-free composition root of `spur workflow commit-guard-*|persist-*` (PR-4)
|
|
71
71
|
- "apps/server/src/serve.ts"
|
|
72
72
|
- "apps/server/src/context.ts"
|
|
73
73
|
- "**/tests/**"
|
|
@@ -37,7 +37,7 @@ rules:
|
|
|
37
37
|
- "apps/desktop/src/server-process.ts"
|
|
38
38
|
|
|
39
39
|
# Low-level system primitives:
|
|
40
|
-
# `spur builder pr
|
|
40
|
+
# `spur builder pr-*` spine (script-absorption PR-7, moved from plugins/sp/scripts/pr-reviewing.ts):
|
|
41
41
|
# every git/gh call goes through ONE synchronous, test-injectable CommandRunner seam
|
|
42
42
|
# (`setCommandRunner`); the spine is synchronous end to end (wait polls with a sync sleep).
|
|
43
43
|
# The ts-runtime sync executors cannot stand in: NodeSyncProcessExecutor maps a spawn
|
|
@@ -101,7 +101,7 @@ rules:
|
|
|
101
101
|
- "packages/app/src/services/history-anatomy.ts" # deterministic history-anatomy cache core (task 1005 R2): fsync'd tmp+rename atomic publish, readdir digest scans and sync report reads must stay byte-stable; bundled standalone for the bare-node plugin twin (mirrors agent-usage-producer.ts / history-service.ts exemptions)
|
|
102
102
|
- "packages/app/src/observability/workflow-run-log-sink.ts" # sync FD append for mid-run tail-able all-in-one run log (task 0426 / feature D2); append() is sync from the observability bus
|
|
103
103
|
- "packages/app/src/observability/agent-run-log.ts" # same primitive as the sink above for the per-run agent stream (task 1076 R1, ADR-132); append() is sync from the agent service's own onOutput hook, and the byte cap needs the FD position it tracks
|
|
104
|
-
# Workflow transports (script-absorption PR-4, `spur workflow commit-guard
|
|
104
|
+
# Workflow transports (script-absorption PR-4, `spur workflow commit-guard-*`): moved
|
|
105
105
|
# verbatim from the plugin scripts; synchronous probes and
|
|
106
106
|
# atomic tmp+rename snapshot writes inside one short-lived CLI process.
|
|
107
107
|
- "packages/app/src/workflow/commit-guard.ts" # .spur/run/<run>-tree-start.json atomic snapshot + target conflict-marker reads
|
|
@@ -121,7 +121,7 @@ rules:
|
|
|
121
121
|
- "packages/app/src/services/residual-scan-run.ts"
|
|
122
122
|
- "packages/app/src/workflow/task-diffstat.ts"
|
|
123
123
|
- "packages/app/src/workflow/feature-verification-run.ts" # the pass opens the run's single merged log fd (`openSync(path,'a')`) and mkdirs the run dir beside the receipt writer, exactly as the plugin entry did before the move; the fd cannot be expressed through the FileSystem seam (task 1176 R2; same class as the quality-gate exemption above)
|
|
124
|
-
- "packages/app/src/services/pr-review/index.ts" # `spur builder pr
|
|
124
|
+
- "packages/app/src/services/pr-review/index.ts" # `spur builder pr-*` (PR-7): sync --status-file verdict writes and the AGENTS.md review-rules probe inside the synchronous spine (same exemption as its process seam above)
|
|
125
125
|
- "packages/app/src/services/run-storage.ts" # durable-evidence migration core (task 1025 R4): atomic tmp+rename byte copies with digest reread and atomic manifest publish must stay byte-stable (mirrors agent-usage-producer.ts / project-registry.ts exemptions)
|
|
126
126
|
- "packages/app/src/services/durable-plane-ignore.ts" # .git/info/exclude append moved verbatim out of run-storage.ts to break an import cycle (same exemption)
|
|
127
127
|
|
|
@@ -62,7 +62,7 @@ rules:
|
|
|
62
62
|
- "apps/cli/src/commands/task/wrapup.ts"
|
|
63
63
|
- "apps/cli/src/commands/feature/handoff.ts"
|
|
64
64
|
- "apps/cli/src/commands/feature/verify.ts"
|
|
65
|
-
# commit-guard
|
|
65
|
+
# commit-guard-* declare no --json: its {staged, foreign} / {foreign} lines are rendered by
|
|
66
66
|
# @gobing-ai/spur-app/commit-guard (byte-identical to the retired script, PR-4 golden).
|
|
67
67
|
- "apps/cli/src/commands/workflow/commit-guard.ts"
|
|
68
68
|
# WT-4 worktree-landing transports (D65 1242, flat since the inline group was deleted): they
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"canonical": "wrapup-pipeline",
|
|
40
40
|
"deadline": "2026-11-24",
|
|
41
41
|
"createdAt": "2026-09-25",
|
|
42
|
-
"rationale": "0944 (feature D64): a deterministic probe (`spur task wrapup drift-probe`, packages/app/src/workflow/wrapup/drift-probe.ts since script-absorption PR-5) runs only when the caller leaves wrapup mode empty and projects mode=fast when no changed path matches a doc-owned surface (AGENTS.md doc map + docs/99_PROJECT_CONSTITUTION.md ownership table) and every task's Solution change map parsed — clean wraps then skip doc-sync via the existing fast edge (fast:drift-probe-clean), any doubt stays on the safety path. Projected basis: doc-sync costs exactly 1 agent.run per wrapup (wrapup-pipeline declares one model query; 0938 baseline docs/reports/2026-09-workflow-cost-baseline.json has 0 recorded wrapup runs — agentRunCountMedian null — so the 1 is structural, never a measured median). Measurement gap honestly named: skipping doc-sync also skips learnings capture (0607 R2 merge), so clean wraps lose per-task learnings rows; measured post-promotion by comparing .spur/memory/wrapup-routes.log fast:drift-probe-clean counts against captured <runId>-wrapup-learnings.md files. For 0946 (measurement-only confirmation): the 0938 snapshot carries per-state rows in states[] but history-anatomy has zero of them (0 recorded runs — only task-pipeline/record exists), and cache hit/miss disposition lives in the history-anatomy provenance stamp (0659/0660, `spur history anatomy
|
|
42
|
+
"rationale": "0944 (feature D64): a deterministic probe (`spur task wrapup drift-probe`, packages/app/src/workflow/wrapup/drift-probe.ts since script-absorption PR-5) runs only when the caller leaves wrapup mode empty and projects mode=fast when no changed path matches a doc-owned surface (AGENTS.md doc map + docs/99_PROJECT_CONSTITUTION.md ownership table) and every task's Solution change map parsed — clean wraps then skip doc-sync via the existing fast edge (fast:drift-probe-clean), any doubt stays on the safety path. Projected basis: doc-sync costs exactly 1 agent.run per wrapup (wrapup-pipeline declares one model query; 0938 baseline docs/reports/2026-09-workflow-cost-baseline.json has 0 recorded wrapup runs — agentRunCountMedian null — so the 1 is structural, never a measured median). Measurement gap honestly named: skipping doc-sync also skips learnings capture (0607 R2 merge), so clean wraps lose per-task learnings rows; measured post-promotion by comparing .spur/memory/wrapup-routes.log fast:drift-probe-clean counts against captured <runId>-wrapup-learnings.md files. For 0946 (measurement-only confirmation): the 0938 snapshot carries per-state rows in states[] but history-anatomy has zero of them (0 recorded runs — only task-pipeline/record exists), and cache hit/miss disposition lives in the history-anatomy provenance stamp (0659/0660, `spur history anatomy-*`, formerly history-anatomy-cache.ts), not in real-run-cost.ts; terminalReasonMix exists per workflow but history-anatomy's is empty. Measured-benefit status: projected from structure + 0938, NOT shadow-run-confirmed; `promotion evaluate` runs post-merge. If it does not beat the baseline, it is reverted (ADR-076).",
|
|
43
43
|
"measurement": {
|
|
44
44
|
"workflow": "wrapup-pipeline"
|
|
45
45
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Orchestration is configuration (ADR-022): a state machine over the existing dual-workflow
|
|
5
5
|
# engine. The YAML owns ONLY the cache branch, deterministic stage ordering, executor dispatch,
|
|
6
6
|
# bounded correction, and atomic publication sequencing. The deterministic cache/digest/
|
|
7
|
-
# structure/publish work is `spur history anatomy
|
|
7
|
+
# structure/publish work is `spur history anatomy-<op>` (0659's helper, absorbed by script-absorption PR-6); the judgment (mode validity,
|
|
8
8
|
# what counts as evidence, the report contract, enrich/validate rubrics) is 0658's skill. Per
|
|
9
9
|
# ADR-069 R1, cache-decide / digest / structure-check / publish must NOT be inline shell — every
|
|
10
10
|
# shell action here is glue length (a single helper invocation), because each of those programs
|
|
@@ -108,11 +108,11 @@ states:
|
|
|
108
108
|
onEnter:
|
|
109
109
|
- kind: shell
|
|
110
110
|
options:
|
|
111
|
-
# Path arithmetic lives in `spur history anatomy
|
|
111
|
+
# Path arithmetic lives in `spur history anatomy-paths` (ADR-069 R1; script-absorption
|
|
112
112
|
# PR-6 — HA_HELPER is the running spur, HA_SKILL the resolved skill dir). Avoid
|
|
113
113
|
# `${...}` here — that syntax collides with the engine's own template interpolation.
|
|
114
114
|
command: >-
|
|
115
|
-
$spurBin history anatomy
|
|
115
|
+
$spurBin history anatomy-paths --report-dir "$reportDir" --date "$date"
|
|
116
116
|
--output "$output" --mode "$mode" --since "$since" --until "$until"
|
|
117
117
|
--focus "$focus" --recompute "$recompute" --run-id "$__runId"
|
|
118
118
|
--out .spur/run/$__runId-paths.txt
|
|
@@ -146,7 +146,7 @@ states:
|
|
|
146
146
|
options:
|
|
147
147
|
command: >-
|
|
148
148
|
. .spur/run/$__runId-paths.txt;
|
|
149
|
-
$spurBin history anatomy
|
|
149
|
+
$spurBin history anatomy-probe --artifact .spur/run/$__runId-history-anatomy-current.json
|
|
150
150
|
--baseline .spur/run/$__runId-history-anatomy-baseline.json --target "$HA_TARGET"
|
|
151
151
|
--mode "$mode" --date "$HA_DATE" --recompute "$recompute" --executor "$agent"
|
|
152
152
|
--skill-dir "$HA_SKILL" --contract "$HA_SKILL/references/report-contract.md"
|
|
@@ -187,7 +187,7 @@ states:
|
|
|
187
187
|
- kind: shell
|
|
188
188
|
options:
|
|
189
189
|
command: >-
|
|
190
|
-
$spurBin history anatomy
|
|
190
|
+
$spurBin history anatomy-assert-clean --baseline .spur/run/$__runId-baseline-enrich.txt --expect .spur/run/$__runId-candidate.md
|
|
191
191
|
|
|
192
192
|
- id: structure-gate
|
|
193
193
|
description: >
|
|
@@ -198,7 +198,7 @@ states:
|
|
|
198
198
|
- kind: shell
|
|
199
199
|
options:
|
|
200
200
|
command: >-
|
|
201
|
-
$spurBin history anatomy
|
|
201
|
+
$spurBin history anatomy-check \
|
|
202
202
|
.spur/run/$__runId-candidate.md > .spur/run/$__runId-structure-gate.txt 2>&1 || true
|
|
203
203
|
|
|
204
204
|
- id: validate
|
|
@@ -264,7 +264,7 @@ states:
|
|
|
264
264
|
- kind: shell
|
|
265
265
|
options:
|
|
266
266
|
command: >-
|
|
267
|
-
$spurBin history anatomy
|
|
267
|
+
$spurBin history anatomy-assert-clean --baseline .spur/run/$__runId-baseline-validate.txt --expect .spur/run/$__runId-validation.txt
|
|
268
268
|
|
|
269
269
|
- id: correct
|
|
270
270
|
description: >
|
|
@@ -301,7 +301,7 @@ states:
|
|
|
301
301
|
- kind: shell
|
|
302
302
|
options:
|
|
303
303
|
command: >-
|
|
304
|
-
$spurBin history anatomy
|
|
304
|
+
$spurBin history anatomy-assert-clean --baseline .spur/run/$__runId-baseline-correct.txt --expect .spur/run/$__runId-candidate.md
|
|
305
305
|
|
|
306
306
|
- id: refresh-provenance
|
|
307
307
|
description: >
|
|
@@ -314,7 +314,7 @@ states:
|
|
|
314
314
|
options:
|
|
315
315
|
command: >-
|
|
316
316
|
. .spur/run/$__runId-paths.txt;
|
|
317
|
-
$spurBin history anatomy
|
|
317
|
+
$spurBin history anatomy-refresh --report "$HA_TARGET"
|
|
318
318
|
--out .spur/run/$__runId-publishable.md --disposition hit
|
|
319
319
|
|
|
320
320
|
- id: stamp
|
|
@@ -328,7 +328,7 @@ states:
|
|
|
328
328
|
options:
|
|
329
329
|
command: >-
|
|
330
330
|
. .spur/run/$__runId-paths.txt;
|
|
331
|
-
$spurBin history anatomy
|
|
331
|
+
$spurBin history anatomy-stamp --candidate .spur/run/$__runId-candidate.md
|
|
332
332
|
--provenance .spur/run/$__runId-provenance.json
|
|
333
333
|
--out .spur/run/$__runId-publishable.md
|
|
334
334
|
|
|
@@ -343,7 +343,7 @@ states:
|
|
|
343
343
|
command: >-
|
|
344
344
|
. .spur/run/$__runId-paths.txt;
|
|
345
345
|
mkdir -p "$(dirname "$HA_TARGET")";
|
|
346
|
-
$spurBin history anatomy
|
|
346
|
+
$spurBin history anatomy-publish .spur/run/$__runId-publishable.md "$HA_TARGET"
|
|
347
347
|
|
|
348
348
|
- id: published
|
|
349
349
|
description: Terminal — report published atomically after a passing validation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.23",
|
|
4
4
|
"description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"spur",
|
|
@@ -102,7 +102,7 @@ full distinction.
|
|
|
102
102
|
- **Bootstrap reads (1128):** before the first dispatch, read [SKILL.md § Bootstrap reads](../skills/spur-dev/SKILL.md#bootstrap-reads) and load only that mode's files — the section whose trigger has not fired is on demand.
|
|
103
103
|
- **Publish the visible batch plan first (1105):** publish `A Prepare batch` (A1–A4) and `Z Batch
|
|
104
104
|
report` before the first task, then one letter per task from `spur task batch-plan waves` after
|
|
105
|
-
freeze/order and digit children from `spur task batch-plan
|
|
105
|
+
freeze/order and digit children from `spur task batch-plan-children` at task start —
|
|
106
106
|
[execution-batch.md](../skills/spur-dev/references/execution-batch.md#27-visible-batch-plan-1105-r3)
|
|
107
107
|
§ 2.7 Visible batch plan.
|
|
108
108
|
- Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the engine loop (`spur workflow run --vars '{"executor":"host"}'` → work item → `spur workflow continue`); the resolved selector applies uniformly — eligible `agent.run` stages dispatch once to a native subagent with host fallback (0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -82,11 +82,11 @@ The command forwards these via `$ARGUMENTS`:
|
|
|
82
82
|
> <!-- pipeline-tokens:end -->
|
|
83
83
|
> matched as a **distinct hyphen-word**
|
|
84
84
|
> (machine-checked by
|
|
85
|
-
> `detectPipelineDriving` (`spur agent dogfood
|
|
85
|
+
> `detectPipelineDriving` (`spur agent dogfood-gate`);
|
|
86
86
|
> see [§Pipeline-driving word-boundary contract](#pipeline-driving-word-boundary-contract))
|
|
87
87
|
> → `⚠ pipeline-driving testee detected; pass --max-retry 0 (observe-only) or --max-retry N (fix mode, tree mutation acknowledged)`.
|
|
88
88
|
> - **Mutating `--fix` modes** — `--fix all` / `--fix blockers-first`, boundary-guarded via
|
|
89
|
-
> `hasMutatingFixMode` (`spur agent dogfood
|
|
89
|
+
> `hasMutatingFixMode` (`spur agent dogfood-gate`) (never matches
|
|
90
90
|
> `--fix none` / `--focus all` / `--prefix all`). No pipeline token required: a verify/review leg
|
|
91
91
|
> with `--fix all` mutates the tree on its own (0280 dogfood P2, task 0293). Honesty note:
|
|
92
92
|
> `--max-retry 0` here bounds **the driver only** — the testee still mutates the tree — so the
|
|
@@ -100,7 +100,7 @@ The command forwards these via `$ARGUMENTS`:
|
|
|
100
100
|
in-agent):
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
|
-
spur agent dogfood
|
|
103
|
+
spur agent dogfood-gate \
|
|
104
104
|
--testee "<raw testee string>" \
|
|
105
105
|
[--max-retry-present]
|
|
106
106
|
```
|
|
@@ -121,7 +121,7 @@ The command forwards these via `$ARGUMENTS`:
|
|
|
121
121
|
re-run the gate with the derived step labels:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
spur agent dogfood
|
|
124
|
+
spur agent dogfood-gate \
|
|
125
125
|
--testee "<raw testee string>" \
|
|
126
126
|
--max-retry-present \
|
|
127
127
|
--steps "step1 label||step2 label||..."
|
|
@@ -232,7 +232,7 @@ contract violation**.
|
|
|
232
232
|
**before** claiming `status: complete`:
|
|
233
233
|
|
|
234
234
|
```bash
|
|
235
|
-
spur agent dogfood
|
|
235
|
+
spur agent dogfood-validate-report --file <report-path>
|
|
236
236
|
```
|
|
237
237
|
|
|
238
238
|
Exit **0** → proceed. Exit **2** → set `status: aborted`, list every error code under §5
|
|
@@ -338,7 +338,7 @@ Do **not** use this skill for:
|
|
|
338
338
|
Pipeline-driving detection is **word-boundary**, not leading-space substring. The live gate is:
|
|
339
339
|
|
|
340
340
|
```bash
|
|
341
|
-
spur agent dogfood
|
|
341
|
+
spur agent dogfood-gate --testee "<testee>" [--max-retry-present] [--steps "…"] [--json]
|
|
342
342
|
```
|
|
343
343
|
|
|
344
344
|
| Token shape | Examples | Matches | Rejects |
|
|
@@ -349,7 +349,7 @@ spur agent dogfood gate --testee "<testee>" [--max-retry-present] [--steps "…"
|
|
|
349
349
|
`-` is a **word character** for boundaries: a token must be a distinct hyphen-word. Contract tests:
|
|
350
350
|
`packages/app/tests/services/dogfood/pipeline-detect.test.ts`. Helpers:
|
|
351
351
|
`detectPipelineDriving`, `isImplementHeavyStep`, `detectImplementHeavy`, `evaluateDogfoodGate` in
|
|
352
|
-
`spur agent dogfood
|
|
352
|
+
`spur agent dogfood-gate` (absorbed into the CLI; was `plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts`).
|
|
353
353
|
|
|
354
354
|
## Mutating `--fix` mode contract
|
|
355
355
|
|
|
@@ -336,7 +336,7 @@ Before the skill may stop (success, partial, fail, observe-only end, or abort),
|
|
|
336
336
|
and mirror the footer block at the **end of the report file**. A report whose body lacks the
|
|
337
337
|
footer cannot set `status: complete`.
|
|
338
338
|
8. **Self-validate (task 0278 R6):** run
|
|
339
|
-
`spur agent dogfood
|
|
339
|
+
`spur agent dogfood-validate-report --file <report-path>` before
|
|
340
340
|
claiming `status: complete`. Exit 2 → `status: aborted` + list error codes under
|
|
341
341
|
`#### Unresolved` (never force complete on a non-@1.2 shape).
|
|
342
342
|
9. **Refusal rule (@1.2):** when any check above fails, set `status: aborted` and list every
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The skill resolves exactly two modes. Everything else fails loud. This matrix is the enforcement
|
|
4
4
|
surface the workflow (0660) and the skill share; keep the vocabulary frozen. Execution note
|
|
5
|
-
(0920): argument validation runs deterministically in `spur history anatomy
|
|
5
|
+
(0920): argument validation runs deterministically in `spur history anatomy-paths`
|
|
6
6
|
(formerly the `history-anatomy-cache` helper) (logic core: `packages/app/src/services/history-anatomy.ts`, task 1005) before the
|
|
7
7
|
workflow starts; the model hop no longer performs it.
|
|
8
8
|
|
|
@@ -30,7 +30,8 @@ that before using `run` for fan-out dispatch.
|
|
|
30
30
|
| `leave` | Leave the fleet: release the guest lease, retire the occupant, return claimed messages to `queued` | `[id]` `--session-id <sid>` `--json` |
|
|
31
31
|
| `status` | Agent specs with live process status and member session (requires `spur self serve`) | `--server <url>` `--json` |
|
|
32
32
|
| `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
|
|
33
|
-
| `dogfood
|
|
33
|
+
| `dogfood-gate` | `sp:dogfood-testing` gate: pipeline-driving refusal (exit 2) | `--testee` `--max-retry-present` `--steps` `--json` |
|
|
34
|
+
| `dogfood-validate-report` | `sp:dogfood-testing` report-contract validation (exit 2) | `--file` `--json` |
|
|
34
35
|
| `usage` | Run-once provider usage capture (codexbar) → quota-owned availability refresh; scheduled externally | `--dry-run` `--source <name>` `--json` |
|
|
35
36
|
| `start <spec-id>` | Start a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
|
|
36
37
|
| `stop <spec-id>` | Stop a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
|
|
@@ -332,12 +333,12 @@ Posts to the supervisor API
|
|
|
332
333
|
(`POST /api/agents/:id/stop`) and prints `stopped <id>`. Same server requirement and flags as
|
|
333
334
|
`start`.
|
|
334
335
|
|
|
335
|
-
## `dogfood` - dogfood-testing gates
|
|
336
|
+
## `dogfood-gate` / `dogfood-validate-report` - dogfood-testing gates
|
|
336
337
|
|
|
337
338
|
```bash
|
|
338
|
-
spur agent dogfood
|
|
339
|
-
spur agent dogfood
|
|
340
|
-
spur agent dogfood
|
|
339
|
+
spur agent dogfood-gate --testee "/sp:dev-run 0123" --json # exit 2 = refuse (pipeline-driving, no --max-retry)
|
|
340
|
+
spur agent dogfood-gate --testee "…" --steps "plan||implement" # Phase 1 W8 re-check
|
|
341
|
+
spur agent dogfood-validate-report --file report.md --json # exit 2 = contract errors
|
|
341
342
|
```
|
|
342
343
|
|
|
343
344
|
Absorbed from `plugins/sp/scripts/dogfood-testing/` (script-absorption PR-7). `--json` here prints
|
|
@@ -20,8 +20,7 @@ This noun is **frozen at exactly eight verbs** (`bump-ver`, `drop-tags`, `publis
|
|
|
20
20
|
script-absorption entries; `show-branches` and the four flat PR verbs `pr-status`, `pr-check`,
|
|
21
21
|
`pr-open`, `pr-review` from the 2026-10-16 feature-L1 entries) by operator consent
|
|
22
22
|
(`docs/design/harness-surface-governance.md` §3) — do not invent additional `builder` subcommands.
|
|
23
|
-
The former `pr <op>` pass-through
|
|
24
|
-
(it prints one stderr deprecation line naming the replacement verb), so it is not listed here.
|
|
23
|
+
The former `pr <op>` pass-through was removed by task 1290 (two-level `spur <noun> <verb>` rule).
|
|
25
24
|
|
|
26
25
|
## Verb map
|
|
27
26
|
|
|
@@ -96,12 +95,6 @@ PR); `pr-check` → `{ ok, verdict, preflight, hygiene }`; `pr-open` → `{ ok,
|
|
|
96
95
|
and returns `PENDING` when a marked request is still in flight; `--force` requests a fresh review
|
|
97
96
|
of the current HEAD regardless. Never force-pushes.
|
|
98
97
|
|
|
99
|
-
```bash
|
|
100
|
-
# deprecated alias, one release: maps the old op names to the verbs above
|
|
101
|
-
spur builder pr preflight --json # -> spur builder pr-check
|
|
102
|
-
spur builder pr status --json # -> spur builder pr-status
|
|
103
|
-
```
|
|
104
|
-
|
|
105
98
|
## `show-branches` - read-only branch topology report
|
|
106
99
|
|
|
107
100
|
```bash
|
|
@@ -23,7 +23,14 @@ live in `packages/app/src/services/history-service.ts` (`FanOutResult`, `DailyRe
|
|
|
23
23
|
| `report [path]` | Purely render an existing artifact; default to `latest.json` | `--mode <name>` `--task <wbs>` `--top <n>` `--json` |
|
|
24
24
|
| `daily` | Run import-all → analyze → artifact → 90-day report pruning once | `--since <iso>` `--until <iso>` `--root <path>` `--source-timeout <ms>` `--mode <name>` `--json` |
|
|
25
25
|
| `reset` | Destructively wipe every `history_*` table for a clean re-import; refuses without `--yes` | `--yes` `--json` |
|
|
26
|
-
| `anatomy
|
|
26
|
+
| `anatomy-digest` | history-anatomy cache op `digest` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-digest --help`) |
|
|
27
|
+
| `anatomy-check` | history-anatomy cache op `check` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-check --help`) |
|
|
28
|
+
| `anatomy-paths` | history-anatomy cache op `paths` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-paths --help`) |
|
|
29
|
+
| `anatomy-assert-clean` | history-anatomy cache op `assert-clean` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-assert-clean --help`) |
|
|
30
|
+
| `anatomy-probe` | history-anatomy cache op `probe` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-probe --help`) |
|
|
31
|
+
| `anatomy-stamp` | history-anatomy cache op `stamp` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-stamp --help`) |
|
|
32
|
+
| `anatomy-refresh` | history-anatomy cache op `refresh` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-refresh --help`) |
|
|
33
|
+
| `anatomy-publish` | history-anatomy cache op `publish` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-publish --help`) |
|
|
27
34
|
| `timeline` | Per-prompt work/wait time and tokens from the host transcript (JSON), for `sp:session-review` | `--transcript <path>` `--group <spec>` |
|
|
28
35
|
| `summary` | Daily summary report for `sp:daily-summary` (tokens, git, history health, annotations) | `--date <d>` `--dry-run` `--output <path>` `--no-git` `--no-ccusage` |
|
|
29
36
|
|
|
@@ -49,7 +49,8 @@ re-reading or re-tokenizing the task.
|
|
|
49
49
|
| `migrate-anchors` | Qualify in-repo evidence anchors to repo-relative paths (0583 R1–R3); `--wbs` scopes to one task file (1109 R1); retargets scratch `done_reason` verdict pointers (1140) | `--wbs` `--dry-run` `--json` |
|
|
50
50
|
| `refresh-roster <wbs>` | Regenerate a parent task's sub-task roster block in `## Plan` | `--folder` `--json` |
|
|
51
51
|
| `batch-create` | Create many tasks from a validated JSON array | `--file <path>` `--skip-ready` `--agent <selector>` `--folder` `--json` |
|
|
52
|
-
| `batch-plan <mode>` | Batch plan projection: `waves` / `order`
|
|
52
|
+
| `batch-plan <mode>` | Batch plan projection: `waves` / `order` (JSON on stdout; the batch driver's visible plan) | `--tasks <file>` `--concurrency <n>` |
|
|
53
|
+
| `batch-plan-children` | One task row's phase digits from the visible plan (JSON on stdout) | `--letter <A-Z>` `--plan <file>` |
|
|
53
54
|
| `preflight [wbs]` | Read-only batch admission: TABLE A STOP check, quick readiness (`--operation`), one-shot recovery hop; status/deps read from the corpus unless given | `--status <s>` `--deps <list>` `--dep-status <map>` `--operation <op>` `--filtered-count <n>` `--required-sections <list>` `--present-sections <list>` `--force` `--recovery` `--classify-feature <json>` `--folder` `--json` |
|
|
54
55
|
| `wrapup <op>` | One deterministic `wrapup-pipeline` step (`resolve`, `route-reason`, `metrics`, `doc-sync-snapshot`, `doc-sync-scope`, `doc-supersession`, `drift-probe`) — workflow-internal | `--run-id <id>` `--tasks <json>` `--mode <m>` `--spur-bin <cmd>` |
|
|
55
56
|
| `record <wbs>` | Write `Testing` from a verify verdict (deterministic); bare-`## Review` fallback only; optional Solution + transition | `--verdict-file <path>` `--solution-from-diff` `--transition <status>` `--folder` `--json` |
|
|
@@ -121,7 +121,9 @@ The skill's logic divides by **whether the LLM adds value**:
|
|
|
121
121
|
| `cost` | `spur workflow cost` (CLI) | `[--workflow <name>]… [--by-state] [--include-bookkeeping] [--since <date>] [--budget <file>] [--measured-file <json>] [--json]` | Real terminal non-dry run measurements, or a budget result; unknown measurements stay null. Budget failures exit 1 |
|
|
122
122
|
| `persist-out` | `spur workflow persist-out` (CLI) | `--from <worktree> [--task-file <path>]…` | WT-4 landing: copy a worktree's run rows, two-file records and cited/owned evidence into the invoking tree before teardown; exit 1 fail closed (retain the worktree) |
|
|
123
123
|
| `persist-check` | `spur workflow persist-check` (CLI) | `--from <worktree> [--task-file <path>]… [--run-id <id>]… [--root <tree>] [--success-json <path>]` | WT-4 pre-removal assertion that the worktree owns no unpersisted durable evidence; exit 0 ok / 1 blocked or divergent / 2 usage |
|
|
124
|
-
| `commit-guard` | `spur workflow commit-guard
|
|
124
|
+
| `commit-guard-start` | `spur workflow commit-guard-start` (CLI) | `--run <id>` | Fingerprint HEAD and the dirty working files into `.spur/run/<run>-tree-start.json` |
|
|
125
|
+
| `commit-guard-stage` | `spur workflow commit-guard-stage` (CLI) | `--run <id> [--base <sha>] [-- <paths…>]` | Stages only paths this run wrote; exit 2 when a listed path is refused, 3 on unmerged/conflict-marked targets |
|
|
126
|
+
| `commit-guard-check` | `spur workflow commit-guard-check` (CLI) | `--run <id> [--base <sha>]` | Report working-tree changes this run did not write; stage nothing. The nested `commit-guard <op>` spelling was removed (task 1290) |
|
|
125
127
|
| `add` | agent procedure | `"<nl-description>" [--kind <state-machine\|transition-flow>] [--file <path>]` | **Mode chosen (confirmed)** → first reconciled against existing workflows (extend an existing flow rather than duplicate) → YAML authored in real schema shape → **validated AND dry-run** (reaches the expected terminal state) → [add](workflows/operations.md#add) |
|
|
126
128
|
| `refine` | agent procedure | `<workflow-file> [--intent "<goal>"] [--dry-run]` | Smallest change meeting the intent, re-validated and re-dry-run; `--dry-run` emits a diff only → [refine](workflows/operations.md#refine) |
|
|
127
129
|
|
|
@@ -277,7 +279,9 @@ spur workflow profile <workflow> [--last <n>] [--window <sec>] [--spur-bin <cmd
|
|
|
277
279
|
spur workflow cost [--workflow <name>]... [--by-state] [--include-bookkeeping] [--since <YYYY-MM-DD>] [--budget <file>] [--measured-file <json>] [--json]
|
|
278
280
|
spur workflow persist-out --from <worktree> [--task-file <path>]...
|
|
279
281
|
spur workflow persist-check --from <worktree> [--task-file <path>]... [--run-id <id>]... [--root <tree>]
|
|
280
|
-
spur workflow commit-guard <
|
|
282
|
+
spur workflow commit-guard-start --run <id>
|
|
283
|
+
spur workflow commit-guard-stage --run <id> [--base <sha>] [-- <paths>...]
|
|
284
|
+
spur workflow commit-guard-check --run <id> [--base <sha>]
|
|
281
285
|
```
|
|
282
286
|
|
|
283
287
|
### `cost` — real-run measurements and budgets
|
|
@@ -185,11 +185,11 @@ batch tip — the step that makes the close-out the report's own contradiction).
|
|
|
185
185
|
is never a point on the base ref.
|
|
186
186
|
Stage them through the guard — never a free-form `git add` — so a concurrent writer's file cannot
|
|
187
187
|
ride into the close-out commit (incident `36f274590`). `$RUN_ID` is the id Step 3 fixed before
|
|
188
|
-
`spur workflow commit-guard
|
|
188
|
+
`spur workflow commit-guard-start` (execution-batch.md § Step 3); an unset id makes the guard exit 1 — fail closed:
|
|
189
189
|
|
|
190
190
|
```bash
|
|
191
|
-
spur workflow commit-guard
|
|
192
|
-
spur workflow commit-guard
|
|
191
|
+
spur workflow commit-guard-check --run "$RUN_ID" # 1129 R3: a non-empty foreign list goes in the batch report
|
|
192
|
+
spur workflow commit-guard-stage --run "$RUN_ID" -- <files the wrap wrote> \
|
|
193
193
|
|| { echo "close-out halt: commit-guard refused a path (foreign, unmerged or conflict-marked); nothing committed" >&2; exit 1; }
|
|
194
194
|
git commit -m "chore(wrap): <command> <selector> close-out writes"
|
|
195
195
|
```
|
|
@@ -311,7 +311,7 @@ per-task letter is ever hand-assigned.
|
|
|
311
311
|
`spur workflow show task-pipeline.yaml --no-logo --format todo --json` payload:
|
|
312
312
|
|
|
313
313
|
```bash
|
|
314
|
-
spur task batch-plan
|
|
314
|
+
spur task batch-plan-children --letter <task-letter> --plan <plan.json>
|
|
315
315
|
```
|
|
316
316
|
|
|
317
317
|
4. **When a task ends:** mark the task's letter (and its published digits) with the task's terminal
|
|
@@ -327,7 +327,7 @@ plan = resolve(--tasks) → freeze → order(deps) # may abort (cycle) or
|
|
|
327
327
|
report = []
|
|
328
328
|
publish visible plan §2.7: A/Z rows now; one letter per task after this freeze (task batch-plan waves)
|
|
329
329
|
RUN_ID = WT-3 marker id under --worktree, else "batch-$(date -u +%Y%m%dT%H%M%SZ)" # fixed ONCE here; the close-out reuses it
|
|
330
|
-
spur workflow commit-guard
|
|
330
|
+
spur workflow commit-guard-start --run "$RUN_ID" # 1129 R1: fingerprint before the first task writes; the close-out commit stages through it
|
|
331
331
|
for wbs in plan: # default sequential mode
|
|
332
332
|
if any dependency of wbs failed earlier in THIS batch:
|
|
333
333
|
report += skipped(wbs, reason); continue # only relevant under --keep-going
|
|
@@ -338,7 +338,7 @@ for wbs in plan: # default sequential mode
|
|
|
338
338
|
preflight = spur task preflight <wbs> # Step 2.6 — TABLE A STOP
|
|
339
339
|
if preflight.action == skip:
|
|
340
340
|
report += preflight-skip(wbs, preflight); continue
|
|
341
|
-
visible plan (§2.7): letter in_progress +
|
|
341
|
+
visible plan (§2.7): letter in_progress + batch-plan-children digits at start; letter ← outcome at end
|
|
342
342
|
run: if interactive sequential omit/inline:
|
|
343
343
|
spur workflow run task-pipeline.yaml --vars <vars with executor=host> --json
|
|
344
344
|
perform the returned work item; spur workflow continue <run-id> --answer-text <receipt>
|
|
@@ -453,14 +453,14 @@ git checkout <base-ref> && git merge --no-ff -m "<prepared message>" <branch>
|
|
|
453
453
|
# the batch's run id, the same one WT-3b's worktree fingerprint used — the two trees keep two
|
|
454
454
|
# artifacts under the same id):
|
|
455
455
|
# RUN_ID="<marker-id>" # the WT-3 marker's id
|
|
456
|
-
# spur workflow commit-guard
|
|
456
|
+
# spur workflow commit-guard-start --run "$RUN_ID"
|
|
457
457
|
# git checkout <base-ref> && git merge --no-commit <branch>
|
|
458
458
|
# 2. resolve source conflicts by hand; generated files are then regenerated with the project's
|
|
459
459
|
# generator, never hand-merged
|
|
460
460
|
# (this repo: bun run --filter @gobing-ai/spur build:bundle)
|
|
461
461
|
# 3. stage every resolved path and regenerated bundle through the guard — an unmerged or
|
|
462
462
|
# unstaged path makes step 5 abort, and a conflict-marked path exits 3 (resolve, then retry):
|
|
463
|
-
# spur workflow commit-guard
|
|
463
|
+
# spur workflow commit-guard-stage --run "$RUN_ID" -- <resolved paths and regenerated bundles>
|
|
464
464
|
# Forbidden here as in every driver commit step: `git add -A` and `git add .`.
|
|
465
465
|
# 4. run qualityGateCmd once, after ALL conflicts are resolved
|
|
466
466
|
# 5. commit the merge with the prepared message file — CHECK THE PARENTS FIRST (step 5a)
|
|
@@ -352,7 +352,7 @@ fingerprints the invoking tree for the same reason (its own step 1b).
|
|
|
352
352
|
[ "$(git branch --show-current)" = "$BRANCH" ] \
|
|
353
353
|
|| { echo "branch mismatch: expected $BRANCH, got $(git branch --show-current)" >&2; exit 1; }
|
|
354
354
|
RUN_ID="<marker-id>" # the WT-3 marker's id — the same id WT-3b's stage call uses
|
|
355
|
-
spur workflow commit-guard
|
|
355
|
+
spur workflow commit-guard-start --run "$RUN_ID" # <worktree>/.spur/run/$RUN_ID-tree-start.json = { head, dirty[] }
|
|
356
356
|
)
|
|
357
357
|
```
|
|
358
358
|
|
|
@@ -368,8 +368,8 @@ same call, verifies the WT-3 identity, and never relies on a persistent `cd` or
|
|
|
368
368
|
cd -- "../<worktree-dir>" || { echo "tree missing: expected ../<worktree-dir>" >&2; exit 1; }
|
|
369
369
|
[ "$(git branch --show-current)" = "$BRANCH" ] \
|
|
370
370
|
|| { echo "branch mismatch: expected $BRANCH, got $(git branch --show-current)" >&2; exit 1; }
|
|
371
|
-
spur workflow commit-guard
|
|
372
|
-
spur workflow commit-guard
|
|
371
|
+
spur workflow commit-guard-check --run "$RUN_ID" # 1129 R3: concurrent foreign writers; a non-empty list goes in the batch report
|
|
372
|
+
spur workflow commit-guard-stage --run "$RUN_ID" -- <files-the-batch-wrote> \
|
|
373
373
|
|| { echo "WT-3b halt: commit-guard refused a path (foreign, unmerged or conflict-marked); nothing committed" >&2; exit 1; }
|
|
374
374
|
git commit -m "<type>(<scope>): <command> <selector> batch writes"
|
|
375
375
|
)
|
|
@@ -377,7 +377,7 @@ same call, verifies the WT-3 identity, and never relies on a persistent `cd` or
|
|
|
377
377
|
|
|
378
378
|
> **Forbidden in every driver commit step:** `git add -A` and `git add .`. They stage whatever a
|
|
379
379
|
> concurrent writer happened to leave in the tree — the two incidents this guard exists for are
|
|
380
|
-
> `a94f9f431` and `36f274590` — so a driver stages only through `spur workflow commit-guard
|
|
380
|
+
> `a94f9f431` and `36f274590` — so a driver stages only through `spur workflow commit-guard-stage`.
|
|
381
381
|
|
|
382
382
|
> **`stage` takes files, never directories.** A directory argument is refused as `(unchanged since
|
|
383
383
|
> base)` and stages *nothing*, so a task whose diff lives in a moved tree must expand the changed
|
package/spur.js
CHANGED
|
@@ -143843,7 +143843,7 @@ async function runBatchPlan(req, read) {
|
|
|
143843
143843
|
}
|
|
143844
143844
|
return usage();
|
|
143845
143845
|
}
|
|
143846
|
-
var BATCH_PLAN_USAGE = "usage: spur task batch-plan waves --tasks <tasks.json> | order --tasks <tasks.json> [--concurrency <n>]
|
|
143846
|
+
var BATCH_PLAN_USAGE = "usage: spur task batch-plan waves --tasks <tasks.json> | order --tasks <tasks.json> [--concurrency <n>]; spur task batch-plan-children --letter <A-Z> --plan <plan.json>", usage = () => ({ exitCode: 2, stdout: "", stderr: `${BATCH_PLAN_USAGE}
|
|
143847
143847
|
` }), invalid = (message) => ({
|
|
143848
143848
|
exitCode: 1,
|
|
143849
143849
|
stdout: "",
|
|
@@ -146370,7 +146370,7 @@ function runCacheCli(argv, deps = {}) {
|
|
|
146370
146370
|
switch (cmd) {
|
|
146371
146371
|
case "digest": {
|
|
146372
146372
|
if (a === undefined) {
|
|
146373
|
-
return { exitCode: 1, stdout: "", stderr: `usage: spur history anatomy
|
|
146373
|
+
return { exitCode: 1, stdout: "", stderr: `usage: spur history anatomy-digest <artifact.json>
|
|
146374
146374
|
` };
|
|
146375
146375
|
}
|
|
146376
146376
|
let artifact;
|
|
@@ -146386,7 +146386,7 @@ function runCacheCli(argv, deps = {}) {
|
|
|
146386
146386
|
}
|
|
146387
146387
|
case "check": {
|
|
146388
146388
|
if (a === undefined) {
|
|
146389
|
-
return { exitCode: 1, stdout: "", stderr: `usage: spur history anatomy
|
|
146389
|
+
return { exitCode: 1, stdout: "", stderr: `usage: spur history anatomy-check <report.md>
|
|
146390
146390
|
` };
|
|
146391
146391
|
}
|
|
146392
146392
|
const result = checkReportStructure(readFileSync26(a, "utf8"));
|
|
@@ -146400,7 +146400,7 @@ ${result.problems.map((p) => `- ${p}
|
|
|
146400
146400
|
return {
|
|
146401
146401
|
exitCode: 1,
|
|
146402
146402
|
stdout: "",
|
|
146403
|
-
stderr: `usage: spur history anatomy
|
|
146403
|
+
stderr: `usage: spur history anatomy-publish <candidate.md> <target.md>
|
|
146404
146404
|
`
|
|
146405
146405
|
};
|
|
146406
146406
|
}
|
|
@@ -146413,7 +146413,7 @@ ${result.problems.map((p) => `- ${p}
|
|
|
146413
146413
|
return {
|
|
146414
146414
|
exitCode: 1,
|
|
146415
146415
|
stdout: "",
|
|
146416
|
-
stderr: `usage: spur history anatomy
|
|
146416
|
+
stderr: `usage: spur history anatomy-assert-clean --baseline <porcelain.txt> [--expect <path>]...
|
|
146417
146417
|
`
|
|
146418
146418
|
};
|
|
146419
146419
|
}
|
|
@@ -146447,7 +146447,7 @@ ${result.problems.map((p) => `- ${p}
|
|
|
146447
146447
|
return {
|
|
146448
146448
|
exitCode: 1,
|
|
146449
146449
|
stdout: "",
|
|
146450
|
-
stderr: `usage: spur history anatomy
|
|
146450
|
+
stderr: `usage: spur history anatomy-paths --out <env> [--skill-dir <d>] [--helper <p>] [--report-dir <d>] [--date <d>] [--output <p>] [--mode <m>] [--since <s>] [--until <u>] [--focus <text>] [--recompute true|false] [--run-id <id>]
|
|
146451
146451
|
`
|
|
146452
146452
|
};
|
|
146453
146453
|
}
|
|
@@ -146535,7 +146535,7 @@ ${reasons}`, stderr: "" };
|
|
|
146535
146535
|
return {
|
|
146536
146536
|
exitCode: 1,
|
|
146537
146537
|
stdout: "",
|
|
146538
|
-
stderr: `usage: spur history anatomy
|
|
146538
|
+
stderr: `usage: spur history anatomy-stamp --candidate <c.md> --provenance <p.json> --out <o.md>
|
|
146539
146539
|
`
|
|
146540
146540
|
};
|
|
146541
146541
|
}
|
|
@@ -146555,7 +146555,7 @@ ${reasons}`, stderr: "" };
|
|
|
146555
146555
|
return {
|
|
146556
146556
|
exitCode: 1,
|
|
146557
146557
|
stdout: "",
|
|
146558
|
-
stderr: `usage: spur history anatomy
|
|
146558
|
+
stderr: `usage: spur history anatomy-refresh --report <published.md> --out <o.md> [--disposition hit]
|
|
146559
146559
|
`
|
|
146560
146560
|
};
|
|
146561
146561
|
}
|
|
@@ -146580,7 +146580,7 @@ var VALID_COMMANDS = "digest, check, paths, assert-clean, probe, stamp, refresh,
|
|
|
146580
146580
|
var init_history_anatomy_cli = __esm(() => {
|
|
146581
146581
|
init_dist5();
|
|
146582
146582
|
init_history_anatomy();
|
|
146583
|
-
PROBE_USAGE = "spur history anatomy
|
|
146583
|
+
PROBE_USAGE = "spur history anatomy-probe --artifact <a.json> --target <report.md> [--baseline <b.json>] [--mode daily|ad-hoc] " + "[--date <YYYY-MM-DD>] [--recompute true] [--out <prov.json>] [--skill-dir <d>] [--contract <f>] [--workflow <f>] [--helper <f>]";
|
|
146584
146584
|
});
|
|
146585
146585
|
|
|
146586
146586
|
// ../../packages/app/src/services/daily-summary.ts
|
|
@@ -147044,7 +147044,7 @@ async function buildDailySummary(options) {
|
|
|
147044
147044
|
}
|
|
147045
147045
|
return result;
|
|
147046
147046
|
}
|
|
147047
|
-
async function
|
|
147047
|
+
async function main(argv, sink) {
|
|
147048
147048
|
const previous = io2;
|
|
147049
147049
|
io2 = sink;
|
|
147050
147050
|
try {
|
|
@@ -155765,7 +155765,7 @@ function parseDogfoodGateArgs(argv) {
|
|
|
155765
155765
|
return { testee, maxRetryPresent, steps, json, help };
|
|
155766
155766
|
}
|
|
155767
155767
|
var DOGFOOD_GATE_USAGE = `Usage:
|
|
155768
|
-
spur agent dogfood
|
|
155768
|
+
spur agent dogfood-gate --testee "<testee string>" [--max-retry-present] [--steps "s1||s2"] [--json]
|
|
155769
155769
|
|
|
155770
155770
|
Exit codes:
|
|
155771
155771
|
0 proceed (stdout may carry implement-heavy advisory)
|
|
@@ -155999,7 +155999,7 @@ function parseDogfoodValidateArgs(argv) {
|
|
|
155999
155999
|
return { file, json, help };
|
|
156000
156000
|
}
|
|
156001
156001
|
var DOGFOOD_VALIDATE_USAGE = `Usage:
|
|
156002
|
-
spur agent dogfood
|
|
156002
|
+
spur agent dogfood-validate-report --file <report.md> [--json]
|
|
156003
156003
|
|
|
156004
156004
|
Exit codes:
|
|
156005
156005
|
0 report validates clean (complete-report shape)
|
|
@@ -156058,8 +156058,7 @@ function writeResult(context, result) {
|
|
|
156058
156058
|
context.setExitCode(result.exitCode);
|
|
156059
156059
|
}
|
|
156060
156060
|
function registerAgentDogfoodCommand(agent, context) {
|
|
156061
|
-
|
|
156062
|
-
dogfood.command("gate").summary("Refuse a pipeline-driving testee without --max-retry (dogfood Phase 1.0 / W8)").description(DOGFOOD_GATE_USAGE).option("--testee <string>", "the testee invocation under evaluation").option("--max-retry-present", "operator already supplied an explicit --max-retry").option("--steps <labels>", "derived step labels joined by || (Phase 1 W8 re-check)").option(...SHARED_OPTIONS.json).argument("[testee]", "positional alias for --testee").action((positional, options) => {
|
|
156061
|
+
agent.command("dogfood-gate").summary("Refuse a pipeline-driving testee without --max-retry (dogfood Phase 1.0 / W8)").description(DOGFOOD_GATE_USAGE).option("--testee <string>", "the testee invocation under evaluation").option("--max-retry-present", "operator already supplied an explicit --max-retry").option("--steps <labels>", "derived step labels joined by || (Phase 1 W8 re-check)").option(...SHARED_OPTIONS.json).argument("[testee]", "positional alias for --testee").action((positional, options) => {
|
|
156063
156062
|
const argv = [];
|
|
156064
156063
|
const testee = options.testee ?? positional;
|
|
156065
156064
|
if (testee)
|
|
@@ -156072,7 +156071,7 @@ function registerAgentDogfoodCommand(agent, context) {
|
|
|
156072
156071
|
argv.push("--json");
|
|
156073
156072
|
writeResult(context, runDogfoodGateCli(argv));
|
|
156074
156073
|
});
|
|
156075
|
-
|
|
156074
|
+
agent.command("dogfood-validate-report").summary("Validate a dogfood report against the @1.2 contract").description(DOGFOOD_VALIDATE_USAGE).option("--file <path>", "report markdown path").option(...SHARED_OPTIONS.json).argument("[file]", "positional alias for --file").action(async (positional, options) => {
|
|
156076
156075
|
const argv = [];
|
|
156077
156076
|
const file = options.file ?? positional;
|
|
156078
156077
|
if (file)
|
|
@@ -157401,6 +157400,9 @@ Recover with: ${err.recoveryCommand}` : err.message;
|
|
|
157401
157400
|
});
|
|
157402
157401
|
}
|
|
157403
157402
|
|
|
157403
|
+
// src/commands/task/batch-plan.ts
|
|
157404
|
+
init_pipeline_steps();
|
|
157405
|
+
|
|
157404
157406
|
// src/commands/task/step-output.ts
|
|
157405
157407
|
function writeStepText(output, stream, text) {
|
|
157406
157408
|
if (text === "")
|
|
@@ -157415,26 +157417,42 @@ function writeStepText(output, stream, text) {
|
|
|
157415
157417
|
|
|
157416
157418
|
// src/commands/task/batch-plan.ts
|
|
157417
157419
|
function registerTaskBatchPlanCommand(task, context) {
|
|
157418
|
-
|
|
157420
|
+
const run = async (req) => {
|
|
157421
|
+
await Promise.resolve().then(() => init_pipeline_steps());
|
|
157422
|
+
const outcome = await runBatchPlan(req, (path) => context.fs.readFile(context.fs.resolve(path)));
|
|
157423
|
+
writeStepText(context.output, "stdout", outcome.stdout);
|
|
157424
|
+
writeStepText(context.output, "stderr", outcome.stderr);
|
|
157425
|
+
context.setExitCode(outcome.exitCode);
|
|
157426
|
+
};
|
|
157427
|
+
const childrenReq = (options) => ({
|
|
157428
|
+
mode: "task-children",
|
|
157429
|
+
...options.letter !== undefined ? { letter: options.letter } : {},
|
|
157430
|
+
...options.plan !== undefined ? { plan: options.plan } : {}
|
|
157431
|
+
});
|
|
157432
|
+
task.command("batch-plan").summary("Project a task batch: visible plan waves or dependency order.").description([
|
|
157419
157433
|
"Batch plan projection (JSON on stdout):",
|
|
157420
157434
|
" waves --tasks <file> {wbs,name}[] \u2192 { waves } (A Prepare batch, B..Y tasks, Z report)",
|
|
157421
157435
|
" order --tasks <file> [--concurrency n] {wbs,dependencies?,files?}[] \u2192 { order, waves, cycle, overlaps, mode, reason }",
|
|
157422
|
-
" task-children --letter <A-Z> --plan <file> todo --json payload (or bare plan) \u2192 phase digits",
|
|
157423
157436
|
"Exit: 0 success, 1 unreadable/invalid input, 2 usage error."
|
|
157424
157437
|
].join(`
|
|
157425
|
-
`)).argument("<mode>", "waves | order
|
|
157426
|
-
|
|
157427
|
-
|
|
157438
|
+
`)).argument("<mode>", "waves | order").option("--tasks <file>", "tasks JSON file").option("--concurrency <n>", "parallel slots for order (default 2)").action(async (mode, options) => {
|
|
157439
|
+
if (mode !== "waves" && mode !== "order") {
|
|
157440
|
+
context.output.error(BATCH_PLAN_USAGE);
|
|
157441
|
+
context.setExitCode(2);
|
|
157442
|
+
return;
|
|
157443
|
+
}
|
|
157444
|
+
await run({
|
|
157428
157445
|
mode,
|
|
157429
157446
|
...options.tasks !== undefined ? { tasks: options.tasks } : {},
|
|
157430
|
-
...options.concurrency !== undefined ? { concurrency: options.concurrency } : {}
|
|
157431
|
-
|
|
157432
|
-
...options.plan !== undefined ? { plan: options.plan } : {}
|
|
157433
|
-
}, (path) => context.fs.readFile(context.fs.resolve(path)));
|
|
157434
|
-
writeStepText(context.output, "stdout", outcome.stdout);
|
|
157435
|
-
writeStepText(context.output, "stderr", outcome.stderr);
|
|
157436
|
-
context.setExitCode(outcome.exitCode);
|
|
157447
|
+
...options.concurrency !== undefined ? { concurrency: options.concurrency } : {}
|
|
157448
|
+
});
|
|
157437
157449
|
});
|
|
157450
|
+
task.command("batch-plan-children").summary("Project one task row\u2019s phase digits from the visible batch plan.").description([
|
|
157451
|
+
"Task-row phase digits (JSON on stdout) from a `spur workflow show --format todo --json`",
|
|
157452
|
+
"payload or a bare plan array.",
|
|
157453
|
+
"Exit: 0 success, 1 unreadable/invalid input, 2 usage error."
|
|
157454
|
+
].join(`
|
|
157455
|
+
`)).option("--letter <letter>", "task row letter A-Z").option("--plan <file>", "todo-format workflow plan payload or bare plan array").allowExcessArguments(false).action((options) => run(childrenReq(options)));
|
|
157438
157456
|
}
|
|
157439
157457
|
|
|
157440
157458
|
// src/commands/task/check.ts
|
|
@@ -161606,9 +161624,9 @@ function cmdStatus(rt, args) {
|
|
|
161606
161624
|
].join(`
|
|
161607
161625
|
`));
|
|
161608
161626
|
}
|
|
161609
|
-
var PR_REVIEW_HELP = `
|
|
161627
|
+
var PR_REVIEW_HELP = `pr-review spine \u2014 internal ops composed by the flat spur builder pr-status|pr-check|pr-open|pr-review verbs
|
|
161610
161628
|
|
|
161611
|
-
Usage:
|
|
161629
|
+
Usage: main([<op>, ...flags]) \u2014 not a CLI verb (the builder pr <op> alias was removed in 1290)
|
|
161612
161630
|
|
|
161613
161631
|
Subcommands:
|
|
161614
161632
|
preflight git/gh/repo checks; FAILs on detached HEAD or a dirty tree
|
|
@@ -161625,15 +161643,6 @@ Subcommands:
|
|
|
161625
161643
|
|
|
161626
161644
|
Global flags: --json (single JSON object) --status-file <path> (one-word verdict)
|
|
161627
161645
|
Exit codes: 0 ok \xB7 1 usage \xB7 2 hard failure \xB7 3 wait timeout`;
|
|
161628
|
-
function main(argv, sink, context = {}) {
|
|
161629
|
-
const previous = io;
|
|
161630
|
-
io = sink;
|
|
161631
|
-
try {
|
|
161632
|
-
return runSpine(argv, createRuntime(context));
|
|
161633
|
-
} finally {
|
|
161634
|
-
io = previous;
|
|
161635
|
-
}
|
|
161636
|
-
}
|
|
161637
161646
|
function runSpine(argv, rt) {
|
|
161638
161647
|
let args = null;
|
|
161639
161648
|
try {
|
|
@@ -161929,22 +161938,7 @@ function runPrVerb(verb, opts, sink, context = {}) {
|
|
|
161929
161938
|
}
|
|
161930
161939
|
|
|
161931
161940
|
// src/commands/builder/pr.ts
|
|
161932
|
-
|
|
161933
|
-
preflight: "pr-check",
|
|
161934
|
-
hygiene: "pr-check",
|
|
161935
|
-
push: "pr-open",
|
|
161936
|
-
ensure: "pr-open",
|
|
161937
|
-
"ensure-pr": "pr-open",
|
|
161938
|
-
request: "pr-review",
|
|
161939
|
-
wait: "pr-review",
|
|
161940
|
-
collect: "pr-status",
|
|
161941
|
-
status: "pr-status"
|
|
161942
|
-
};
|
|
161943
|
-
function prDeprecationLine(op) {
|
|
161944
|
-
const replacement = op === undefined ? undefined : PR_VERB_FOR_OP[op];
|
|
161945
|
-
return replacement !== undefined ? `spur builder pr ${op} is deprecated; use spur builder ${replacement}` : "spur builder pr is deprecated; use spur builder pr-status | pr-check | pr-open | pr-review";
|
|
161946
|
-
}
|
|
161947
|
-
function registerBuilderPrCommands(builder, context) {
|
|
161941
|
+
function registerBuilderPrCommand(builder, context) {
|
|
161948
161942
|
const io = () => ({
|
|
161949
161943
|
out: (line) => context.output.write(line),
|
|
161950
161944
|
err: (line) => context.output.error(line)
|
|
@@ -162015,15 +162009,6 @@ function registerBuilderPrCommands(builder, context) {
|
|
|
162015
162009
|
});
|
|
162016
162010
|
});
|
|
162017
162011
|
}
|
|
162018
|
-
function registerBuilderPrAliasCommand(builder, context) {
|
|
162019
|
-
builder.command("pr", { hidden: true }).summary("deprecated alias for the flat pr-<verb> commands").description(PR_REVIEW_HELP).allowUnknownOption(true).allowExcessArguments(true).argument("[argv...]", "subcommand and flags (see description)").action((argv) => {
|
|
162020
|
-
context.output.error(prDeprecationLine(argv[0]));
|
|
162021
|
-
context.setExitCode(main(argv, {
|
|
162022
|
-
out: (line) => context.output.write(line),
|
|
162023
|
-
err: (line) => context.output.error(line)
|
|
162024
|
-
}, { cwd: context.cwd, env: context.env }));
|
|
162025
|
-
});
|
|
162026
|
-
}
|
|
162027
162012
|
|
|
162028
162013
|
// ../../packages/app/src/services/branch-topology/render.ts
|
|
162029
162014
|
var INDENT = " ";
|
|
@@ -162695,8 +162680,7 @@ function registerBuilderCommand(program, context) {
|
|
|
162695
162680
|
}
|
|
162696
162681
|
});
|
|
162697
162682
|
registerBuilderShowBranchesCommand(noun, context);
|
|
162698
|
-
|
|
162699
|
-
registerBuilderPrAliasCommand(noun, context);
|
|
162683
|
+
registerBuilderPrCommand(noun, context);
|
|
162700
162684
|
}
|
|
162701
162685
|
|
|
162702
162686
|
// src/commands/decision.ts
|
|
@@ -163624,7 +163608,7 @@ import { createRequire as createRequire3 } from "module";
|
|
|
163624
163608
|
var CLI_CONFIG = {
|
|
163625
163609
|
binaryName: "spur",
|
|
163626
163610
|
binaryLabel: "spur",
|
|
163627
|
-
binaryVersion: "0.4.
|
|
163611
|
+
binaryVersion: "0.4.23",
|
|
163628
163612
|
configDir: ".spur",
|
|
163629
163613
|
configFile: ".spur/config.yaml",
|
|
163630
163614
|
databaseFile: ".spur/spur.db"
|
|
@@ -163635,20 +163619,18 @@ function spurEntryPath(argv = process.argv, execPath = process.execPath) {
|
|
|
163635
163619
|
const entry = argv[1];
|
|
163636
163620
|
return entry !== undefined && /\.(?:[cm]?[jt]s)$/.test(entry) ? entry : execPath;
|
|
163637
163621
|
}
|
|
163622
|
+
var OPS = {
|
|
163623
|
+
digest: "<artifact.json> \u2014 semantic artifact digest",
|
|
163624
|
+
check: "<report.md> \u2014 report-contract structure gate (PASS/FAIL)",
|
|
163625
|
+
paths: "--out <env> [--skill-dir d] ... \u2014 resolve the run paths into an env file",
|
|
163626
|
+
"assert-clean": "--baseline <porcelain> [--expect <path>]... \u2014 fail on undeclared writes",
|
|
163627
|
+
probe: "--artifact a --target t ... \u2014 cache disposition + provenance",
|
|
163628
|
+
stamp: "--candidate c --provenance p --out o \u2014 stamp provenance frontmatter",
|
|
163629
|
+
refresh: "--report r --out o \u2014 refresh a cache-hit report",
|
|
163630
|
+
publish: "<candidate.md> <target.md> \u2014 atomic publish"
|
|
163631
|
+
};
|
|
163638
163632
|
function registerHistoryAnatomyCommand(history, context) {
|
|
163639
|
-
|
|
163640
|
-
"Deterministic cache ops behind the history-anatomy workflow (ADR-079):",
|
|
163641
|
-
" digest <artifact.json> semantic artifact digest",
|
|
163642
|
-
" check <report.md> report-contract structure gate (PASS/FAIL)",
|
|
163643
|
-
" paths --out <env> [--skill-dir d] ... resolve the run paths into an env file",
|
|
163644
|
-
" assert-clean --baseline <porcelain> fail on undeclared writes (--expect=<path>)",
|
|
163645
|
-
" probe --artifact a --target t ... cache disposition + provenance",
|
|
163646
|
-
" stamp --candidate c --provenance p --out o stamp provenance frontmatter",
|
|
163647
|
-
" refresh --report r --out o refresh a cache-hit report",
|
|
163648
|
-
" publish <candidate.md> <target.md> atomic publish",
|
|
163649
|
-
"Exit: 0 ok, 1 usage or op failure."
|
|
163650
|
-
].join(`
|
|
163651
|
-
`)).allowUnknownOption(true).allowExcessArguments(true).argument("[argv...]", "op and its flags (see description)").action(async (argv) => {
|
|
163633
|
+
const run = async (argv) => {
|
|
163652
163634
|
for (let i = 0;i < argv.length; i++) {
|
|
163653
163635
|
if (argv[i] === "--run-id" && !acceptArtifactId(argv[i + 1] ?? "", "run id", context))
|
|
163654
163636
|
return;
|
|
@@ -163662,7 +163644,11 @@ function registerHistoryAnatomyCommand(history, context) {
|
|
|
163662
163644
|
writeStepText(context.output, "stdout", result.stdout);
|
|
163663
163645
|
writeStepText(context.output, "stderr", result.stderr);
|
|
163664
163646
|
context.setExitCode(result.exitCode);
|
|
163665
|
-
}
|
|
163647
|
+
};
|
|
163648
|
+
for (const [op, synopsis] of Object.entries(OPS)) {
|
|
163649
|
+
history.command(`anatomy-${op}`).summary(`history-anatomy cache op: ${synopsis}`).description(`history-anatomy cache op (ADR-079): ${op} ${synopsis}
|
|
163650
|
+
Exit: 0 ok, 1 usage or op failure.`).allowUnknownOption(true).allowExcessArguments(true).argument("[argv...]", "the op flags and operands (see description)").action((argv) => run([op, ...argv]));
|
|
163651
|
+
}
|
|
163666
163652
|
}
|
|
163667
163653
|
|
|
163668
163654
|
// src/commands/history/summary.ts
|
|
@@ -163685,7 +163671,7 @@ function registerHistorySummaryCommand(history, context) {
|
|
|
163685
163671
|
argv.push("--no-git");
|
|
163686
163672
|
if (options.ccusage === false)
|
|
163687
163673
|
argv.push("--no-ccusage");
|
|
163688
|
-
const code = await
|
|
163674
|
+
const code = await main(argv, {
|
|
163689
163675
|
out: (line) => context.output.write(line),
|
|
163690
163676
|
err: (line) => context.output.error(line)
|
|
163691
163677
|
});
|
|
@@ -171148,7 +171134,7 @@ init_dist5();
|
|
|
171148
171134
|
import { homedir as homedir17 } from "os";
|
|
171149
171135
|
import { basename as basename21, join as join94, relative as relative19, resolve as resolve37 } from "path";
|
|
171150
171136
|
// ../server/package.json
|
|
171151
|
-
var version4 = "0.4.
|
|
171137
|
+
var version4 = "0.4.23";
|
|
171152
171138
|
|
|
171153
171139
|
// ../server/src/modules/health/index.ts
|
|
171154
171140
|
var startedAt = Date.now();
|
|
@@ -176358,7 +176344,7 @@ init_src();
|
|
|
176358
176344
|
init_dist5();
|
|
176359
176345
|
import { mkdirSync as mkdirSync23, readFileSync as readFileSync28, renameSync as renameSync10, writeFileSync as writeFileSync20 } from "fs";
|
|
176360
176346
|
import { join as join100 } from "path";
|
|
176361
|
-
var COMMIT_GUARD_USAGE = "usage: spur workflow commit-guard
|
|
176347
|
+
var COMMIT_GUARD_USAGE = "usage: spur workflow commit-guard-start --run <id> | commit-guard-stage --run <id> [--base <sha>] -- <paths\u2026> | commit-guard-check --run <id> [--base <sha>]";
|
|
176362
176348
|
var isBookkeeping = (path) => path === ".spur" || path.startsWith(".spur/");
|
|
176363
176349
|
var at2 = (options, rel) => options.cwd ? join100(options.cwd, rel) : rel;
|
|
176364
176350
|
var artifactPath = (run) => join100(".spur", "run", `${run}-tree-start.json`);
|
|
@@ -176449,7 +176435,7 @@ var report = (exitCode, stdout = [], stderr = []) => ({
|
|
|
176449
176435
|
stderr
|
|
176450
176436
|
});
|
|
176451
176437
|
function missingStart(run) {
|
|
176452
|
-
return report(1, [], [`commit-guard: no ${artifactPath(run)} \u2014 run \`spur workflow commit-guard
|
|
176438
|
+
return report(1, [], [`commit-guard: no ${artifactPath(run)} \u2014 run \`spur workflow commit-guard-start --run ${run}\` first`]);
|
|
176453
176439
|
}
|
|
176454
176440
|
function commitGuardUsage() {
|
|
176455
176441
|
return report(1, [], [COMMIT_GUARD_USAGE]);
|
|
@@ -176580,21 +176566,21 @@ function registerWorkflowCommitGuardCommand(workflow, context) {
|
|
|
176580
176566
|
return;
|
|
176581
176567
|
emit(guarded(run));
|
|
176582
176568
|
};
|
|
176583
|
-
|
|
176584
|
-
|
|
176585
|
-
|
|
176586
|
-
|
|
176587
|
-
|
|
176588
|
-
|
|
176589
|
-
|
|
176590
|
-
|
|
176591
|
-
|
|
176592
|
-
|
|
176593
|
-
|
|
176594
|
-
|
|
176595
|
-
|
|
176596
|
-
|
|
176597
|
-
})
|
|
176569
|
+
workflow.command("commit-guard-start").description("Fingerprint HEAD and the dirty working files into .spur/run/<run>-tree-start.json").option("--run <id>", "Run id the snapshot belongs to").allowExcessArguments(false).action((options) => {
|
|
176570
|
+
withRun(options.run, (run) => commitGuardStart(run, { cwd: context.cwd }));
|
|
176571
|
+
});
|
|
176572
|
+
workflow.command("commit-guard-stage").description("Stage only the listed paths this run wrote; print {staged, foreign}").argument("[paths...]", "Candidate paths (after `--`)").option("--run <id>", "Run id whose tree-start snapshot partitions the paths").option("--base <sha>", "Diff base (default: the snapshot HEAD)").action((paths, options) => {
|
|
176573
|
+
withRun(options.run, (run) => commitGuardStage(run, paths, {
|
|
176574
|
+
cwd: context.cwd,
|
|
176575
|
+
...options.base === undefined ? {} : { base: options.base }
|
|
176576
|
+
}));
|
|
176577
|
+
});
|
|
176578
|
+
workflow.command("commit-guard-check").description("Report working-tree changes this run did not write; stage nothing").option("--run <id>", 'Run id whose tree-start snapshot defines "written by this run"').option("--base <sha>", "Diff base (default: the snapshot HEAD)").allowExcessArguments(false).action((options) => {
|
|
176579
|
+
withRun(options.run, (run) => commitGuardCheck(run, {
|
|
176580
|
+
cwd: context.cwd,
|
|
176581
|
+
...options.base === undefined ? {} : { base: options.base }
|
|
176582
|
+
}));
|
|
176583
|
+
});
|
|
176598
176584
|
}
|
|
176599
176585
|
|
|
176600
176586
|
// src/commands/workflow/continue.ts
|
|
@@ -177089,7 +177075,7 @@ async function runBudgetGate(opts) {
|
|
|
177089
177075
|
// src/commands/workflow/cost.ts
|
|
177090
177076
|
var collect3 = (value, previous) => [...previous, value];
|
|
177091
177077
|
function registerWorkflowCostCommand(workflow, context, deps = {}) {
|
|
177092
|
-
workflow.command("cost").description([
|
|
177078
|
+
workflow.command("cost").summary("Report per-workflow wall-clock and cost from real runs (or --budget gate)").description([
|
|
177093
177079
|
"Report per-workflow wall-clock and cost from REAL (terminal, non-dry) runs in .spur/spur.db.",
|
|
177094
177080
|
"The cohort defaults to every definition in .spur/workflows/ (bookkeeping workflows excluded).",
|
|
177095
177081
|
"--json emits the byte-stable baseline payload (workflow + state rows, key-sorted).",
|
|
@@ -178503,7 +178489,13 @@ function registerWorkflowCommand(program, context) {
|
|
|
178503
178489
|
}
|
|
178504
178490
|
|
|
178505
178491
|
// src/workflow-transport-argv.ts
|
|
178506
|
-
var WORKFLOW_TRANSPORT_VERBS = [
|
|
178492
|
+
var WORKFLOW_TRANSPORT_VERBS = [
|
|
178493
|
+
"commit-guard-start",
|
|
178494
|
+
"commit-guard-stage",
|
|
178495
|
+
"commit-guard-check",
|
|
178496
|
+
"persist-out",
|
|
178497
|
+
"persist-check"
|
|
178498
|
+
];
|
|
178507
178499
|
function isWorkflowTransportInvocation(argv) {
|
|
178508
178500
|
const tokens = argv.filter((token) => !["--no-logo", "--cli-verbose", "-v"].includes(token));
|
|
178509
178501
|
return tokens[0] === "workflow" && WORKFLOW_TRANSPORT_VERBS.includes(tokens[1] ?? "");
|
|
@@ -178516,7 +178508,7 @@ function registerWorkflowTransportCommands(workflow, context) {
|
|
|
178516
178508
|
}
|
|
178517
178509
|
|
|
178518
178510
|
// src/index.ts
|
|
178519
|
-
async function
|
|
178511
|
+
async function main2(argv = process.argv.slice(2), options = {}) {
|
|
178520
178512
|
const output = options.output ?? consoleOutput;
|
|
178521
178513
|
let exitCode = 0;
|
|
178522
178514
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -178713,7 +178705,7 @@ async function runCli() {
|
|
|
178713
178705
|
consoleOutput.write(bannerText());
|
|
178714
178706
|
}
|
|
178715
178707
|
try {
|
|
178716
|
-
return await
|
|
178708
|
+
return await main2();
|
|
178717
178709
|
} finally {
|
|
178718
178710
|
await disposeDecisionServices();
|
|
178719
178711
|
}
|
|
@@ -178724,7 +178716,7 @@ if (import.meta.main) {
|
|
|
178724
178716
|
export {
|
|
178725
178717
|
bannerText,
|
|
178726
178718
|
buildProgram,
|
|
178727
|
-
|
|
178719
|
+
main2 as main,
|
|
178728
178720
|
runCli,
|
|
178729
178721
|
shouldRenderBanner
|
|
178730
178722
|
};
|