@gobing-ai/spur 0.3.78 → 0.3.81
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/config.example.yaml +29 -18
- package/config/config.global.yaml +10 -11
- package/config/pipeline-budgets.json +34 -2
- package/config/plugin-scripts.json +25 -0
- package/config/rules/boundary/config-loading-ownership.yaml +0 -3
- package/config/rules/boundary/dao-boundary.yaml +4 -17
- package/config/rules/boundary/planning-folder-hardcode.yaml +0 -1
- package/config/rules/boundary/sp-no-vendor-refs.yaml +3 -2
- package/config/rules/boundary/sp-runtime-path.yaml +3 -14
- package/config/rules/quality/coverage-gate.yaml +3 -14
- package/config/rules/quality/tsdoc-exports.yaml +4 -7
- package/config/rules/strict/http-boundaries.yaml +5 -8
- package/config/rules/strict/runtime-boundaries.yaml +1 -5
- package/config/rules/structure/protected-files.yaml +9 -3
- package/config/rules/structure/test-focus-skip.yaml +0 -2
- package/config/rules/structure/test-location.yaml +0 -5
- package/config/rules/surface/check-cli-surface.yaml +3 -2
- package/config/rules/typescript/bun-tooling.yaml +5 -7
- package/config/rules/typescript/guarded-happy-dom-register.yaml +0 -2
- package/config/rules/typescript/happy-dom-teardown.yaml +0 -2
- package/config/rules/typescript/no-biome-suppressions.yaml +0 -2
- package/config/rules/typescript/no-debugger.yaml +0 -2
- package/config/rules/typescript/no-eslint-suppressions.yaml +0 -4
- package/config/rules/typescript/no-leaky-module-mocks.yaml +6 -13
- package/config/rules/typescript/no-module-scope-import-calls.yaml +0 -2
- package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +0 -3
- package/config/rules/typescript/no-unmocked-module-eval-side-effects.yaml +0 -3
- package/config/rules/typescript/output-boundaries.yaml +0 -3
- package/config/rules/typescript/prefer-accessible-role-for-button-queries.yaml +0 -3
- package/config/rules/ui/ui-import-boundary.yaml +1 -5
- package/config/templates/AGENTS.md +26 -23
- package/config/templates/docs/00_ADR.md +13 -23
- package/config/templates/docs/01_PRD.md +5 -2
- package/config/templates/docs/02_ROADMAP.md +9 -13
- package/config/templates/docs/03_ARCHITECTURE.md +2 -2
- package/config/templates/docs/04_DESIGN.md +12 -31
- package/config/templates/docs/05_FEATURES.md +6 -18
- package/config/templates/docs/99_PROJECT_CONSTITUTION.md +162 -394
- package/config/transition-shims.json +7 -7
- package/config/workflows/basic.yaml +4 -0
- package/config/workflows/docs-pipeline.yaml +13 -14
- package/config/workflows/feature-dev.yaml +20 -65
- package/config/workflows/history-anatomy.yaml +22 -1
- package/config/workflows/idea-pipeline.yaml +53 -97
- package/config/workflows/pr-review.yaml +21 -33
- package/config/workflows/task-pipeline.yaml +87 -330
- package/config/workflows/wayfinder-resolution.yaml +12 -26
- package/config/workflows/wrapup-pipeline.yaml +48 -189
- package/package.json +9 -9
- package/plugins/sp/README.md +22 -8
- package/plugins/sp/agents/expert-spur.md +41 -19
- package/plugins/sp/agents/super-reviewer.md +43 -8
- package/plugins/sp/lib/idea-handoff.generated.d.mts +17 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +1301 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/feature-dev-precheck.mjs +146 -0
- package/plugins/sp/scripts/feature-dev-precheck.ts +238 -0
- package/plugins/sp/scripts/idea-handoff.mjs +27 -0
- package/plugins/sp/scripts/idea-handoff.ts +44 -0
- package/plugins/sp/scripts/quality-gate.mjs +165 -0
- package/plugins/sp/scripts/quality-gate.ts +217 -0
- package/plugins/sp/scripts/verify-answer-lint.ts +21 -3
- package/plugins/sp/scripts/workflow-step-profile.mjs +319 -0
- package/plugins/sp/scripts/workflow-step-profile.ts +456 -0
- package/plugins/sp/scripts/wrapup-steps.mjs +350 -0
- package/plugins/sp/scripts/wrapup-steps.ts +466 -0
- package/plugins/sp/skills/conflict-finding/SKILL.md +6 -0
- package/plugins/sp/skills/daily-summary/SKILL.md +1 -1
- package/plugins/sp/skills/doc-evolve/SKILL.md +26 -40
- package/plugins/sp/skills/doc-evolve/references/operations.md +17 -30
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +29 -0
- package/plugins/sp/skills/spur-cli/references/agent.md +56 -14
- package/plugins/sp/skills/spur-cli/references/message.md +30 -3
- package/plugins/sp/skills/spur-cli/references/projects.md +45 -1
- package/plugins/sp/skills/spur-cli/references/self.md +5 -4
- package/plugins/sp/skills/spur-cli/references/serve.md +5 -4
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +17 -1
- package/plugins/sp/skills/spur-cli/references/tasks.md +32 -2
- package/plugins/sp/skills/spur-cli/references/team.md +21 -1
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +6 -3
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +57 -18
- package/plugins/sp/skills/spur-composer/SKILL.md +145 -0
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +14 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -3
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +12 -0
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +46 -4
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +24 -0
- package/plugins/sp/skills/spur-doctor/SKILL.md +138 -0
- package/plugins/sp/skills/taste-refactoring-api/README.md +43 -0
- package/plugins/sp/skills/taste-refactoring-api/SKILL.md +334 -0
- package/plugins/sp/skills/taste-refactoring-api/checklists/daily-api-review.md +71 -0
- package/plugins/sp/skills/taste-refactoring-api/examples/refactor-example.md +72 -0
- package/plugins/sp/skills/taste-refactoring-api/examples/review-template.md +93 -0
- package/plugins/sp/skills/taste-refactoring-api/references/api-refactoring-playbook.md +253 -0
- package/plugins/sp/skills/taste-refactoring-api/references/protocol-modes.md +79 -0
- package/plugins/sp/skills/taste-refactoring-api/references/research-basis.md +58 -0
- package/plugins/sp/skills/taste-refactoring-architect/README.md +26 -0
- package/plugins/sp/skills/taste-refactoring-architect/SKILL.md +471 -0
- package/plugins/sp/skills/taste-refactoring-architect/checklists/daily-architecture-review.md +48 -0
- package/plugins/sp/skills/taste-refactoring-architect/examples/refactor-example.md +55 -0
- package/plugins/sp/skills/taste-refactoring-architect/examples/review-template.md +51 -0
- package/plugins/sp/skills/taste-refactoring-architect/references/architecture-refactoring-playbook.md +173 -0
- package/plugins/sp/skills/taste-refactoring-architect/references/research-basis.md +28 -0
- package/plugins/sp/skills/taste-refactoring-tests/README.md +28 -0
- package/plugins/sp/skills/taste-refactoring-tests/SKILL.md +482 -0
- package/plugins/sp/skills/taste-refactoring-tests/checklists/daily-test-review.md +39 -0
- package/plugins/sp/skills/taste-refactoring-tests/examples/refactor-example.md +85 -0
- package/plugins/sp/skills/taste-refactoring-tests/examples/review-template.md +59 -0
- package/plugins/sp/skills/taste-refactoring-tests/references/research-basis.md +47 -0
- package/plugins/sp/skills/taste-refactoring-tests/references/test-refactoring-playbook.md +222 -0
- package/plugins/sp/skills/taste-refactoring-ui/README.md +12 -0
- package/plugins/sp/skills/taste-refactoring-ui/SKILL.md +290 -0
- package/plugins/sp/skills/taste-refactoring-ui/checklists/daily-ui-review.md +72 -0
- package/plugins/sp/skills/taste-refactoring-ui/examples/review-template.md +51 -0
- package/plugins/sp/skills/taste-refactoring-ui/references/refactoring-ui-playbook.md +170 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +2 -2
- package/plugins/sp/skills/wayfinder/references/pipeline-resolution.md +30 -0
- package/schemas/spur-config.schema.json +49 -0
- package/spur.js +46936 -44198
- package/web/_astro/{BoardApp.CHQ1lycZ.js → BoardApp.B1U26g3I.js} +97 -95
- package/web/_astro/BoardApp.Csgyg-lS.js +1 -0
- package/web/_astro/{TaskDetail.GKfQJ60c.js → TaskDetail.DwPqpq7v.js} +1 -1
- package/web/_astro/{arc.DWEtA3Tx.js → arc.CweZEjN2.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.DB42oWmP.js → architectureDiagram-3BPJPVTR.D89pbDuv.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.rhv-zNQV.js → blockDiagram-GPEHLZMM.BOuTeEpX.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.Ci4-4VvY.js → c4Diagram-AAUBKEIU.CASbkWZF.js} +1 -1
- package/web/_astro/channel.Cx6sXxhq.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.Cc9veUgf.js → chunk-2J33WTMH.BKQYtOvY.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.Bec9c4eI.js → chunk-4BX2VUAB.9sHLdMtG.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DoV8S1iB.js → chunk-55IACEB6.wOLXWlPs.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DwR-Qlyj.js → chunk-727SXJPM.DovFbwg3.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.ND_a81WY.js → chunk-AQP2D5EJ.B1Weod1X.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Wv_jwG48.js → chunk-FMBD7UC4.TEMS04st.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CXKXCMmp.js → chunk-ND2GUHAM.Cp8VT1wQ.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.nkaoNYQq.js → chunk-QZHKN3VN.BzATdEcP.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.cMQcVlQu.js → classDiagram-4FO5ZUOK.C9BOCfAO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.cMQcVlQu.js → classDiagram-v2-Q7XG4LA2.C9BOCfAO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.OaDJ7Mr2.js → cose-bilkent-S5V4N54A.DUnr4UAw.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.Chi8IphF.js → cynefin-OW5HDTMX.rYq5uM3D.js} +1 -1
- package/web/_astro/{cytoscape.esm.DzSz-X2X.js → cytoscape.esm.BB4DxJjf.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.CzK2t_Fp.js → dagre-BM42HDAG.CWeNKe3I.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DRvxlVS7.js → diagram-2AECGRRQ.DCkfls10.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CnYvNdwA.js → diagram-5GNKFQAL.D5U4JCka.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CpLpMw5R.js → diagram-KO2AKTUF.BZJgqaqG.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.JTb78qUA.js → diagram-LMA3HP47.DoMeHvPR.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Bk-1jDIb.js → diagram-OG6HWLK6.B50qwwWX.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D8hN9GZq.js → erDiagram-TEJ5UH35.DdGPG6LK.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.-6zQr6m5.js → flowDiagram-I6XJVG4X.QP2MJ12u.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DboLQ9ca.js → ganttDiagram-6RSMTGT7.BI6LgKSy.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.4tYvJKGR.js → gitGraphDiagram-PVQCEYII.npPZiC2G.js} +1 -1
- package/web/_astro/index.DayyIngm.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.Bd9rXpsB.js → infoDiagram-5YYISTIA.DCJCBVbp.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CvMoaf67.js → ishikawaDiagram-YF4QCWOH.BMLV-3I1.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.Ccy1CA7y.js → journeyDiagram-JHISSGLW.LE58crde.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.0MaMqHNS.js → kanban-definition-UN3LZRKU.BPbz8rH9.js} +1 -1
- package/web/_astro/{linear.CHXgcIbN.js → linear.DhZaBtYh.js} +1 -1
- package/web/_astro/{mermaid.core.Ca-kcelG.js → mermaid.core.BD5-jXum.js} +6 -6
- package/web/_astro/{mindmap-definition-RKZ34NQL.BUIDlHa0.js → mindmap-definition-RKZ34NQL.MTJyrQ65.js} +1 -1
- package/web/_astro/ordinal.BYWQX77i.js +1 -0
- package/web/_astro/{pieDiagram-4H26LBE5.2dX3CU1s.js → pieDiagram-4H26LBE5.BrDhDvIS.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.B3LBlRiv.js → quadrantDiagram-W4KKPZXB.71d73_5N.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.X12I2uNx.js → requirementDiagram-4Y6WPE33.Bga6UF-z.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.BXohIHqx.js → sankeyDiagram-5OEKKPKP.BnHs4K82.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.C37ZIUzg.js → sequenceDiagram-3UESZ5HK.DsfY2gnj.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BRgz317z.js → stateDiagram-AJRCARHV.DvsTSc9a.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.7VYSXN9-.js → stateDiagram-v2-BHNVJYJU.DxzzmHUR.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.BVNz_HiN.js → timeline-definition-PNZ67QCA.4ZuQmOTt.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CHVDkPX4.js → vennDiagram-CIIHVFJN.Ck5Q86SG.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.EQQ_qT9v.js → wardleyDiagram-YWT4CUSO.BK7k2hXr.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DrAT9WoP.js → xychartDiagram-2RQKCTM6.DfCrgauK.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.DV9kx0wo.js +0 -1
- package/web/_astro/channel.BAI6xLeV.js +0 -1
- package/web/_astro/index.Dcr_8fiK.css +0 -1
- package/web/_astro/ordinal.DBvzRdQf.js +0 -1
|
@@ -60,18 +60,10 @@ states:
|
|
|
60
60
|
onEnter:
|
|
61
61
|
- kind: shell
|
|
62
62
|
options:
|
|
63
|
+
# (e) 0825: 8 lines — task check + show capture the investigate input bundle in the
|
|
64
|
+
# same soft probe; show must stay verbatim (it IS the bundle downstream reads).
|
|
63
65
|
command: >-
|
|
64
|
-
mkdir -p .spur/run &&
|
|
65
|
-
set +e &&
|
|
66
|
-
$spurBin task check $wbs; check_rc=$?;
|
|
67
|
-
$spurBin task show $wbs --json > .spur/run/$__runId-wayfinder-input.json; show_rc=$?;
|
|
68
|
-
set -e &&
|
|
69
|
-
if [ "$check_rc" -eq 0 ] && [ "$show_rc" -eq 0 ]; then
|
|
70
|
-
printf 'PASS\n' > .spur/run/$__runId-wayfinder-precheck.status;
|
|
71
|
-
else
|
|
72
|
-
printf 'FAIL\n' > .spur/run/$__runId-wayfinder-precheck.status;
|
|
73
|
-
fi &&
|
|
74
|
-
exit 0
|
|
66
|
+
mkdir -p .spur/run; $spurBin task check $wbs; c=$?; $spurBin task show $wbs --json > .spur/run/$__runId-wayfinder-input.json && [ "$c" -eq 0 ] && printf 'PASS\n' > .spur/run/$__runId-wayfinder-precheck.status || printf 'FAIL\n' > .spur/run/$__runId-wayfinder-precheck.status; exit 0
|
|
75
67
|
- kind: note
|
|
76
68
|
options:
|
|
77
69
|
message: "Wayfinder resolution started for task ${vars.wbs} (mode=${vars.resolutionMode}, evidence=${vars.evidencePolicy}); no code implementation pipeline is permitted."
|
|
@@ -86,22 +78,10 @@ states:
|
|
|
86
78
|
# Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
|
|
87
79
|
role: planner
|
|
88
80
|
mode: text
|
|
81
|
+
# (e) 0825: bounded reference-reading prompt (260 chars) — the authoring contract
|
|
82
|
+
# lives in the skill reference sp:wayfinder references/pipeline-resolution.md.
|
|
89
83
|
input: >-
|
|
90
|
-
Resolve task ${vars.wbs}
|
|
91
|
-
local bundle `.spur/run/${vars.__runId}-wayfinder-input.json` and only local shell/file
|
|
92
|
-
reads plus the `spur` CLI; do not use network search or MCP tools. Do not
|
|
93
|
-
invoke task-pipeline.yaml, /sp:dev-run, /sp:dev-runall, or code implementation.
|
|
94
|
-
Read the task file, map its existing Requirements and Acceptance Criteria to the
|
|
95
|
-
existing Design/Plan/References, then author concise Solution, Testing, and Review
|
|
96
|
-
sections through `spur task update --section --from-file`. Preserve the research
|
|
97
|
-
boundary. Finish with a short summary and stop. Evidence policy: ${vars.evidencePolicy}.
|
|
98
|
-
|
|
99
|
-
Evidence-anchor contract (mandatory — 0299 R1 line-anchor rule): when the task's
|
|
100
|
-
evidence lives in a shared evidence file, anchor every Solution/Testing `file:line`
|
|
101
|
-
citation truthfully — resolve the section's real start line with
|
|
102
|
-
`grep -n "^## <wbs> " <evidence-file>` and cite that exact line. NEVER copy a line
|
|
103
|
-
number from another ticket's example; each WBS anchors to its own section. Before
|
|
104
|
-
finishing, re-read each cited line and confirm it names the requirement's subject.
|
|
84
|
+
Resolve wayfinder task ${vars.wbs} per the sp:wayfinder skill (references/pipeline-resolution.md). Mode ${vars.resolutionMode}; evidence policy ${vars.evidencePolicy}; bundle .spur/run/${vars.__runId}-wayfinder-input.json. Finish with a short summary and stop.
|
|
105
85
|
answerFile: .spur/run/${vars.__runId}-wayfinder-answer.md
|
|
106
86
|
expectFile: .spur/run/${vars.__runId}-wayfinder-answer.md
|
|
107
87
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
@@ -121,6 +101,8 @@ states:
|
|
|
121
101
|
# proof digest via taskFile; a silent miss would degrade the proof to tree-only.
|
|
122
102
|
- kind: shell
|
|
123
103
|
options:
|
|
104
|
+
# (e) 0825: 6 lines — fail-closed lookup feeds every downstream artifact name;
|
|
105
|
+
# folding a silent miss into the digest would fake tree coverage.
|
|
124
106
|
command: >-
|
|
125
107
|
set -e;
|
|
126
108
|
task_path="$($spurBin task path $wbs --json | jq -r '.path // .filePath // empty')";
|
|
@@ -155,6 +137,8 @@ states:
|
|
|
155
137
|
command: "$spurBin task verdict $wbs --from-answer .spur/run/$__runId-wayfinder-verify-answer.txt"
|
|
156
138
|
- kind: shell
|
|
157
139
|
options:
|
|
140
|
+
# (e) 0825: 6 lines — stamp shell freezes the proof digest + capture point into the
|
|
141
|
+
# verdict before it is registered; the closing guard compares against this stamp.
|
|
158
142
|
command: >-
|
|
159
143
|
V=".spur/run/$wbs-verdict.json";
|
|
160
144
|
if [ -f "$V" ] && [ -n "$proofDigest" ]; then
|
|
@@ -246,6 +230,8 @@ transitions:
|
|
|
246
230
|
guard:
|
|
247
231
|
kind: shell
|
|
248
232
|
options:
|
|
233
|
+
# (e) 0825: 5-line guard — approval + digest-bracket + verdict PASS must all hold
|
|
234
|
+
# before record; dropping any operand would let a stale proof auto-record.
|
|
249
235
|
command: >-
|
|
250
236
|
test "$approval" = auto &&
|
|
251
237
|
test -n "$proofDigest" &&
|
|
@@ -130,91 +130,36 @@ states:
|
|
|
130
130
|
- kind: note
|
|
131
131
|
options:
|
|
132
132
|
message: "Resolving task list: ${vars.tasks} (proportional mode: ${vars.mode})"
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
# __runId, an unresolved task, a failed or malformed lookup, or a task
|
|
137
|
-
# not at a completed status records FAIL (routed to `failed` by the first
|
|
138
|
-
# declared edge) and is never re-interpreted as an empty list by a later
|
|
139
|
-
# sibling guard. The normalized, deduplicated list is persisted
|
|
140
|
-
# run-scoped; the route writer, metrics, prompts, notes and guards only
|
|
141
|
-
# ever read that capture.
|
|
133
|
+
# (d) wrapup-steps.ts resolve owns task capture and status resolution (0824);
|
|
134
|
+
# the wrapper only locates it (monorepo first, registered twin under node) and
|
|
135
|
+
# fails closed, writing FAIL for the failed defense edge — never PASS.
|
|
142
136
|
- kind: shell
|
|
143
137
|
options:
|
|
144
138
|
command: >-
|
|
145
139
|
mkdir -p .spur/run &&
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
fi &&
|
|
151
|
-
REASON_FILE=".spur/run/$RUN_ID-route-reason.txt" &&
|
|
152
|
-
STATUS_FILE=".spur/run/$RUN_ID-wrapup-resolve.status" &&
|
|
153
|
-
TASKS_FILE=".spur/run/$RUN_ID-wrapup-tasks.json" &&
|
|
154
|
-
if ! printf '%s' "$tasks" | jq -e 'type == "array" and all(.[]; type == "string" and test("^[0-9]{4}$"))' > /dev/null 2>&1; then
|
|
155
|
-
echo "task-resolve: tasks must be a JSON array of canonical four-digit WBS strings (whitespace is rejected, not trimmed)" >&2;
|
|
156
|
-
echo "failed:tasks is not a JSON array of canonical four-digit WBS strings" > "$REASON_FILE";
|
|
157
|
-
printf 'FAIL\n' > "$STATUS_FILE";
|
|
140
|
+
if [ -f plugins/sp/scripts/wrapup-steps.ts ]; then
|
|
141
|
+
bun plugins/sp/scripts/wrapup-steps.ts resolve;
|
|
142
|
+
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
143
|
+
node "$W" resolve;
|
|
158
144
|
else
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
fi;
|
|
170
|
-
done;
|
|
171
|
-
if [ "$RESOLVE_RC" -eq 0 ]; then
|
|
172
|
-
printf 'PASS\n' > "$STATUS_FILE";
|
|
173
|
-
else
|
|
174
|
-
echo "failed:unresolved or non-completed task (see $TASKS_FILE)" > "$REASON_FILE";
|
|
175
|
-
printf 'FAIL\n' > "$STATUS_FILE";
|
|
176
|
-
fi;
|
|
177
|
-
fi;
|
|
178
|
-
exit 0
|
|
179
|
-
# Route reason writer (0758 R3/R4 run-attribution pins intact). Runs AFTER
|
|
180
|
-
# validation and reads ONLY the validated run-scoped capture — never raw
|
|
181
|
-
# vars.tasks (0783 R2/R5); the fixed-path fallback is gone because
|
|
182
|
-
# validation refuses an empty __runId above. A FAIL resolve exits without
|
|
183
|
-
# writing: the failed reason written by validation stands, and the skip
|
|
184
|
-
# reason can never mask it. A missing/corrupted capture yields N=-1 and
|
|
185
|
-
# no skipped claim; the failed defense edge owns the run.
|
|
145
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
146
|
+
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-resolve.status";
|
|
147
|
+
fi
|
|
148
|
+
# (e) route-reason writer: one jq table lookup over the mode var over the
|
|
149
|
+
# validated capture; workflow-local routing glue (0824). Runs AFTER validation
|
|
150
|
+
# and reads ONLY .spur/run/<runId>-wrapup-tasks.json — never raw vars.tasks
|
|
151
|
+
# (0783 R2/R5). A FAIL resolve exits without writing: the failed reason written
|
|
152
|
+
# by validation stands, and the skip reason can never mask it. A missing or
|
|
153
|
+
# corrupted capture fails the jq lookup (no skipped claim can be invented);
|
|
154
|
+
# the failed defense edge owns the run.
|
|
186
155
|
- kind: shell
|
|
187
156
|
options:
|
|
188
157
|
command: >-
|
|
189
|
-
mkdir -p .spur/run .spur/memory
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
fi &&
|
|
195
|
-
REASON_FILE=".spur/run/$RUN_ID-route-reason.txt" &&
|
|
196
|
-
STATUS_FILE=".spur/run/$RUN_ID-wrapup-resolve.status" &&
|
|
197
|
-
TASKS_FILE=".spur/run/$RUN_ID-wrapup-tasks.json" &&
|
|
198
|
-
if [ "$(cat "$STATUS_FILE" 2>/dev/null)" = FAIL ]; then
|
|
199
|
-
exit 0;
|
|
200
|
-
fi &&
|
|
201
|
-
N=$(jq length "$TASKS_FILE" 2>/dev/null || echo -1) &&
|
|
202
|
-
if [ "$N" -eq 0 ]; then
|
|
203
|
-
echo "skipped:empty task list" > "$REASON_FILE";
|
|
204
|
-
elif [ "$mode" = "fast" ]; then
|
|
205
|
-
echo "fast:evidence complete+consistent" > "$REASON_FILE";
|
|
206
|
-
elif [ -z "$mode" ]; then
|
|
207
|
-
echo "safety:missing evidence (mode empty)" > "$REASON_FILE";
|
|
208
|
-
elif [ "$mode" = "unknown" ]; then
|
|
209
|
-
echo "safety:unknown evidence quality" > "$REASON_FILE";
|
|
210
|
-
elif [ "$mode" = "conflict" ]; then
|
|
211
|
-
echo "safety:conflicting evidence" > "$REASON_FILE";
|
|
212
|
-
else
|
|
213
|
-
echo "safety:unrecognized evidence (mode=$mode)" > "$REASON_FILE";
|
|
214
|
-
fi &&
|
|
215
|
-
printf '%s %s\n' "$RUN_ID" "$(cat "$REASON_FILE")"
|
|
216
|
-
>> .spur/memory/wrapup-routes.log &&
|
|
217
|
-
exit 0
|
|
158
|
+
mkdir -p .spur/run .spur/memory; RUN_ID="$__runId"; case "$RUN_ID" in '') echo "task-resolve: __runId is empty — refusing to write a route reason" >&2; exit 1 ;; esac;
|
|
159
|
+
REASON_FILE=".spur/run/$RUN_ID-route-reason.txt"; case "$(cat ".spur/run/$RUN_ID-wrapup-resolve.status" 2>/dev/null)" in FAIL) exit 0 ;; esac;
|
|
160
|
+
N=$(jq length ".spur/run/$RUN_ID-wrapup-tasks.json" 2>/dev/null);
|
|
161
|
+
jq -rn --arg m "$mode" --arg n "$N" 'if $n == "0" then "skipped:empty task list" else {"fast":"fast:evidence complete+consistent","":"safety:missing evidence (mode empty)","unknown":"safety:unknown evidence quality","conflict":"safety:conflicting evidence"}[$m] // "safety:unrecognized evidence (mode=\($m))" end' > "$REASON_FILE";
|
|
162
|
+
printf '%s %s\n' "$RUN_ID" "$(cat "$REASON_FILE")" >> .spur/memory/wrapup-routes.log
|
|
218
163
|
|
|
219
164
|
- id: doc-sync
|
|
220
165
|
description: >
|
|
@@ -227,6 +172,8 @@ states:
|
|
|
227
172
|
a non-empty capture before the append; append is best-effort soft (empty capture
|
|
228
173
|
skips without aborting wrap-up).
|
|
229
174
|
onEnter:
|
|
175
|
+
# (warn) free-form prompt: no /sp:doc-evolve command surface yet (ADR-043
|
|
176
|
+
# residual, 0607 R2 one-query merge); capture is bounded by expectFile.
|
|
230
177
|
- kind: agent.run
|
|
231
178
|
options:
|
|
232
179
|
agent: ${vars.agent}
|
|
@@ -245,6 +192,8 @@ states:
|
|
|
245
192
|
answerFile: .spur/run/${vars.__runId}-wrapup-learnings.md
|
|
246
193
|
expectFile: .spur/run/${vars.__runId}-wrapup-learnings.md
|
|
247
194
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
195
|
+
# (warn) learnings append is intentionally soft (empty capture skips
|
|
196
|
+
# without aborting wrap-up, 0607 R2).
|
|
248
197
|
- kind: shell
|
|
249
198
|
options:
|
|
250
199
|
command: >-
|
|
@@ -270,40 +219,20 @@ states:
|
|
|
270
219
|
is UNKNOWN telemetry, never proof of completion; previously written valid rows
|
|
271
220
|
survive a failure.
|
|
272
221
|
onEnter:
|
|
222
|
+
# (d) wrapup-steps.ts metrics owns the JSONL row append (0824); the wrapper
|
|
223
|
+
# only locates it and fails closed — FAIL, never a silent skip.
|
|
273
224
|
- kind: shell
|
|
274
225
|
options:
|
|
275
226
|
command: >-
|
|
276
|
-
mkdir -p .spur/run
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
echo "metrics-record: run-scoped task capture missing, corrupted or non-canonical — refusing to record metrics" >&2;
|
|
282
|
-
printf 'FAIL\n' > "$STATUS_FILE";
|
|
227
|
+
mkdir -p .spur/run &&
|
|
228
|
+
if [ -f plugins/sp/scripts/wrapup-steps.ts ]; then
|
|
229
|
+
bun plugins/sp/scripts/wrapup-steps.ts metrics;
|
|
230
|
+
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
231
|
+
node "$W" metrics;
|
|
283
232
|
else
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
feat=$(printf '%s' "$task_json" | jq -r '.frontmatter.feature_id // .feature_id // ""');
|
|
288
|
-
stat=$(printf '%s' "$task_json" | jq -r '.frontmatter.status // .status // "unknown"');
|
|
289
|
-
verdict="UNKNOWN";
|
|
290
|
-
if [ -f ".spur/run/$wbs-verdict.json" ]; then
|
|
291
|
-
v=$(jq -r '.verdict // "UNKNOWN"' ".spur/run/$wbs-verdict.json" 2>/dev/null || true);
|
|
292
|
-
if [ -n "$v" ]; then verdict="$v"; fi;
|
|
293
|
-
fi;
|
|
294
|
-
ts=$(date -u +"%Y-%m-%dT%H:%M:%SZ");
|
|
295
|
-
if ! jq -cn --arg wbs "$wbs" --arg feature_id "$feat" --arg status "$stat" --arg verdict "$verdict" --arg timestamp "$ts" '{wbs:$wbs, feature_id:$feature_id, status:$status, verdict:$verdict, timestamp:$timestamp}' >> .spur/memory/wrapup-metrics.jsonl; then
|
|
296
|
-
echo "metrics-record: metrics append failed for task $wbs — recording FAIL instead of claiming the row landed" >&2;
|
|
297
|
-
METRICS_RC=1;
|
|
298
|
-
fi;
|
|
299
|
-
else
|
|
300
|
-
echo "metrics-record: task $wbs lookup failed or was malformed — recording FAIL instead of silently omitting its metrics row" >&2;
|
|
301
|
-
METRICS_RC=1;
|
|
302
|
-
fi;
|
|
303
|
-
done;
|
|
304
|
-
if [ "$METRICS_RC" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi;
|
|
305
|
-
fi;
|
|
306
|
-
exit 0
|
|
233
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
234
|
+
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-metrics.status";
|
|
235
|
+
fi
|
|
307
236
|
|
|
308
237
|
- id: feature-transition
|
|
309
238
|
description: >
|
|
@@ -320,94 +249,24 @@ states:
|
|
|
320
249
|
(the engine only enters this state when vars.feature is set) and fails
|
|
321
250
|
loud (dogfood 2026-08-15, feature I3).
|
|
322
251
|
onEnter:
|
|
323
|
-
#
|
|
324
|
-
#
|
|
325
|
-
#
|
|
326
|
-
#
|
|
327
|
-
# writes PASS
|
|
328
|
-
#
|
|
329
|
-
# the plain `spur feature sync` verb.
|
|
330
|
-
# R1 (0625): a feature transition that changed state may have left
|
|
331
|
-
# cross-task fallout the per-task fast gates never see. The
|
|
332
|
-
# affected-feature gate (featureGateCmd) runs after an applied sync OR a
|
|
333
|
-
# non-zero exit that may follow a partial multi-hop transition. It is a
|
|
334
|
-
# diagnostic only: a gate PASS can never convert a failed sync into
|
|
335
|
-
# success, and a gate FAIL fails the step (0770 failure routing).
|
|
336
|
-
# NOTE: do not add
|
|
337
|
-
# `#` comments INSIDE the folded shell string — YAML `>-` folds them onto
|
|
338
|
-
# the following statement line and comments it out.
|
|
252
|
+
# (d) wrapup-steps.ts feature-transition owns the bounded sync, observation
|
|
253
|
+
# and the gate (0824); the wrapper only locates it and fails closed. The
|
|
254
|
+
# script terminates exit 0 on every path so artifacts that already landed
|
|
255
|
+
# are never discarded; soft TERMINATION is not soft TRUTH — only a verified
|
|
256
|
+
# sync writes PASS (0783 R4). A gate PASS can never convert a failed sync
|
|
257
|
+
# into success, and a gate FAIL fails the step (0770 failure routing).
|
|
339
258
|
- kind: shell
|
|
340
259
|
options:
|
|
341
260
|
command: >-
|
|
342
261
|
mkdir -p .spur/run &&
|
|
343
|
-
if [ -
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
SYNC_OUTPUT=$(if [ -f plugins/sp/scripts/feature-sync-bounded.ts ]; then
|
|
348
|
-
bun plugins/sp/scripts/feature-sync-bounded.ts "$feature" --spur-bin "$spurBin" --json;
|
|
349
|
-
elif SYNC_MJS="$(superskill script path sp feature-sync-bounded.mjs 2>/dev/null)" && [ -f "$SYNC_MJS" ]; then
|
|
350
|
-
node "$SYNC_MJS" "$feature" --spur-bin "$spurBin" --json;
|
|
351
|
-
else
|
|
352
|
-
$spurBin feature sync "$feature" --json;
|
|
353
|
-
fi);
|
|
354
|
-
SYNC_RC=$?;
|
|
355
|
-
printf '%s\n' "$SYNC_OUTPUT";
|
|
356
|
-
OBSERVED=$($spurBin feature show "$feature" --json 2>/dev/null | jq -r '.status // .frontmatter.status // empty' 2>/dev/null || true);
|
|
357
|
-
if [ -z "$OBSERVED" ]; then OBSERVED=unreadable; fi;
|
|
358
|
-
APPLIED=unreadable;
|
|
359
|
-
SYNC_OK=0;
|
|
360
|
-
REASON="";
|
|
361
|
-
if [ "$SYNC_RC" -ne 0 ]; then
|
|
362
|
-
REASON="sync exited nonzero (rc=$SYNC_RC)";
|
|
363
|
-
elif ! printf '%s' "$SYNC_OUTPUT" | jq -e 'type == "object" and (.proposal | type == "object") and (.proposal.featureId | type == "string") and (.proposal.from | type == "string") and (.proposal.to | type == "string") and (.applied | type == "boolean")' > /dev/null 2>&1; then
|
|
364
|
-
REASON="malformed or unreadable sync result";
|
|
365
|
-
else
|
|
366
|
-
P_FROM=$(printf '%s' "$SYNC_OUTPUT" | jq -r '.proposal.from // ""');
|
|
367
|
-
P_TO=$(printf '%s' "$SYNC_OUTPUT" | jq -r '.proposal.to // ""');
|
|
368
|
-
APPLIED=$(printf '%s' "$SYNC_OUTPUT" | jq -r '.applied');
|
|
369
|
-
if [ "$(printf '%s' "$SYNC_OUTPUT" | jq -r '.proposal.featureId // ""')" != "$feature" ]; then
|
|
370
|
-
REASON="sync proposal does not match feature $feature";
|
|
371
|
-
elif [ "$(printf '%s' "$SYNC_OUTPUT" | jq -r '.proposal.gateBlocked // false')" = "true" ]; then
|
|
372
|
-
REASON="sync proposal is gate-blocked — a blocked sync is not a no-change success";
|
|
373
|
-
elif [ "$(printf '%s' "$SYNC_OUTPUT" | jq -r '.proposal.requiresConfirm // false')" = "true" ]; then
|
|
374
|
-
REASON="sync proposal requires operator confirmation";
|
|
375
|
-
elif [ "$APPLIED" = "true" ] && [ "$OBSERVED" != "$P_TO" ]; then
|
|
376
|
-
REASON="applied sync did not land on the proposal target (observed=$OBSERVED, to=$P_TO)";
|
|
377
|
-
elif [ "$APPLIED" = "false" ] && { [ "$P_FROM" != "$P_TO" ] || [ "$OBSERVED" != "$P_TO" ]; }; then
|
|
378
|
-
REASON="sync applied nothing without a from==to observed no-op (from=$P_FROM, to=$P_TO, observed=$OBSERVED)";
|
|
379
|
-
else
|
|
380
|
-
SYNC_OK=1;
|
|
381
|
-
fi;
|
|
382
|
-
fi;
|
|
383
|
-
GATE="skipped";
|
|
384
|
-
if [ "$APPLIED" = "true" ] || [ "$SYNC_RC" -ne 0 ]; then
|
|
385
|
-
echo "feature-transition: sync applied or failed after a possible partial transition for $feature — running feature gate: $featureGateCmd";
|
|
386
|
-
if sh -c "$featureGateCmd"; then
|
|
387
|
-
GATE="PASS";
|
|
388
|
-
echo "feature-transition: feature gate PASS for feature $feature";
|
|
389
|
-
else
|
|
390
|
-
GATE="FAIL";
|
|
391
|
-
echo "feature-transition: feature gate FAIL for feature $feature — inspect findings before reporting the transition complete" >&2;
|
|
392
|
-
fi;
|
|
393
|
-
else
|
|
394
|
-
echo "feature-transition: sync did not apply a transition (rc=$SYNC_RC, applied=$APPLIED) — feature gate skipped";
|
|
395
|
-
fi;
|
|
396
|
-
SYNC_STATUS="PASS";
|
|
397
|
-
if [ "$SYNC_OK" -ne 1 ] || [ "$GATE" = "FAIL" ]; then
|
|
398
|
-
SYNC_STATUS="FAIL";
|
|
399
|
-
echo "feature-transition: required synchronization failed for $feature — $REASON; gate=$GATE" >&2;
|
|
400
|
-
elif [ "$APPLIED" = "false" ]; then
|
|
401
|
-
echo "feature-transition: feature sync verified for $feature (from==to observed at $OBSERVED, gate=$GATE) — explicit no-change";
|
|
402
|
-
else
|
|
403
|
-
echo "feature-transition: feature sync verified for $feature (applied, observed=$OBSERVED, gate=$GATE)";
|
|
404
|
-
fi;
|
|
405
|
-
if [ "$SYNC_STATUS" = "PASS" ]; then
|
|
406
|
-
printf 'PASS\n' > ".spur/run/$__runId-wrapup-sync.status";
|
|
262
|
+
if [ -f plugins/sp/scripts/wrapup-steps.ts ]; then
|
|
263
|
+
bun plugins/sp/scripts/wrapup-steps.ts feature-transition;
|
|
264
|
+
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
265
|
+
node "$W" feature-transition;
|
|
407
266
|
else
|
|
267
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
408
268
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-sync.status";
|
|
409
|
-
fi
|
|
410
|
-
exit 0
|
|
269
|
+
fi
|
|
411
270
|
|
|
412
271
|
- id: branch-cleanup
|
|
413
272
|
description: >
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.81",
|
|
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.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.4.66",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.4.66",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.66",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.4.66",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.66",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.4.66",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.4.66",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.4.66",
|
|
64
64
|
"@types/bun": "1.3.14",
|
|
65
65
|
"@types/figlet": "^1.7.0",
|
|
66
66
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -171,10 +171,12 @@ Commands above are thin wrappers; the actual logic lives in `skills/`. The spine
|
|
|
171
171
|
dispatches five competency skills by function — design (`sp:sys-architecture`), decomposition
|
|
172
172
|
(`sp:spec-decomposition`), implementation (`sp:code-implementation`), testing (`sp:code-testing`),
|
|
173
173
|
and verification (`sp:code-verification`) — plus a CLI facade (`sp:spur-cli`, one reference per
|
|
174
|
-
`spur` noun) and standalone technique skills (`sp:next-router`, `sp:
|
|
175
|
-
`sp:
|
|
176
|
-
`sp:
|
|
177
|
-
`sp:
|
|
174
|
+
`spur` noun) and standalone technique skills (`sp:next-router`, `sp:next-feature`,
|
|
175
|
+
`sp:test-driven-development`, `sp:source-driven-development`, `sp:doubt-driven-development`,
|
|
176
|
+
`sp:brainstorm`, `sp:wayfinder`, `sp:sys-debugging`, `sp:code-review`, `sp:pr-reviewing`,
|
|
177
|
+
`sp:functional-review`, `sp:code-simplification`, `sp:code-improvement`, `sp:parallel-execution`,
|
|
178
|
+
`sp:branch-workflow`, `sp:doc-evolve`, `sp:dogfood-testing`, `sp:daily-summary`,
|
|
179
|
+
`sp:reverse-engineering`, `sp:history-anatomy`, `sp:issue-finding`, `sp:conflict-finding`,
|
|
178
180
|
`sp:indexed-context`, `sp:session-review`, `sp:redesign-web-ui`). See
|
|
179
181
|
[skills/spur-dev/SKILL.md](skills/spur-dev/SKILL.md)'s Step routing table for which skill owns which
|
|
180
182
|
pipeline step.
|
|
@@ -183,7 +185,7 @@ pipeline step.
|
|
|
183
185
|
|
|
184
186
|
```
|
|
185
187
|
plugins/sp/
|
|
186
|
-
├── skills/ # Domain knowledge + workflow docs (
|
|
188
|
+
├── skills/ # Domain knowledge + workflow docs (34 skills)
|
|
187
189
|
│ ├── brainstorm/ # Structured ideation workflow
|
|
188
190
|
│ │ ├── agents/openai.yaml
|
|
189
191
|
│ │ ├── examples/ideation-example.md
|
|
@@ -215,6 +217,7 @@ plugins/sp/
|
|
|
215
217
|
│ │ └── references/routing-table.md
|
|
216
218
|
│ ├── parallel-execution/ # Fan-out decision framework + patterns
|
|
217
219
|
│ │ └── references/{fan-out-patterns, result-synthesis}.md
|
|
220
|
+
│ ├── pr-reviewing/ # GitHub PR review loop backing /sp:dev-pr-review
|
|
218
221
|
│ ├── source-driven-development/ # Source-first API/contract verification (SKILL.md only)
|
|
219
222
|
│ ├── spec-decomposition/ # Feature/spec → task-batch competency
|
|
220
223
|
│ │ └── references/decomposition.md
|
|
@@ -224,6 +227,8 @@ plugins/sp/
|
|
|
224
227
|
│ │ ├── features.md + features/{verbs, acceptance-criteria, roadmap-priority}.md
|
|
225
228
|
│ │ ├── rules.md + rules/{operations, authoring-rules, fine-tuning, validation-and-extension}.md
|
|
226
229
|
│ │ └── workflows.md + workflows/{operations, authoring-workflows, validation-and-extension}.md
|
|
230
|
+
│ ├── spur-composer/ # Cross-noun selection, composition ladder, rule tuning; applies doctor proposals
|
|
231
|
+
│ ├── spur-doctor/ # Read-only artifact evaluation → proposal table (backs spur-composer)
|
|
227
232
|
│ ├── spur-dev/ # Thin planning→execution orchestration spine
|
|
228
233
|
│ │ └── references/ # ac-style-guide, cross-cutting, decision-brief, dev-operations,
|
|
229
234
|
│ │ execution-batch, execution-workflow, feature-link-helper,
|
|
@@ -255,6 +260,8 @@ plugins/sp/
|
|
|
255
260
|
├── agents/ # 4 specialist subagents (expert-spur, super-coder, super-planner, super-reviewer)
|
|
256
261
|
├── hooks/ # hooks.json + task-write-guard.{ts,test.ts} + context-{session-start,post-tool,session-stop}.ts
|
|
257
262
|
│ # + careful-guard.{ts,test.ts} + context-hooks.test.ts + token-estimate.test.ts
|
|
263
|
+
│ # + shared policy modules: agent-hint.ts, destructive-policy.{ts,test.ts}, task-file-policy.{ts,test.ts}
|
|
264
|
+
│ # + pi/guard-extension.{ts,test.ts} (plugin.json `extensions.pi` entry point)
|
|
258
265
|
├── scripts/ # Executable helpers, split from prompts (ADR-031) — validate-commands.ts (thin-wrapper validator), batch-preflight.ts + scripts/<skill>/
|
|
259
266
|
│ # (daily-summary: {daily-summary, logger}.ts; dogfood-testing: {detect-pipeline-driving, validate-report}.ts)
|
|
260
267
|
├── tests/ # Plugin tests — command-contract.test.ts + skill-structure.test.ts + batch-preflight.test.ts + per-skill suites
|
|
@@ -318,14 +325,20 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
318
325
|
| `daily-summary` | 1.0.0 | Daily summary report generator — orchestrates ccusage CLI + git history into structured markdown summaries |
|
|
319
326
|
| `doc-evolve` | 1.0 | Key-document evolution per `docs/99_PROJECT_CONSTITUTION.md` — drift audits, same-commit sync checks, frontmatter-contract verification, machine-appended lessons |
|
|
320
327
|
| `reverse-engineering` | 1.1 | Codebase analysis / HLD generation / audit — depth-driven reverse engineering with orthogonal mode, focus, and format controls; backs `/sp:dev-reverse` |
|
|
321
|
-
| `issue-finding` |
|
|
328
|
+
| `issue-finding` | 2.0 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; **legacy path** — superseded by `history-anatomy` for indexed reporting; backs no current command; directly invocable as sp:issue-finding |
|
|
322
329
|
| `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` |
|
|
323
330
|
| `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` |
|
|
324
331
|
| `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` |
|
|
325
332
|
| `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 |
|
|
326
333
|
| `history-anatomy` | 1.0 | Diagnostic interpretation owner over already-imported history — daily/ad-hoc mode contract, closed finding taxonomy, twelve-section report contract, `enrich`/`validate` rubrics; no workflow launch, no JSONL fallback, no corpus mutation |
|
|
327
|
-
| `session-review` | 1.
|
|
334
|
+
| `session-review` | 1.1 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
|
|
335
|
+
| `spur-composer` | 1.0 | Cross-noun composition — workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning; applies accepted `spur-doctor` proposals through `spur` verbs; never judges its own output and never runs a recurring loop |
|
|
336
|
+
| `spur-doctor` | 1.0 | Cross-noun evaluation — read-only CLI evidence per noun (task/feature/rule/workflow/agent spec), reflection over `history-anatomy` findings through a closed action-class map, and a proposal table; writes nothing; diagnoses artifacts, not runtime environments (`spur agent doctor`'s job) |
|
|
328
337
|
| `redesign-web-ui` | 1.0 | Existing-UI visual upgrade — audit generic AI fingerprints, apply in-stack polish against `DESIGN.md` / live tokens, verify behavior and viewports; does not migrate frameworks |
|
|
338
|
+
| `taste-refactoring-api` | — | API design and refactoring for REST/HTTP, RPC/gRPC, GraphQL, and event contracts; compatibility, security, and migration review |
|
|
339
|
+
| `taste-refactoring-ui` | — | UI design and refactoring with visual hierarchy, typography, spacing, color, and interaction review |
|
|
340
|
+
| `taste-refactoring-architect` | — | Architecture review, simplification, and refactoring; boundary modeling, dependency reduction, and migration planning |
|
|
341
|
+
| `taste-refactoring-tests` | — | Test suite refactoring for failure sensitivity, regression detection, and assertion strength; eliminates brittle mocks |
|
|
329
342
|
|
|
330
343
|
#### Bounded coexistence and retirement gate — `sp:issue-finding` (HA-S1 0661)
|
|
331
344
|
|
|
@@ -418,7 +431,7 @@ the pipeline's Phase 7 review step.
|
|
|
418
431
|
| ---------------- | ------------ | ----------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------- |
|
|
419
432
|
| `expert-spur` | expert | `sp:spur-cli` | green | "create tasks", "feature lifecycle", "add a rule", "author a workflow" |
|
|
420
433
|
| `super-coder` | builder | `sp:sys-architecture` + `sp:code-implementation` + `sp:code-testing` + `sp:sys-debugging` | blue | "implement this", "write the code", "fix this bug", "design the architecture" |
|
|
421
|
-
| `super-planner` | orchestrator | `sp:spur-dev` + `sp:dogfood-testing`
|
|
434
|
+
| `super-planner` | orchestrator | `sp:spur-dev` + `sp:parallel-execution` + `sp:dogfood-testing` + `sp:next-router` | green | "run this task end to end", "run all tasks", "run the batch", "runall" |
|
|
422
435
|
| `super-reviewer` | reviewer | `sp:code-verification` + `sp:functional-review` + `sp:code-improvement` | crimson | "review this", "check the code", "SECUA review", "run task 0042 through review" |
|
|
423
436
|
|
|
424
437
|
Each agent has:
|
|
@@ -483,6 +496,7 @@ hold `SKILL.md` and prompt-side companions only.
|
|
|
483
496
|
| `hooks/context-*.ts` | Runtime for the three registered context hooks (session-start, post-tool, session-stop) — token-cost estimation + ledger append for `sp:indexed-context` |
|
|
484
497
|
| `hooks/careful-guard.ts` | Opt-in destructive-command guard (unwired — see Hooks above) |
|
|
485
498
|
| `scripts/batch-preflight.ts` | Pure TABLE A STOP evaluation for `super-planner` — skip doomed pipeline launches without spawning a Skill subprocess; recovery hints map stuck statuses to a single `/sp:dev-*` hop |
|
|
499
|
+
| `scripts/workflow-step-profile.ts` | Read-only step profile from `spur workflow trace` — per node and action-kind durations, idle gaps, session mode and `cacheHit` coverage, plus the ADR-115 cache-window flags `sp:spur-doctor` turns into workflow-optimization proposals |
|
|
486
500
|
| `scripts/dogfood-testing/detect-pipeline-driving.ts` | Word-boundary detector for pipeline-driving testees (leading-space invariant) |
|
|
487
501
|
| `scripts/dogfood-testing/validate-report.ts` | Pure `validateReport(md)` — footer-mandatory + 7-check finalize-or-abort contract with stable error codes |
|
|
488
502
|
| `scripts/daily-summary/{daily-summary,logger}.ts` | ccusage + git-history orchestration helpers for `sp:daily-summary` |
|