@gobing-ai/spur 0.3.48 → 0.3.49

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.
Files changed (29) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +52 -4
  3. package/config/workflows/pr-review.yaml +338 -0
  4. package/package.json +8 -8
  5. package/plugins/sp/README.md +9 -6
  6. package/plugins/sp/commands/{dev-featurechange.md → dev-feature-change.md} +7 -10
  7. package/plugins/sp/commands/dev-find-issue.md +24 -19
  8. package/plugins/sp/commands/dev-find-next.md +3 -3
  9. package/plugins/sp/commands/dev-gtd.md +11 -12
  10. package/plugins/sp/commands/dev-history-load.md +63 -0
  11. package/plugins/sp/commands/dev-pr-review.md +39 -0
  12. package/plugins/sp/plugin.json +1 -1
  13. package/plugins/sp/references/roles.md +25 -12
  14. package/plugins/sp/scripts/history-load.ts +400 -0
  15. package/plugins/sp/scripts/pr-reviewing.ts +867 -0
  16. package/plugins/sp/scripts/validate-commands.ts +33 -2
  17. package/plugins/sp/skills/code-implementation/SKILL.md +9 -1
  18. package/plugins/sp/skills/code-verification/SKILL.md +27 -28
  19. package/plugins/sp/skills/issue-finding/SKILL.md +6 -5
  20. package/plugins/sp/skills/issue-finding/references/session-formats.md +4 -2
  21. package/plugins/sp/skills/next-feature/SKILL.md +6 -6
  22. package/plugins/sp/skills/next-feature/references/handoff-routing.md +5 -5
  23. package/plugins/sp/skills/next-feature/references/signal-derivation.md +7 -2
  24. package/plugins/sp/skills/pr-reviewing/SKILL.md +285 -0
  25. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +5 -5
  26. package/plugins/sp/skills/spur-cli/references/features.md +1 -1
  27. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +14 -4
  28. package/schemas/spur-config.schema.json +20 -0
  29. package/spur.js +682 -222
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "plugins": [
8
8
  {
9
- "version": "0.3.48",
9
+ "version": "0.3.49",
10
10
  "name": "sp",
11
11
  "source": "./plugins/sp",
12
12
  "description": "Spur - my harness toolkits"
@@ -49,6 +49,28 @@ agent:
49
49
  # naming both accepted sets.
50
50
  default: coder
51
51
 
52
+ # Role → tier map (SSOT: DEFAULT_AGENT_ROLES in packages/config, task 0572 /
53
+ # ADR-061; plugins/sp/references/roles.md is a parity-gated projection).
54
+ # Resolution: role → tier → cheapest USABLE executor whose tier >= the role's
55
+ # tier, climbing the ladder across gaps. Declare at least one usable executor
56
+ # at or above each rung or that role fails loudly at dispatch:
57
+ # scribe=cheap · coder=standard · reviewer=capable-1 · planner=capable-2
58
+ # Stage floors (stage-registry model_policy): changelog=cheap;
59
+ # implement/test/wrap/review/refine/brainstorm=standard;
60
+ # verify/dogfood=capable-1; plan=capable-2. A stage's fallback ladder
61
+ # (auth / resource-exhaustion / gate-fail) only advances when a higher rung
62
+ # has a usable executor — an empty rung turns a quota failure into a hang.
63
+ #
64
+ # Optional per-project override (0572): re-tier / re-stage a KNOWN role only —
65
+ # the vocabulary is closed; a config naming any other key fails at config load
66
+ # naming the accepted four. Per-field merge over the defaults (restate only
67
+ # what you override; a role you omit keeps its default wholesale):
68
+ # roles:
69
+ # reviewer:
70
+ # tier: capable-2 # e.g. pin review work one rung higher
71
+ # coder:
72
+ # stages: [implement] # e.g. stop folding test/wrap into coder
73
+
52
74
  # Canonical coding-agent ids (ts-ai-runner DISPLAY_ORDER, 0.4.8+):
53
75
  # claude, codex, gemini, pi, omp, opencode, antigravity-cli,
54
76
  # openclaw, hermes, grok
@@ -56,32 +78,58 @@ agent:
56
78
  # auth-status verb).
57
79
 
58
80
  # Named executor profiles (ADR-033 / 0343). Each pairs a canonical agent with
59
- # an optional opaque model override and an explicit capability tier.
81
+ # an explicit model override and an explicit capability tier.
82
+ # `model` is pinned on every entry: omitting it defers to the agent CLI's own
83
+ # default, which drifts with CLI upgrades and account state — pin what your
84
+ # CLI would resolve today (`grok models`, omp config.yml modelRoles.default,
85
+ # ~/.codex/config.toml, ~/.claude.json). The ids below are working examples,
86
+ # not vendor defaults — re-pin for your accounts.
87
+ #
88
+ # Pairing philosophy (operator guidance, 2026-08): a `native` pair — a vendor's
89
+ # model served by that vendor's own CLI (gpt-5.6-* via codex, claude-*-5 via
90
+ # claude, grok-4.6 via grok, gemini-3.x via agy) — consistently outperforms the
91
+ # same model routed through a third-party CLI, and belongs at the capable rungs.
92
+ # `portable` models (glm-5.x, deepseek-v4-*, …) are provider-agnostic and best
93
+ # carried by omp or pi at the cheap/standard rungs. The ladder below mixes both
94
+ # classes on purpose; measure pairings with the history plane before promoting
95
+ # a portable model into a capable rung.
60
96
  # Live tiers: cheap | standard | capable-1 | capable-2 | capable-3
61
97
  # (1=low quality within capable, 3=high). DECLARE tier — inference never
62
98
  # invents capable-2/3. Stage routing starts on the cheapest executor whose
63
99
  # tier >= min_tier; same exact tier ties break by array order.
64
100
  # Legacy bare `capable` is accepted at runtime as synonym for capable-1.
65
101
  executors:
102
+ # cheap rung is optional: with none declared, scribe-role work starts one
103
+ # rung up at the cheapest standard executor. Add one when transcript-heavy
104
+ # mechanical commands (changelog/gitmsg/handover) get noisy on cost.
105
+ # - name: minimax
106
+ # agent: omp
107
+ # model: minimax/MiniMax-M3
108
+ # tier: cheap
66
109
  - name: omp
67
110
  agent: omp
111
+ model: opencode/deepseek-v4-flash
68
112
  tier: standard
69
113
  # - name: omp-zai
70
114
  # agent: omp
71
115
  # model: zai/glm-5.2
72
116
  # tier: standard
117
+ - name: pi
118
+ agent: pi
119
+ model: "k3"
120
+ tier: capable-1
73
121
  - name: grok
74
122
  agent: grok
123
+ model: grok-4.6
75
124
  tier: capable-2
76
125
  - name: claude
77
126
  agent: claude
127
+ model: k3
78
128
  tier: capable-3
79
129
  - name: codex
80
130
  agent: codex
131
+ model: gpt-5.6
81
132
  tier: capable-3
82
- # - name: pi
83
- # agent: pi
84
- # tier: capable-1
85
133
 
86
134
  # `default-by-phase` is a REMOVED (0452). Prefer
87
135
  # executor `tier` + stage-registry model_policy. When present, a matching
@@ -0,0 +1,338 @@
1
+ # PR-review workflow: deterministic spine for /sp:dev-pr-review (skill sp:pr-reviewing).
2
+ # Authored for the @gobing-ai/ts-dual-workflow-engine state-machine schema
3
+ # (initialState / states[].id / onEnter / top-level transitions), same family as
4
+ # basic.yaml / task-pipeline.yaml. Seeded into projects by `spur init` (scaffold manifest).
5
+ #
6
+ # Shape: preflight → hygiene → precheck → push → ensure-pr → request → wait → collect → done
7
+ # (soft probes everywhere: red gates route to `failed`/`pending` via transitions,
8
+ # never a raw lifecycle abort — same reliability contract as basic.yaml)
9
+ #
10
+ # This YAML is the SSOT for the review spine's state order and guards. Every state shells
11
+ # out to the staged pr-reviewing.ts entrypoint (the tested deterministic core); no gh/git
12
+ # logic lives in this file. All model-bearing work — finding triage, `fix` mode, `rules`
13
+ # mode — stays in the sp:pr-reviewing skill and never enters this machine.
14
+ #
15
+ # Non-negotiable: the external review goes through the GitHub PR + an `@codex review`
16
+ # comment. Never substitute a local Codex review mechanism.
17
+ #
18
+ # Vars (override per run: --vars '{"mode":"submit","focus":"migration safety"}'):
19
+ # mode — full (default) | submit | rerun
20
+ # full: dedupe an up-to-date Codex review, else request + wait + collect
21
+ # submit: request and stop at `pending` (no wait)
22
+ # rerun: request with --force even when HEAD is already reviewed
23
+ # baseBranch — base for a newly created PR (default: existing PR base, else repo default)
24
+ # focus — extra review focus appended to the @codex request
25
+ # noWait — "true" returns pending right after the request instead of polling
26
+ # waitTimeoutSec — poll budget for Codex output (default 600)
27
+ # waitIntervalSec — poll interval (default 30; do not poll aggressively)
28
+ # preReviewCmd — project fast check run before requesting (empty = skipped).
29
+ # TRUSTED CONFIG ONLY — executed via `sh -c` (task 0436 SECUA residual).
30
+ # Never interpolate untrusted operator/LLM input into it.
31
+ # __runId — injected by WorkflowAppService.run(); scopes .spur/run artifacts.
32
+
33
+ "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
34
+ name: pr-review
35
+ kind: state-machine
36
+ description: GitHub Codex PR-review spine — preflight → hygiene → precheck → push → ensure-pr → request → wait → collect
37
+ iterationBound: 16
38
+ initialState: preflight
39
+ terminalStates:
40
+ - done
41
+ - pending
42
+ - failed
43
+ failureStates:
44
+ - failed
45
+ vars:
46
+ mode: 'full'
47
+ baseBranch: ''
48
+ focus: ''
49
+ noWait: 'false'
50
+ waitTimeoutSec: '600'
51
+ waitIntervalSec: '30'
52
+ preReviewCmd: ''
53
+ __runId: ''
54
+
55
+ states:
56
+ - id: preflight
57
+ description: >
58
+ Soft probe: git/gh/repo checks (detached HEAD, dirty tree, gh auth, GitHub remote).
59
+ Writes PASS|FAIL to .spur/run/${vars.__runId}-pr-preflight.status; always exit 0.
60
+ onEnter:
61
+ - kind: shell
62
+ options:
63
+ command: >-
64
+ mkdir -p .spur/run &&
65
+ STATUS_FILE=".spur/run/$__runId-pr-preflight.status" &&
66
+ set +e &&
67
+ bun "$(superskill script path sp pr-reviewing.ts)" preflight --json > ".spur/run/$__runId-pr-context.json";
68
+ rc=$?; set -e &&
69
+ if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi &&
70
+ exit 0
71
+
72
+ - id: hygiene
73
+ description: >
74
+ Submission sanity scan of base...HEAD: secrets/.env/conflict markers BLOCK the run;
75
+ debug residue only WARNs. Not a replacement for the independent Codex review.
76
+ onEnter:
77
+ - kind: shell
78
+ options:
79
+ command: >-
80
+ mkdir -p .spur/run &&
81
+ STATUS_FILE=".spur/run/$__runId-pr-hygiene.status" &&
82
+ set +e &&
83
+ bun "$(superskill script path sp pr-reviewing.ts)" hygiene --base "$baseBranch" --json
84
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-hygiene.json";
85
+ rc=$?; set -e &&
86
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
87
+ exit 0
88
+
89
+ - id: precheck
90
+ description: >
91
+ Optional project fast check (vars.preReviewCmd) before spending a review request.
92
+ Empty command records SKIP; a red check stops the run before request (fail loud).
93
+ onEnter:
94
+ - kind: shell
95
+ options:
96
+ command: >-
97
+ mkdir -p .spur/run &&
98
+ STATUS_FILE=".spur/run/$__runId-pr-precheck.status" &&
99
+ if [ -z "$preReviewCmd" ]; then
100
+ printf 'SKIP\n' > "$STATUS_FILE";
101
+ else
102
+ set +e; sh -c "$preReviewCmd"; rc=$?; set -e;
103
+ if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi;
104
+ fi &&
105
+ exit 0
106
+
107
+ - id: push
108
+ description: >
109
+ Publish the branch (normal push only, never force; sets upstream when missing).
110
+ A PR reviews pushed commits only.
111
+ onEnter:
112
+ - kind: shell
113
+ options:
114
+ command: >-
115
+ mkdir -p .spur/run &&
116
+ STATUS_FILE=".spur/run/$__runId-pr-push.status" &&
117
+ set +e &&
118
+ bun "$(superskill script path sp pr-reviewing.ts)" push --json --status-file "$STATUS_FILE"
119
+ > ".spur/run/$__runId-pr-push.json";
120
+ rc=$?; set -e &&
121
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
122
+ exit 0
123
+
124
+ - id: ensure-pr
125
+ description: Find or create the GitHub PR for the current branch — never a duplicate.
126
+ onEnter:
127
+ - kind: shell
128
+ options:
129
+ command: >-
130
+ mkdir -p .spur/run &&
131
+ STATUS_FILE=".spur/run/$__runId-pr-ensure.status" &&
132
+ set +e &&
133
+ bun "$(superskill script path sp pr-reviewing.ts)" ensure-pr --base "$baseBranch" --json
134
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr.json";
135
+ rc=$?; set -e &&
136
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
137
+ exit 0
138
+
139
+ - id: request
140
+ description: >
141
+ Post the `@codex review` request (per-HEAD dedupe unless mode=rerun forces).
142
+ Records the request under .spur/run/${vars.__runId}-pr-request.json.
143
+ onEnter:
144
+ - kind: shell
145
+ options:
146
+ command: >-
147
+ mkdir -p .spur/run &&
148
+ STATUS_FILE=".spur/run/$__runId-pr-request.status" &&
149
+ FORCE_FLAG="" &&
150
+ if [ "$mode" = "rerun" ]; then FORCE_FLAG="--force"; fi &&
151
+ set +e &&
152
+ bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $FORCE_FLAG --json
153
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-request.json";
154
+ rc=$?; set -e &&
155
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
156
+ exit 0
157
+
158
+ - id: wait
159
+ description: >
160
+ Bounded poll for Codex output on the current pushed HEAD. Timeout records TIMEOUT
161
+ and routes to `pending` — never a failure (collect later with /sp:dev-pr-review collect).
162
+ onEnter:
163
+ - kind: shell
164
+ options:
165
+ command: >-
166
+ mkdir -p .spur/run &&
167
+ STATUS_FILE=".spur/run/$__runId-pr-wait.status" &&
168
+ set +e &&
169
+ SINCE="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).requestedAt;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
170
+ REQUEST_HEAD="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).head;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
171
+ bun "$(superskill script path sp pr-reviewing.ts)" wait --since "$SINCE" --head "$REQUEST_HEAD" --timeout "$waitTimeoutSec" --interval "$waitIntervalSec"
172
+ --json --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-wait.json";
173
+ rc=$?; set -e &&
174
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
175
+ exit 0
176
+
177
+ - id: collect
178
+ description: Normalize the latest current-HEAD Codex result and record composite PR/CI status.
179
+ onEnter:
180
+ - kind: shell
181
+ options:
182
+ command: >-
183
+ mkdir -p .spur/run &&
184
+ STATUS_FILE=".spur/run/$__runId-pr-collect.status" &&
185
+ set +e &&
186
+ SINCE="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).requestedAt;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
187
+ REQUEST_HEAD="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).head;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
188
+ bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$SINCE" --head "$REQUEST_HEAD" --json
189
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-findings.json";
190
+ collect_rc=$?;
191
+ bun "$(superskill script path sp pr-reviewing.ts)" status --since "$SINCE" --head "$REQUEST_HEAD" --json > ".spur/run/$__runId-pr-status.json";
192
+ status_rc=$?; set -e &&
193
+ if [ "$collect_rc" -ne 0 ] || [ "$status_rc" -ne 0 ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
194
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
195
+ { cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null || true; } &&
196
+ exit 0
197
+
198
+ - id: done
199
+ description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
200
+ - id: pending
201
+ description: Terminal — review requested (or timed out) but not yet collected; run /sp:dev-pr-review collect later
202
+ - id: failed
203
+ description: Terminal — a gate went red; the stage .status/.json artifacts under .spur/run name the blocker
204
+
205
+ transitions:
206
+ - from: preflight
207
+ to: hygiene
208
+ description: Repo, gh auth, and clean tree verified
209
+ guard:
210
+ kind: shell
211
+ options:
212
+ command: 'test "$(cat .spur/run/$__runId-pr-preflight.status 2>/dev/null)" = PASS'
213
+ - from: preflight
214
+ to: failed
215
+ description: Preflight red (detached HEAD, dirty tree, gh auth, no GitHub remote) — stop before any publishing
216
+ guard:
217
+ kind: always
218
+
219
+ - from: hygiene
220
+ to: precheck
221
+ description: Clean or warn-only — warnings ride along to the report
222
+ guard:
223
+ kind: shell
224
+ options:
225
+ command: 'grep -qE "^(PASS|WARN)$" .spur/run/$__runId-pr-hygiene.status 2>/dev/null'
226
+ - from: hygiene
227
+ to: failed
228
+ description: BLOCK (secrets/.env/conflict markers) or probe failure — never submit a tainted diff
229
+ guard:
230
+ kind: always
231
+
232
+ - from: precheck
233
+ to: push
234
+ description: Project fast check passed or was skipped
235
+ guard:
236
+ kind: shell
237
+ options:
238
+ command: 'grep -qE "^(PASS|SKIP)$" .spur/run/$__runId-pr-precheck.status 2>/dev/null'
239
+ - from: precheck
240
+ to: failed
241
+ description: Project checks red — do not spend a review request on code that fails its own gate
242
+ guard:
243
+ kind: always
244
+
245
+ - from: push
246
+ to: ensure-pr
247
+ description: Branch published (or already up to date)
248
+ guard:
249
+ kind: shell
250
+ options:
251
+ command: 'grep -qE "^(PUSHED|UP_TO_DATE)$" .spur/run/$__runId-pr-push.status 2>/dev/null'
252
+ - from: push
253
+ to: failed
254
+ description: Push rejected (e.g. non-fast-forward) — report; never force-push as a workaround
255
+ guard:
256
+ kind: always
257
+
258
+ - from: ensure-pr
259
+ to: request
260
+ description: PR found or created
261
+ guard:
262
+ kind: shell
263
+ options:
264
+ command: 'grep -qE "^(FOUND|CREATED)$" .spur/run/$__runId-pr-ensure.status 2>/dev/null'
265
+ - from: ensure-pr
266
+ to: failed
267
+ description: No reviewable delta or PR creation failed — report the actual git/GitHub state
268
+ guard:
269
+ kind: always
270
+
271
+ # Declaration order matters: ALREADY_REVIEWED routes straight to collect (full mode dedupe);
272
+ # submit/noWait stop at pending; everything else waits.
273
+ - from: request
274
+ to: collect
275
+ description: Current HEAD already carries a Codex review — collect instead of duplicating
276
+ guard:
277
+ kind: shell
278
+ options:
279
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = ALREADY_REVIEWED'
280
+ - from: request
281
+ to: pending
282
+ description: Request already in flight, or mode=submit/--no-wait after posting — return pending
283
+ guard:
284
+ kind: shell
285
+ options:
286
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = ALREADY_REQUESTED || { test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = REQUESTED && { test "$mode" = "submit" || test "$noWait" = "true"; }; }'
287
+ - from: request
288
+ to: wait
289
+ description: Request posted — poll for the result
290
+ guard:
291
+ kind: shell
292
+ options:
293
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = REQUESTED'
294
+ - from: request
295
+ to: failed
296
+ description: Request failed (no PR, gh error) — report the preserved error
297
+ guard:
298
+ kind: always
299
+
300
+ - from: wait
301
+ to: collect
302
+ description: Codex findings or an explicit clean result on the current HEAD found
303
+ guard:
304
+ kind: shell
305
+ options:
306
+ command: 'grep -qE "^(FOUND|CLEAN)$" .spur/run/$__runId-pr-wait.status 2>/dev/null'
307
+ - from: wait
308
+ to: pending
309
+ description: Poll budget exhausted — pending, not failed
310
+ guard:
311
+ kind: shell
312
+ options:
313
+ command: 'test "$(cat .spur/run/$__runId-pr-wait.status 2>/dev/null)" = TIMEOUT'
314
+ - from: wait
315
+ to: failed
316
+ description: Poll probe itself failed
317
+ guard:
318
+ kind: always
319
+
320
+ - from: collect
321
+ to: done
322
+ description: Current-HEAD review collected (CLEAN/FINDINGS)
323
+ guard:
324
+ kind: shell
325
+ options:
326
+ command: 'grep -qE "^(FINDINGS|CLEAN)$" .spur/run/$__runId-pr-collect.status 2>/dev/null'
327
+ - from: collect
328
+ to: pending
329
+ description: No current-HEAD result yet — pending, never clean
330
+ guard:
331
+ kind: shell
332
+ options:
333
+ command: 'test "$(cat .spur/run/$__runId-pr-collect.status 2>/dev/null)" = PENDING'
334
+ - from: collect
335
+ to: failed
336
+ description: Collect probe failed
337
+ guard:
338
+ kind: always
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.3.48",
3
+ "version": "0.3.49",
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",
@@ -53,14 +53,14 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@commander-js/extra-typings": "^14.0.0",
56
- "@gobing-ai/ts-db": "^0.4.31",
57
- "@gobing-ai/ts-ai-runner": "^0.4.32",
58
- "@gobing-ai/ts-dual-workflow-engine": "^0.4.31",
59
- "@gobing-ai/ts-infra": "^0.4.31",
56
+ "@gobing-ai/ts-db": "^0.4.35",
57
+ "@gobing-ai/ts-ai-runner": "^0.4.35",
58
+ "@gobing-ai/ts-dual-workflow-engine": "^0.4.35",
59
+ "@gobing-ai/ts-infra": "^0.4.35",
60
60
  "@gobing-ai/ts-llm-jsonl-importer": "^0.4.31",
61
- "@gobing-ai/ts-rule-engine": "^0.4.31",
62
- "@gobing-ai/ts-runtime": "^0.4.31",
63
- "@gobing-ai/ts-utils": "^0.4.31",
61
+ "@gobing-ai/ts-rule-engine": "^0.4.35",
62
+ "@gobing-ai/ts-runtime": "^0.4.35",
63
+ "@gobing-ai/ts-utils": "^0.4.35",
64
64
  "@types/bun": "1.3.14",
65
65
  "@types/figlet": "^1.7.0",
66
66
  "@types/node-notifier": "8.0.5",
@@ -103,11 +103,12 @@ list this README is checked against.
103
103
  | `dev-next` | Status-aware router — inspect a task (or next frontier under a feature), dispatch the best existing `/sp:dev-*` command, chain on clean success |
104
104
  | `dev-run` | Run a task — full pipeline (precheck→implement→test→review→approve→verify→record→done) or single-step (implement) |
105
105
  | `dev-review` | Multi-dimensional review for a task or path — functional requirements traceability, SECUA framework, and architectural depth |
106
+ | `dev-pr-review` | GitHub Codex PR review — prepare/reuse a PR, request `@codex review`, collect findings, validate/fix/re-review (fix mode); workflow-backed spine |
106
107
  | `dev-verify` | Verify a task against its requirements and Acceptance Criteria — traceability check producing a PASS/PARTIAL/FAIL verdict with evidence |
107
108
  | `dev-unit` | Generate or extend tests until the unit target is met |
108
109
  | `dev-wrap` | Wrap up a single completed task — learnings, metrics, doc-sync, optional feature transition and branch cleanup |
109
110
  | `dev-refresh` | Refresh feature status by feature ID, task WBS, or batch sweep via spur feature sync |
110
- | `dev-featurechange` | Restructure feature tree from a mapping file — dry-run/apply via `spur feature move`, task edges, root `docs/*.md` only |
111
+ | `dev-feature-change` | Restructure feature tree from a mapping file — dry-run/apply via `spur feature move`, task edges, root `docs/*.md` only |
111
112
 
112
113
  #### Lifecycle — batch and parallel
113
114
 
@@ -126,6 +127,7 @@ list this README is checked against.
126
127
  | `dev-handover` | Generate a structured handover document when blocked — captures goal, progress, blocker, rejected approaches, and next steps |
127
128
  | `dev-debug` | Systematic debugging protocol — reproduce, isolate, diagnose root cause, apply minimal fix, and verify with regression tests |
128
129
  | `dev-daily` | Generate a daily summary report from agent usage data, git history, and notes |
130
+ | `dev-history-load` | On-demand cumulative history load + narrowed analyze — import (checkpoint-resume) then analyze, optionally by session/task/window, with optional forensics render |
129
131
  | `dev-dogfood` | Dogfood an agent skill/command/CLI — drive it end-to-end with bounded auto-fix, self-monitor, and emit a comprehensive report |
130
132
  | `dev-find-issue` | Review agent session logs, identify performance bottlenecks and behavioral anti-patterns, and generate a structured task file with proposed fixes |
131
133
  | `dev-find-conflict` | Authority-aware semantic audit across source, task, feature, and project authority files — detect conflicts, resolve claim-specific authority, and route confirmed repairs through owner surfaces |
@@ -135,7 +137,7 @@ list this README is checked against.
135
137
  | `dev-arch` | Survey a codebase (or module tree) for shallow modules and deepening opportunities — emit a ranked MARKDOWN candidate report that feeds the planning half; never auto-refactors |
136
138
  | `dev-reverse` | Reverse-engineer a codebase — analyze unfamiliar repos, generate HLD/architecture docs, audit quality/security, and produce onboarding documentation |
137
139
  | `dev-gitmsg` | Generate conventional commit message(s) from staged changes via per-file summarization, optionally commit |
138
- | `dev-gtd` | Get things done — quality gate (auto-fix) → act CI simulation → conventional commit → push → gh verify in one flow |
140
+ | `dev-gtd` | Get things done — quality gate (auto-fix) → conventional commit → push → gh verify in one flow; optional act CI simulation via `--act` |
139
141
  | `dev-changelog` | Generate changelog from git commits |
140
142
 
141
143
  #### Rule authoring
@@ -313,6 +315,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
313
315
  | `issue-finding` | 1.1 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; backs `/sp:dev-find-issue` |
314
316
  | `conflict-finding` | 1.0 | Authority-aware semantic audit — four-pillar (source/task/feature/authority) conflict discovery, claim-specific authority resolution, reproducible evidence, confirmed owner-routed remediation; backs `/sp:dev-find-conflict` |
315
317
  | `next-feature` | 1.0 | Prompt-first feature frontier prioritizer — sync-first precondition, B3 actionability gate (cited, never restated), tiered rubric over measured signals, D1–D4 defect proposals conforming to the restructure map schema; backs `/sp:dev-find-next` |
318
+ | `pr-reviewing` | 1.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; spine SSOT `pr-review.yaml` + `scripts/pr-reviewing.ts`; backs `/sp:dev-pr-review` |
316
319
  | `indexed-context` | 1.0 | Cross-agent project context — anatomy/learnings/pitfalls/buglog/memory in `.spur/context/`; hook-tracked token-ledger; graceful degradation on agents without hooks |
317
320
 
318
321
  Each skill directory contains:
@@ -335,11 +338,11 @@ Skills contain zero validation logic — the CLI is the gate.
335
338
 
336
339
  Thin slash-command wrappers that parse user arguments and delegate to the corresponding skill. Each
337
340
  command is a user-facing entry point that bridges natural language to skill invocation. There are
338
- **37 commands** (see the Command index above for the full list), organized by the surface they wrap:
341
+ **39 commands** (see the Command index above for the full list), organized by the surface they wrap:
339
342
 
340
343
  | Prefix | Count | Delegates to | Purpose |
341
344
  | ------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
342
- | `dev-*` | 31 | `sp:spur-dev`, `sp:code-implementation`, `sp:code-testing`, `sp:code-verification`, `sp:code-simplification`, `sp:next-router`, `sp:brainstorm`, `sp:dogfood-testing`, `sp:parallel-execution`, `sp:sys-debugging`, `sp:daily-summary`, `sp:issue-finding`, `sp:conflict-finding`, `sp:reverse-engineering`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
345
+ | `dev-*` | 33 | `sp:spur-dev`, `sp:code-implementation`, `sp:code-testing`, `sp:code-verification`, `sp:code-simplification`, `sp:next-router`, `sp:brainstorm`, `sp:dogfood-testing`, `sp:parallel-execution`, `sp:sys-debugging`, `sp:daily-summary`, `sp:issue-finding`, `sp:conflict-finding`, `sp:reverse-engineering`, `sp:pr-reviewing`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
343
346
  | `rule-*` | 3 | `sp:spur-cli` | The rule surface — `rule-add`, `rule-refine`, `rule-scan` |
344
347
  | `workflow-*` | 2 | `sp:spur-cli` | The workflow surface — `workflow-add`, `workflow-refine` |
345
348
  | `spur-init` | 1 | `sp:doc-evolve` | Project bootstrap (`spur init`) with doc-evolve integration |
@@ -349,7 +352,7 @@ Each command file contains:
349
352
  - YAML frontmatter (`description`, `argument-hint`, `allowed-tools`).
350
353
  - A delegation block: `Skill(skill="sp:<skill-name>", args="<operation> $ARGUMENTS")`.
351
354
 
352
- **Commands as SSOT (ADR-032).** The 37 `.md` files in `commands/` are the authoritative,
355
+ **Commands as SSOT (ADR-032).** The 39 `.md` files in `commands/` are the authoritative,
353
356
  hand-editable source for the operator command surface. Per-platform adapters are **install-time
354
357
  output** owned by `superskill` (`superskill install sp`) and never committed here. Plugin `sp` ships
355
358
  no per-platform artifacts — only the platform-independent thin wrappers.
@@ -357,7 +360,7 @@ no per-platform artifacts — only the platform-independent thin wrappers.
357
360
  **Thin-wrapper contract** is enforced by `scripts/validate-commands.ts`:
358
361
 
359
362
  ```bash
360
- bun plugins/sp/scripts/validate-commands.ts # validate all 37 commands
363
+ bun plugins/sp/scripts/validate-commands.ts # validate all 39 commands
361
364
  bun plugins/sp/scripts/validate-commands.ts --json # machine-readable output
362
365
  ```
363
366
 
@@ -1,14 +1,11 @@
1
1
  ---
2
- description: >-
2
+ description: "Restructure the feature tree from a mapping file — dry-run then apply via spur feature move / task feature_id edges / root docs/*.md reference rewrites (CLI-gated; no raw Write on docs/features or docs/tasks). Triggers: feature restructure, feature tree move, reparent features, apply mapping file"
3
3
  role: planner
4
- Restructure the feature tree from a mapping file — dry-run then apply via
5
- spur feature move / task feature_id edges / root docs/*.md reference rewrites
6
- (CLI-gated; no raw Write on docs/features or docs/tasks)
7
4
  argument-hint: "[--map <path>] [--dry-run] [--apply] [--limit <old-id>] [--wave <1|2|3|all>] [--yes]"
8
5
  allowed-tools: ["Bash", "Read", "AskUserQuestion", "Skill"]
9
6
  ---
10
7
 
11
- # Dev Featurechange
8
+ # Dev Feature Change
12
9
 
13
10
  CLI-gated feature-tree restructure orchestrator. Executes dispositions from a mapping file; does not invent hierarchy.
14
11
 
@@ -28,7 +25,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
28
25
  ## Usage
29
26
 
30
27
  ```
31
- /sp:dev-featurechange [--map <path>] [--dry-run] [--apply] [--limit <old-id>] [--wave <1|2|3|all>] [--yes]
28
+ /sp:dev-feature-change [--map <path>] [--dry-run] [--apply] [--limit <old-id>] [--wave <1|2|3|all>] [--yes]
32
29
  ```
33
30
 
34
31
  ## Implementation
@@ -43,7 +40,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
43
40
 
44
41
  - Read `--map`. Collect rows where disposition is not `keep` (typically `reparent-under:<parent>`).
45
42
  - Filter by `--limit` / `--wave` if set.
46
- - Wave defaults from map: **1** = K→J, L→J · **2** = N→H, O→H · **3** = P→D, Q→F, R→F8.
43
+ - Wave membership comes from the map itself (its wave column/section is the SSOT). Never hard-code letter sets here the tree moves under the command and literals go stale.
47
44
 
48
45
  **Free-digit preflight (mandatory before dry-run report)**
49
46
 
@@ -53,7 +50,7 @@ Group selected reparent rows by `new_parent`. For each parent:
53
50
  spur feature list --json
54
51
  ```
55
52
 
56
- Count current children (ids where `id` starts with parent and length = parent.length+1, digit 1–9).
53
+ Count current children (ids where `id` starts with parent and length = parent.length+1, digit 1–9).
57
54
  `free = 9 - childCount`. If `rowsUnderParent.length > free`, **abort the plan** with a clear error naming the parent, free slots, and competing old_ids. Do not apply a partial wave.
58
55
 
59
56
  **Dry-run plan (always) — sequential prediction**
@@ -102,10 +99,10 @@ spur feature refresh --json
102
99
  spur feature check --json
103
100
  ```
104
101
 
105
- Task edges: `feature move` rewrites `feature_id` across **all** configured task folders (via `foldersConfig`). Safety check:
102
+ Task edges: `feature move` rewrites `feature_id` across **all** configured task folders (via `foldersConfig`). Safety check (the glob covers every tasks folder, present and future):
106
103
 
107
104
  ```bash
108
- rg -n '^feature_id: <old_id>$' docs/tasks docs/tasks2 docs/tasks3
105
+ rg -n '^feature_id: <old_id>$' docs/tasks*/
109
106
  ```
110
107
 
111
108
  If any stale edges remain, fix with: