@gobing-ai/spur 0.3.80 → 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/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 +10 -1
- package/plugins/sp/agents/expert-spur.md +41 -19
- 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/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/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.md +1 -1
- 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/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 +46754 -44121
- 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
|
@@ -331,7 +331,7 @@ states:
|
|
|
331
331
|
- kind: agent.run
|
|
332
332
|
options:
|
|
333
333
|
agent: ${vars.planningAgent}
|
|
334
|
-
input: "Run sp:spec-decomposition for feature ${vars.featureId}
|
|
334
|
+
input: "Run sp:spec-decomposition for feature ${vars.featureId} per skill references/decomposition.md § Idea-pipeline emission: sizing first, then the batch JSON at .spur/run/${vars.__runId}-idea-task-batch.json and the private task-order sidecar at .spur/run/${vars.__runId}-idea-task-order.json."
|
|
335
335
|
# Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
|
|
336
336
|
role: planner
|
|
337
337
|
expectFile: .spur/run/${vars.__runId}-idea-task-batch.json
|
|
@@ -341,6 +341,8 @@ states:
|
|
|
341
341
|
# unique, every sidecar name/dependency must refer to exactly one batch name, and — the
|
|
342
342
|
# converse (F2, 0518 verify) — every batch name must appear in the sidecar, so a partial
|
|
343
343
|
# sidecar can never silently skip `task deps` for an unlisted item (`[]` is valid).
|
|
344
|
+
# (warn) stays inline by design: one jq predicate over two run-scoped files; splitting
|
|
345
|
+
# it into a script would hide the exact fail-closed contract this guard pins (0824).
|
|
344
346
|
- kind: shell
|
|
345
347
|
options:
|
|
346
348
|
command: >-
|
|
@@ -380,17 +382,22 @@ states:
|
|
|
380
382
|
(CLI error or malformed result) writes the failed sentinel, preserving the
|
|
381
383
|
existing retry behavior.
|
|
382
384
|
onEnter:
|
|
385
|
+
# (e) idempotent batch creation: sentinel + temp/mv atomicity stay inline (0824);
|
|
386
|
+
# the jq verdict check keeps the done sentinel truthful so handoff-finalize can
|
|
387
|
+
# zip batch names to the returned WBS list.
|
|
383
388
|
- kind: shell
|
|
384
389
|
options:
|
|
385
390
|
command: >-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
+
P=".spur/run/$__runId-idea-batch-create" &&
|
|
392
|
+
test ! -f "$P.done" || exit 0 &&
|
|
393
|
+
rm -f "$P.failed" "$P-result.json" "$P-result.json.tmp" &&
|
|
394
|
+
if $spurBin task batch-create --file .spur/run/$__runId-idea-task-batch.json --skip-ready --json > "$P-result.json.tmp" &&
|
|
395
|
+
jq -e ".created == (.wbs | length)" "$P-result.json.tmp" >/dev/null 2>&1; then
|
|
396
|
+
mv "$P-result.json.tmp" "$P-result.json" &&
|
|
397
|
+
date -u +%Y-%m-%dT%H:%M:%SZ > "$P.done";
|
|
391
398
|
else
|
|
392
|
-
rm -f
|
|
393
|
-
date -u +%Y-%m-%dT%H:%M:%SZ > .
|
|
399
|
+
rm -f "$P-result.json.tmp" &&
|
|
400
|
+
date -u +%Y-%m-%dT%H:%M:%SZ > "$P.failed";
|
|
394
401
|
fi
|
|
395
402
|
|
|
396
403
|
- id: ready-prepare
|
|
@@ -411,24 +418,22 @@ states:
|
|
|
411
418
|
# Declared Layer-1 role (0538 R2), same planner executor as decompose.
|
|
412
419
|
role: planner
|
|
413
420
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
421
|
+
# (warn) non-slash pointer: the 0788 checklist is per-checkout (digest via the
|
|
422
|
+
# project's own computePlanningDigest), so the bounded prompt pins the skill
|
|
423
|
+
# reference instead of a command; artifacts are gated by answerFile/expectFile.
|
|
414
424
|
input: >-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
sections, never Solution/Testing/Review/History. Record one checklist row per id
|
|
422
|
-
with concrete evidence of how you verified it. Compute the planning digest with
|
|
423
|
-
the project's own implementation when this is a monorepo checkout:
|
|
424
|
-
`bun -e 'const m = await import("./packages/app/src/services/task-readiness"); console.log(m.computePlanningDigest(await Bun.file(process.argv[1]).text()))' <task-file>`
|
|
425
|
-
— when that is impossible in this checkout, set status "skipped" instead of
|
|
426
|
-
guessing a digest. Finally write .spur/run/${vars.__runId}-idea-ready.json with
|
|
427
|
-
exactly this shape: {"runId":"${vars.__runId}","depth":"ready","tasks":[{"wbs":"<wbs>","status":"ready" or "failed" or "skipped","planningDigest":"<sha256 hex>","checks":[{"id":"requirements" or "design" or "plan" or "ac" or "decisions" or "dependencies" or "premises","pass":true or false,"evidence":"<how verified>"}]}]}. A task you cannot fully prepare gets status "failed" or "skipped" — never fabricate evidence; the handoff degrades to refineall.
|
|
425
|
+
Run the ready-prepare stage for feature ${vars.featureId} per sp:spur-dev
|
|
426
|
+
references/planning-workflow.md § Step 5.6 (Ready preparation): read
|
|
427
|
+
.spur/run/${vars.__runId}-idea-batch-create-result.json and write
|
|
428
|
+
.spur/run/${vars.__runId}-idea-ready.json.
|
|
429
|
+
answerFile: .spur/run/${vars.__runId}-ready-prepare-answer.txt
|
|
430
|
+
expectFile: .spur/run/${vars.__runId}-ready-prepare-answer.txt
|
|
428
431
|
# Fail-closed shape validation (mirrors the order-sidecar guard). Absence is
|
|
429
432
|
# normalized to an empty sidecar: finalize and the seeded fallback then degrade
|
|
430
433
|
# the recommendation to refineall instead of failing the run. A PRESENT but
|
|
431
434
|
# malformed sidecar fails the run here — it must not masquerade as evidence.
|
|
435
|
+
# (warn) stays inline by design: single jq shape predicate over the run-scoped
|
|
436
|
+
# sidecar; the failed/skipped rows are what degrade the recommendation (0824).
|
|
432
437
|
- kind: shell
|
|
433
438
|
options:
|
|
434
439
|
command: >-
|
|
@@ -447,87 +452,23 @@ states:
|
|
|
447
452
|
A mapping or CLI error fails the run before terminal handoff; an unready
|
|
448
453
|
task is a successful planning outcome recorded as a refineall recommendation.
|
|
449
454
|
onEnter:
|
|
450
|
-
#
|
|
451
|
-
#
|
|
452
|
-
#
|
|
453
|
-
#
|
|
454
|
-
#
|
|
455
|
-
#
|
|
456
|
-
# D5-O (R4): the deterministic writer owns finalization wherever it exists.
|
|
457
|
-
# `idea-handoff-cli.ts` calls the tested `finalizeIdeaHandoff` capability and
|
|
458
|
-
# implements this exact contract (equal-length/unique-name zip, `spur task deps`,
|
|
459
|
-
# `spur feature refresh`, per-task check with a row-count assertion, and a single
|
|
460
|
-
# recommended next command). `spur init` never scaffolds `packages/`, so seeded
|
|
461
|
-
# projects fall through to the portable shell program below — the same
|
|
462
|
-
# monorepo-writer/shell-fallback split the wrap-up metrics hop uses (0604 Q&A).
|
|
455
|
+
# (d) idea-handoff owns finalization (0824): the bundled finalizeIdeaHandoff
|
|
456
|
+
# capability runs from the monorepo checkout first; seeded projects (no
|
|
457
|
+
# packages/, no plugins/) resolve the registered idea-handoff.mjs twin under
|
|
458
|
+
# bare node; neither present fails closed (exit 1) instead of silently
|
|
459
|
+
# skipping finalization. The zip/deps/refresh/check/report contract itself is
|
|
460
|
+
# pinned by finalizeIdeaHandoff unit tests, not by this file.
|
|
463
461
|
- kind: shell
|
|
464
462
|
options:
|
|
465
463
|
command: >-
|
|
466
464
|
if [ -f packages/app/src/workflow/idea-handoff-cli.ts ]; then
|
|
467
465
|
bun packages/app/src/workflow/idea-handoff-cli.ts;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
DEPMAP=".spur/run/$__runId-idea-dep-map.tsv" &&
|
|
475
|
-
CHECKS=".spur/run/$__runId-idea-check-results.jsonl" &&
|
|
476
|
-
rm -f "$DEPMAP" "$CHECKS" &&
|
|
477
|
-
jq -e --slurpfile b "$BATCH" '(.wbs | length) == ($b[0] | length) and (($b[0] | map(.name) | unique | length) == ($b[0] | length))' "$RESULT" >/dev/null &&
|
|
478
|
-
jq -r --slurpfile b "$BATCH" --slurpfile r "$RESULT" --slurpfile o "$ORDER" '
|
|
479
|
-
($b[0] | map(.name)) as $names | ($r[0].wbs) as $wbs |
|
|
480
|
-
$o[0] | .[] |
|
|
481
|
-
(.name as $n | $names | index($n)) as $i |
|
|
482
|
-
(if $i == null or $wbs[$i] == null then "MISSING" else $wbs[$i] end) as $own |
|
|
483
|
-
((.depends_on_names // []) | map(. as $dep | $names | index($dep) as $d | if $d == null then "MISSING" else $wbs[$d] end) | join(" ")) as $deps |
|
|
484
|
-
[.name, $own, $deps] | @tsv
|
|
485
|
-
' "$ORDER" > "$DEPMAP" &&
|
|
486
|
-
while IFS="$(printf '\t')" read -r name own deps; do
|
|
487
|
-
test "$own" != MISSING || exit 1;
|
|
488
|
-
if test -n "$deps"; then
|
|
489
|
-
for d in $deps; do test "$d" != MISSING || exit 1; done;
|
|
490
|
-
$spurBin task deps "$own" set $deps --json >/dev/null || exit 1;
|
|
491
|
-
fi;
|
|
492
|
-
done < "$DEPMAP" &&
|
|
493
|
-
$spurBin feature refresh --feature "$featureId" --json >/dev/null &&
|
|
494
|
-
WBS_LIST=$(jq -r '.wbs | join(" ")' "$RESULT") &&
|
|
495
|
-
for wbs in $WBS_LIST; do
|
|
496
|
-
TMP=".spur/run/$__runId-idea-check-$wbs.tmp";
|
|
497
|
-
if $spurBin task check "$wbs" --json > "$TMP" 2>&1; then P=true; else P=false; fi;
|
|
498
|
-
jq -c --arg w "$wbs" --argjson p "$P" 'if (type == "array" and length > 0) then {wbs: $w, pass: $p, status: (.[0].status // "unknown")} else {wbs: $w, pass: $p, status: "missing"} end' "$TMP" >> "$CHECKS" || exit 1;
|
|
499
|
-
rm -f "$TMP";
|
|
500
|
-
done &&
|
|
501
|
-
CHECK_ROWS=$(wc -l < "$CHECKS" | tr -d ' ') &&
|
|
502
|
-
WBS_COUNT=$(printf '%s\n' $WBS_LIST | wc -l | tr -d ' ') &&
|
|
503
|
-
test "$CHECK_ROWS" = "$WBS_COUNT" &&
|
|
504
|
-
READY=".spur/run/$__runId-idea-ready.json" &&
|
|
505
|
-
(test -f "$READY" || printf '{"tasks":[]}\n' > "$READY") &&
|
|
506
|
-
NEXT=$(jq -r --arg feature "$featureId" --slurpfile c "$CHECKS" --slurpfile k "$READY" 'if (($c | any(.[]; .pass == false)) or (($k[0].tasks // []) | length == 0) or (($k[0].tasks // []) | any(.[]; .status != "ready"))) then "/sp:dev-refineall --feature \($feature) --auto --depth ready" else "/sp:dev-runall --feature \($feature) --auto" end' "$RESULT") &&
|
|
507
|
-
{
|
|
508
|
-
echo "# Idea pipeline handoff report";
|
|
509
|
-
echo;
|
|
510
|
-
echo "Feature: $featureId";
|
|
511
|
-
echo "Run ID: $__runId";
|
|
512
|
-
echo;
|
|
513
|
-
echo "## Created tasks";
|
|
514
|
-
printf '%s\n' $WBS_LIST | sed 's/^/ - /';
|
|
515
|
-
echo;
|
|
516
|
-
echo "## Per-task readiness (spur task check)";
|
|
517
|
-
echo;
|
|
518
|
-
echo "| WBS | Outcome |";
|
|
519
|
-
echo "|-----|---------|";
|
|
520
|
-
while IFS= read -r line; do
|
|
521
|
-
w=$(printf '%s' "$line" | jq -r '.wbs');
|
|
522
|
-
o=$(printf '%s' "$line" | jq -r 'if .pass then "PASS" else "FAIL" end');
|
|
523
|
-
printf '| %s | %s |\n' "$w" "$o";
|
|
524
|
-
done < "$CHECKS";
|
|
525
|
-
echo;
|
|
526
|
-
echo "## Next command";
|
|
527
|
-
echo;
|
|
528
|
-
echo "$NEXT";
|
|
529
|
-
} > "$REPORT"
|
|
530
|
-
|
|
466
|
+
elif H="$(superskill script path sp idea-handoff.mjs 2>/dev/null)" && [ -f "$H" ]; then
|
|
467
|
+
node "$H";
|
|
468
|
+
else
|
|
469
|
+
echo "idea handoff failed closed — idea-handoff script not found — run 'superskill install sp'" >&2;
|
|
470
|
+
exit 1;
|
|
471
|
+
fi
|
|
531
472
|
- id: handoff
|
|
532
473
|
description: >
|
|
533
474
|
Terminal — idea pipeline complete. Ordering applied, roster refreshed, and
|
|
@@ -627,6 +568,8 @@ transitions:
|
|
|
627
568
|
- from: ac-generate
|
|
628
569
|
to: system-design
|
|
629
570
|
description: "profile=auto, check passed, design route — run system design."
|
|
571
|
+
# (warn) 4 test segments: profile gate + captured status + route signal jointly own the
|
|
572
|
+
# route; guards never re-run the CLI (0769), so there is nothing smaller to extract.
|
|
630
573
|
guard:
|
|
631
574
|
kind: shell
|
|
632
575
|
options:
|
|
@@ -635,6 +578,8 @@ transitions:
|
|
|
635
578
|
- from: ac-generate
|
|
636
579
|
to: decompose
|
|
637
580
|
description: "profile=auto, check passed, skip-design route — go directly to decompose."
|
|
581
|
+
# (warn) 5 test segments: same as auto-skip 1 plus the OR'd design=auto/needs_design=false
|
|
582
|
+
# pair that keeps one captured signal file authoritative for both routes (0769).
|
|
638
583
|
guard:
|
|
639
584
|
kind: shell
|
|
640
585
|
options:
|
|
@@ -643,6 +588,8 @@ transitions:
|
|
|
643
588
|
- from: ac-generate
|
|
644
589
|
to: ac-generate
|
|
645
590
|
description: "profile=auto, check failed, retry cap not reached — re-run ac-generate."
|
|
591
|
+
# (warn) 4 test segments: profile gate + captured status + captured retry count; the
|
|
592
|
+
# retry loop is the smallest honest formulation of cap<3 routing (0769).
|
|
646
593
|
guard:
|
|
647
594
|
kind: shell
|
|
648
595
|
options:
|
|
@@ -651,6 +598,8 @@ transitions:
|
|
|
651
598
|
- from: ac-generate
|
|
652
599
|
to: failed
|
|
653
600
|
description: "profile=auto, check failed after 3 retries — escalate to failed."
|
|
601
|
+
# (warn) 4 test segments: mirror of the retry guard with cap>=3; keeping escalation and
|
|
602
|
+
# retry as one test-chain pair makes the cap boundary auditable in the diff (0769).
|
|
654
603
|
guard:
|
|
655
604
|
kind: shell
|
|
656
605
|
options:
|
|
@@ -667,6 +616,8 @@ transitions:
|
|
|
667
616
|
- from: feature-check
|
|
668
617
|
to: system-design
|
|
669
618
|
description: Feature check passed, design route — run system design.
|
|
619
|
+
# (warn) 4 test segments: HITL answer + captured status + design route; same shape as the
|
|
620
|
+
# ac-generate auto-skips, reading the same captured signal files (0769).
|
|
670
621
|
guard:
|
|
671
622
|
kind: shell
|
|
672
623
|
options:
|
|
@@ -674,6 +625,8 @@ transitions:
|
|
|
674
625
|
- from: feature-check
|
|
675
626
|
to: decompose
|
|
676
627
|
description: Feature check passed, skip-design route — go directly to decompose.
|
|
628
|
+
# (warn) 5 test segments: same as the feature-check design route plus the OR'd
|
|
629
|
+
# design=auto/needs_design=false pair (0769).
|
|
677
630
|
guard:
|
|
678
631
|
kind: shell
|
|
679
632
|
options:
|
|
@@ -681,6 +634,8 @@ transitions:
|
|
|
681
634
|
- from: feature-check
|
|
682
635
|
to: ac-generate
|
|
683
636
|
description: "Feature check failed — revise AC (retry cap: 3)."
|
|
637
|
+
# (warn) 4 test segments: HITL reject/failed-status OR-pair + captured retry count; the
|
|
638
|
+
# interactive retry mirror of the ac-generate cap<3 guard (0769).
|
|
684
639
|
guard:
|
|
685
640
|
kind: shell
|
|
686
641
|
options:
|
|
@@ -688,6 +643,7 @@ transitions:
|
|
|
688
643
|
- from: feature-check
|
|
689
644
|
to: failed
|
|
690
645
|
description: Feature check failed after 3 retries — escalate to failed.
|
|
646
|
+
# (warn) 4 test segments: mirror of the revise guard with cap>=3 (0769).
|
|
691
647
|
guard:
|
|
692
648
|
kind: shell
|
|
693
649
|
options:
|
|
@@ -67,6 +67,8 @@ states:
|
|
|
67
67
|
onEnter:
|
|
68
68
|
- kind: shell
|
|
69
69
|
options:
|
|
70
|
+
# (e) 0825: 10 lines — detached-HEAD/dirty/gh-auth/base-refusal probes must record
|
|
71
|
+
# before any push can publish; split would let a half-probed run continue.
|
|
70
72
|
command: >-
|
|
71
73
|
mkdir -p .spur/run &&
|
|
72
74
|
STATUS_FILE=".spur/run/$__runId-pr-preflight.status" &&
|
|
@@ -83,6 +85,8 @@ states:
|
|
|
83
85
|
onEnter:
|
|
84
86
|
- kind: shell
|
|
85
87
|
options:
|
|
88
|
+
# (e) 0825: 9 lines — hygiene verdict + json capture land together; the status-file
|
|
89
|
+
# fallback keeps a silent driver from passing the gate.
|
|
86
90
|
command: >-
|
|
87
91
|
mkdir -p .spur/run &&
|
|
88
92
|
STATUS_FILE=".spur/run/$__runId-pr-hygiene.status" &&
|
|
@@ -100,16 +104,10 @@ states:
|
|
|
100
104
|
onEnter:
|
|
101
105
|
- kind: shell
|
|
102
106
|
options:
|
|
107
|
+
# (e) 0825: 7 lines — unchanged shape (optional preReviewCmd probe, SKIP/PASS/FAIL)
|
|
108
|
+
# condensed onto folded one-liners to hold the §1.2 budget.
|
|
103
109
|
command: >-
|
|
104
|
-
mkdir -p .spur/run
|
|
105
|
-
STATUS_FILE=".spur/run/$__runId-pr-precheck.status" &&
|
|
106
|
-
if [ -z "$preReviewCmd" ]; then
|
|
107
|
-
printf 'SKIP\n' > "$STATUS_FILE";
|
|
108
|
-
else
|
|
109
|
-
set +e; sh -c "$preReviewCmd"; rc=$?; set -e;
|
|
110
|
-
if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi;
|
|
111
|
-
fi &&
|
|
112
|
-
exit 0
|
|
110
|
+
mkdir -p .spur/run; if [ -z "$preReviewCmd" ]; then R=SKIP; elif sh -c "$preReviewCmd"; then R=PASS; else R=FAIL; fi; printf '%s\n' "$R" > ".spur/run/$__runId-pr-precheck.status"
|
|
113
111
|
|
|
114
112
|
- id: push
|
|
115
113
|
description: >
|
|
@@ -118,6 +116,8 @@ states:
|
|
|
118
116
|
onEnter:
|
|
119
117
|
- kind: shell
|
|
120
118
|
options:
|
|
119
|
+
# (e) 0825: 9 lines — push result and status fallback are atomic; a split could
|
|
120
|
+
# publish commits without recording the outcome.
|
|
121
121
|
command: >-
|
|
122
122
|
mkdir -p .spur/run &&
|
|
123
123
|
STATUS_FILE=".spur/run/$__runId-pr-push.status" &&
|
|
@@ -133,6 +133,8 @@ states:
|
|
|
133
133
|
onEnter:
|
|
134
134
|
- kind: shell
|
|
135
135
|
options:
|
|
136
|
+
# (e) 0825: 9 lines — PR dedupe lookup captures its record for the downstream
|
|
137
|
+
# review link; ensure + capture must not race.
|
|
136
138
|
command: >-
|
|
137
139
|
mkdir -p .spur/run &&
|
|
138
140
|
STATUS_FILE=".spur/run/$__runId-pr-ensure.status" &&
|
|
@@ -150,19 +152,10 @@ states:
|
|
|
150
152
|
onEnter:
|
|
151
153
|
- kind: shell
|
|
152
154
|
options:
|
|
155
|
+
# (e) 0825: 10 lines — the write-then-read split is the file-var transport feeding
|
|
156
|
+
# wait/collect and must stay one action (same record, same run scope).
|
|
153
157
|
command: >-
|
|
154
|
-
mkdir -p .spur/run &&
|
|
155
|
-
STATUS_FILE=".spur/run/$__runId-pr-request.status" &&
|
|
156
|
-
FORCE_FLAG="" &&
|
|
157
|
-
if [ "$mode" = "rerun" ]; then FORCE_FLAG="--force"; fi &&
|
|
158
|
-
set +e &&
|
|
159
|
-
bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $FORCE_FLAG --json
|
|
160
|
-
--status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-request.json";
|
|
161
|
-
rc=$?; set -e &&
|
|
162
|
-
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
163
|
-
[ -f ".spur/run/$__runId-pr-request.json" ] &&
|
|
164
|
-
bun -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));fs.writeFileSync(process.argv[2],(r.requestedAt ?? "")+"\n");fs.writeFileSync(process.argv[3],(r.head ?? "")+"\n")' ".spur/run/$__runId-pr-request.json" ".spur/run/$__runId-pr-since.txt" ".spur/run/$__runId-pr-head.txt";
|
|
165
|
-
exit 0
|
|
158
|
+
mkdir -p .spur/run; case "$mode" in rerun) F=--force ;; *) F= ;; esac; bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $F --json --status-file ".spur/run/$__runId-pr-request.status" > ".spur/run/$__runId-pr-request.json"; [ -f ".spur/run/$__runId-pr-request.status" ] || printf 'FAIL\n' > ".spur/run/$__runId-pr-request.status"; jq -e . ".spur/run/$__runId-pr-request.json" > /dev/null 2>&1 && jq -r '.requestedAt // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-since.txt" && jq -r '.head // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-head.txt"; exit 0
|
|
166
159
|
|
|
167
160
|
- id: wait
|
|
168
161
|
description: >
|
|
@@ -181,6 +174,8 @@ states:
|
|
|
181
174
|
var: prHead
|
|
182
175
|
- kind: shell
|
|
183
176
|
options:
|
|
177
|
+
# (e) 0825: 9 lines — bounded wait loop keeps rc bookkeeping so a crashed driver
|
|
178
|
+
# fails closed instead of polling forever.
|
|
184
179
|
command: >-
|
|
185
180
|
mkdir -p .spur/run &&
|
|
186
181
|
STATUS_FILE=".spur/run/$__runId-pr-wait.status" &&
|
|
@@ -206,19 +201,10 @@ states:
|
|
|
206
201
|
var: prHead
|
|
207
202
|
- kind: shell
|
|
208
203
|
options:
|
|
204
|
+
# (e) 0825: 9 lines — collect + status must run against the same since/head pair
|
|
205
|
+
# before the composite status is decided (same 0771 record contract).
|
|
209
206
|
command: >-
|
|
210
|
-
mkdir -p .spur/run &&
|
|
211
|
-
STATUS_FILE=".spur/run/$__runId-pr-collect.status" &&
|
|
212
|
-
set +e &&
|
|
213
|
-
bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$prSince" --head "$prHead" --json
|
|
214
|
-
--status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-findings.json";
|
|
215
|
-
collect_rc=$?;
|
|
216
|
-
bun "$(superskill script path sp pr-reviewing.ts)" status --since "$prSince" --head "$prHead" --json > ".spur/run/$__runId-pr-status.json";
|
|
217
|
-
status_rc=$?; set -e &&
|
|
218
|
-
if [ "$collect_rc" -ne 0 ] || [ "$status_rc" -ne 0 ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
219
|
-
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
220
|
-
{ cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null || true; } &&
|
|
221
|
-
exit 0
|
|
207
|
+
mkdir -p .spur/run; bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$prSince" --head "$prHead" --json --status-file ".spur/run/$__runId-pr-collect.status" > ".spur/run/$__runId-pr-findings.json"; c=$?; bun "$(superskill script path sp pr-reviewing.ts)" status --since "$prSince" --head "$prHead" --json > ".spur/run/$__runId-pr-status.json" && [ "$c" -eq 0 ] && [ -f ".spur/run/$__runId-pr-collect.status" ] || printf 'FAIL\n' > ".spur/run/$__runId-pr-collect.status"; cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null; exit 0
|
|
222
208
|
|
|
223
209
|
- id: done
|
|
224
210
|
description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
|
|
@@ -308,6 +294,8 @@ transitions:
|
|
|
308
294
|
guard:
|
|
309
295
|
kind: shell
|
|
310
296
|
options:
|
|
297
|
+
# (e) 0825: 4-predicate guard — ALREADY_REQUESTED/REQUESTED pair state is the
|
|
298
|
+
# fallback route when the review driver stalls (mode/noWait honored).
|
|
311
299
|
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"; }; }'
|
|
312
300
|
- from: request
|
|
313
301
|
to: wait
|