@gobing-ai/spur 0.3.23 → 0.3.25
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/config/config.example.yaml +74 -31
- package/config/templates/AGENTS.md +1 -0
- package/config/workflows/docs-pipeline.yaml +9 -0
- package/config/workflows/idea-pipeline.yaml +78 -18
- package/package.json +9 -9
- package/schemas/spur-config.schema.json +4 -4
- package/schemas/task-batch.schema.json +12 -0
- package/spur.js +1893 -477
- package/web/_astro/{BoardApp.b8HvN_Uy.js → BoardApp.DH9wI8y7.js} +72 -72
- package/web/_astro/BoardApp.DZiwQCP7.js +1 -0
- package/web/_astro/{TaskDetail.BRr8ebLd.js → TaskDetail.Dsk9DnGY.js} +1 -1
- package/web/_astro/{arc.D9I3ghf3.js → arc.Biv8k-OR.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.B60VjZ82.js → architectureDiagram-3BPJPVTR.BrtW5Sn7.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.B8xiXsGb.js → blockDiagram-GPEHLZMM.CTpFZJhW.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.D8Q9jRJZ.js → c4Diagram-AAUBKEIU._ZJj9H0G.js} +1 -1
- package/web/_astro/channel.Ih1_8SAH.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.BVcogAuP.js → chunk-2J33WTMH.DD9mDiEM.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.pDodeppW.js → chunk-4BX2VUAB.ENDQu3TH.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.5dYLJxJn.js → chunk-55IACEB6.DLpJf8Xp.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.C6GTI_n6.js → chunk-727SXJPM.BR6vsvIV.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.kgDX41bQ.js → chunk-AQP2D5EJ.DGOBzXM6.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.CSnAi74r.js → chunk-FMBD7UC4.DrghnRtZ.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.qQ8ldUUT.js → chunk-ND2GUHAM.BqIqI3oO.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.PzPFlVri.js → chunk-QZHKN3VN.CJ2RJt0K.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.C7RulRYW.js → classDiagram-4FO5ZUOK.Qu1p6crX.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.C7RulRYW.js → classDiagram-v2-Q7XG4LA2.Qu1p6crX.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.Dw4HZHnT.js → cose-bilkent-S5V4N54A.7VrRetJ0.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.MmGbZWM_.js → dagre-BM42HDAG.r4lTyJXQ.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DugWYvZC.js → diagram-2AECGRRQ.DahExuaR.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BL7D0BMi.js → diagram-5GNKFQAL.B-dSm3op.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.B9GQMjwM.js → diagram-KO2AKTUF.CQGlKa6a.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.CbHPvhbu.js → diagram-LMA3HP47.CJ6nomD-.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Bx6GcKpw.js → diagram-OG6HWLK6.ijGl68sM.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35._sHJgXD7.js → erDiagram-TEJ5UH35.DBAe2Iin.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.D305L8m4.js → flowDiagram-I6XJVG4X.z3iXF6Ku.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.qjJ4kX00.js → ganttDiagram-6RSMTGT7.DP2ouiRt.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.D-t4MzVO.js → gitGraphDiagram-PVQCEYII.DizVfgVG.js} +1 -1
- package/web/_astro/index.D3Y4Q0mx.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.WwSNIljZ.js → infoDiagram-5YYISTIA.BPTTgL0f.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.EWsUYdpd.js → ishikawaDiagram-YF4QCWOH.CXdMa4-b.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.CqKE9hNP.js → journeyDiagram-JHISSGLW.ChSKZ-1j.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BDCCufoa.js → kanban-definition-UN3LZRKU.DUUlW-km.js} +1 -1
- package/web/_astro/{linear.CyHEakPy.js → linear.AzHrSiEQ.js} +1 -1
- package/web/_astro/{mermaid.core.B-9P_KDH.js → mermaid.core.BajX78G7.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.bCxpjW2r.js → mindmap-definition-RKZ34NQL.BmdUHcac.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.x_CRiGMu.js → pieDiagram-4H26LBE5.Dh59Ur2v.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.CnbQkwo7.js → quadrantDiagram-W4KKPZXB.D2qYQmFj.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CfeJKVEP.js → requirementDiagram-4Y6WPE33.DW5nnrHl.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.COYpTQlG.js → sankeyDiagram-5OEKKPKP.CMl1PJrk.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DVzoeimO.js → sequenceDiagram-3UESZ5HK.U5dq1PA0.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BVL5te9q.js → stateDiagram-AJRCARHV.zrt55DVx.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.C_x1GbV0.js → stateDiagram-v2-BHNVJYJU.CKBGQ0dG.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DtZPbOJL.js → timeline-definition-PNZ67QCA.CKAlx9rU.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.pexoUOut.js → vennDiagram-CIIHVFJN.Bgt1eF06.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.DLG5pKRN.js → wardley-L42UT6IY.BF02aioC.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.CnYrM4tH.js → wardleyDiagram-YWT4CUSO.C94wxcnJ.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.kBrlce_Y.js → xychartDiagram-2RQKCTM6.BwK7SRoW.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.LygxZgOy.js +0 -1
- package/web/_astro/channel.BToTp7Lu.js +0 -1
- package/web/_astro/index.CmVh0AUD.css +0 -1
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
# Spur project configuration
|
|
2
|
-
#
|
|
1
|
+
# Spur project configuration example
|
|
2
|
+
# Seeded by `spur init` as ~/.config/spur/config.yaml on first run (never overwritten).
|
|
3
|
+
# Copy / adapt into a project as `.spur/config.yaml`.
|
|
3
4
|
|
|
4
5
|
$schema: "@gobing-ai/spur/schemas/spur-config.schema.json"
|
|
5
|
-
version: "1"
|
|
6
|
-
|
|
6
|
+
# Config schema version (string). Current recommended: "1.1".
|
|
7
|
+
# "1" remains accepted; there is no hard migrator yet. Prefer "1.1" for new projects
|
|
8
|
+
# so editors and operators know the file targets the ADR-033 + planning shape.
|
|
9
|
+
version: "1.1"
|
|
10
|
+
name: my-project
|
|
7
11
|
|
|
8
12
|
# ── Portable bootstrap (consumed by @gobing-ai/ts-infra runNodeApplication) ──
|
|
9
13
|
# Shared across spur and (future) spur-server. Keys map 1:1 to ts-infra's
|
|
10
14
|
# LoggingOptions / TelemetryOptions / database / SchedulerOptions.
|
|
15
|
+
# Not validated by spurConfigSchema (bootstrap is owned by runNodeApplication).
|
|
11
16
|
bootstrap:
|
|
12
17
|
logging:
|
|
13
18
|
enabled: true
|
|
@@ -28,40 +33,65 @@ bootstrap:
|
|
|
28
33
|
scheduler:
|
|
29
34
|
enabled: false # CLI is run-once; no scheduler
|
|
30
35
|
|
|
31
|
-
# ──
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
host: localhost # env: HOST
|
|
35
|
-
openBrowser: true # spur serve only; skip with --no-open
|
|
36
|
-
webDistPath: null # S5 local static asset path
|
|
37
|
-
# ── Spur app section (validated by a local zod schema — UNCHANGED keys) ──
|
|
36
|
+
# ── Spur app section (validated by spurConfigSchema in @gobing-ai/spur-config) ──
|
|
37
|
+
# Server runtime (port/host/openBrowser) is env-backed via PORT/HOST — not a
|
|
38
|
+
# project-config key. See design §2.2.
|
|
38
39
|
agent:
|
|
39
|
-
# `default` is the executor selector for `--agent auto`
|
|
40
|
-
#
|
|
40
|
+
# `default` is the executor selector for `--agent auto` when stage-registry
|
|
41
|
+
# routing does not apply (or as a fallback). Resolved as an executor name
|
|
42
|
+
# first, then a legacy agent name.
|
|
41
43
|
default: omp
|
|
44
|
+
|
|
42
45
|
# Canonical coding-agent ids (ts-ai-runner DISPLAY_ORDER, 0.4.8+):
|
|
43
46
|
# claude, codex, gemini, pi, omp, opencode, antigravity-cli, openclaw, hermes, grok
|
|
44
47
|
# Grok auth: non-empty XAI_API_KEY and/or ~/.grok/auth.json (no CLI auth-status verb).
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
|
|
49
|
+
# Named executor profiles (ADR-033 / 0343). Each pairs a canonical agent with
|
|
50
|
+
# an optional opaque model override and an explicit capability tier.
|
|
51
|
+
# Live tiers: cheap | standard | capable-1 | capable-2 | capable-3
|
|
52
|
+
# (1=low quality within capable, 3=high). DECLARE tier — inference never
|
|
53
|
+
# invents capable-2/3. Stage routing starts on the cheapest executor whose
|
|
54
|
+
# tier >= min_tier; same exact tier ties break by array order.
|
|
55
|
+
# Legacy bare `capable` is accepted at runtime as synonym for capable-1.
|
|
56
|
+
executors:
|
|
57
|
+
- name: omp
|
|
58
|
+
agent: omp
|
|
59
|
+
tier: standard
|
|
60
|
+
# - name: omp-zai
|
|
61
|
+
# agent: omp
|
|
62
|
+
# model: zai/glm-5.2
|
|
63
|
+
# tier: standard
|
|
64
|
+
- name: grok
|
|
65
|
+
agent: grok
|
|
66
|
+
tier: capable-2
|
|
67
|
+
- name: claude
|
|
68
|
+
agent: claude
|
|
69
|
+
tier: capable-3
|
|
70
|
+
- name: codex
|
|
71
|
+
agent: codex
|
|
72
|
+
tier: capable-3
|
|
73
|
+
# - name: pi
|
|
74
|
+
# agent: pi
|
|
75
|
+
# tier: capable-1
|
|
76
|
+
|
|
77
|
+
# `default-by-phase` is a deprecated backward-compat shim (ADR-033). Prefer
|
|
78
|
+
# executor `tier` + stage-registry model_policy. When present, a matching
|
|
79
|
+
# phase mapping is still authoritative (fail-fast; no fall back to default)
|
|
80
|
+
# and shadows stage routing for that phase.
|
|
61
81
|
# default-by-phase:
|
|
62
|
-
# dev-run: omp
|
|
82
|
+
# dev-run: omp
|
|
63
83
|
# dev-review: claude
|
|
64
|
-
|
|
84
|
+
|
|
85
|
+
# Declarative teams (feature M) — materialize with `spur team up <teamId>`.
|
|
86
|
+
# team:
|
|
87
|
+
# demo:
|
|
88
|
+
# name: "Demo Team"
|
|
89
|
+
# work_dir: ~/path/to/project
|
|
90
|
+
# members:
|
|
91
|
+
# - executor: claude
|
|
92
|
+
# purpose: "Lead — planning & review"
|
|
93
|
+
# - executor: omp
|
|
94
|
+
# purpose: "Implementer"
|
|
65
95
|
|
|
66
96
|
rules:
|
|
67
97
|
paths:
|
|
@@ -73,3 +103,16 @@ workflows:
|
|
|
73
103
|
|
|
74
104
|
redaction:
|
|
75
105
|
enabled: false
|
|
106
|
+
|
|
107
|
+
# ── Planning (design §2.1 / §9) ──
|
|
108
|
+
tasks:
|
|
109
|
+
active: docs/tasks
|
|
110
|
+
folders:
|
|
111
|
+
docs/tasks:
|
|
112
|
+
baseCounter: 0
|
|
113
|
+
label: Core
|
|
114
|
+
# severity:
|
|
115
|
+
# L3.plan-format: off # error | warning | off (known finding codes only)
|
|
116
|
+
|
|
117
|
+
features:
|
|
118
|
+
dir: docs/features
|
|
@@ -37,6 +37,7 @@ All product development work goes through the harness by default.
|
|
|
37
37
|
| Plan a feature (intake → AC → tasks) | `/sp:dev-plan`, `/sp:dev-idea` | Freeform feature files without gates |
|
|
38
38
|
| Drive one task end-to-end | `/sp:dev-run <wbs>` or **`sp:super-coder`** | Implement with no task / no pipeline |
|
|
39
39
|
| Batch or parallel task runs | `/sp:dev-runall`, `/sp:dev-parallel` → **`sp:super-coder`** | Unordered multi-task thrash |
|
|
40
|
+
| Batch-refine tasks under a feature | `/sp:dev-refineall --feature <id> --auto` | Hand-looping `/sp:dev-refine` per WBS |
|
|
40
41
|
| Multi-step corpus CLI (tasks/features/rules/workflows) | **`sp:expert-spur`** | Raw Write/Edit on corpus files |
|
|
41
42
|
| Look up `spur` verbs / flags / `--json` | Skill **`sp:spur-cli`** | Inventing flags from memory |
|
|
42
43
|
| Create/edit/list tasks or features | **`spur task` / `spur feature`** (`--section --from-file`) | Direct-writing task/feature corpus files |
|
|
@@ -65,6 +65,15 @@ states:
|
|
|
65
65
|
- id: done
|
|
66
66
|
description: Terminal — docs deliverable reviewed and recorded.
|
|
67
67
|
onEnter:
|
|
68
|
+
# Done gate requires a PASS verdict artifact (no silent no-artifact allow).
|
|
69
|
+
# Docs-only pipelines do not run /sp:dev-verify; write a docs-only PASS stub
|
|
70
|
+
# then transition. Override path remains: --force-done --reason.
|
|
71
|
+
- kind: shell
|
|
72
|
+
options:
|
|
73
|
+
command: >
|
|
74
|
+
mkdir -p .spur/run &&
|
|
75
|
+
printf '%s\n' "{\"wbs\":\"${vars.wbs}\",\"verdict\":\"PASS\",\"source\":\"docs-pipeline\",\"requirements\":[{\"id\":\"docs-deliverable\",\"status\":\"MET\",\"evidence\":\"docs-pipeline record step\"}],\"acceptanceCriteria\":[],\"checks\":[{\"name\":\"docs-only\",\"status\":\"pass\",\"evidence\":\"docs-pipeline\"}]}"
|
|
76
|
+
> ".spur/run/${vars.wbs}-verdict.json"
|
|
68
77
|
- kind: shell
|
|
69
78
|
options:
|
|
70
79
|
command: "${vars.spurBin} task update ${vars.wbs} done --no-lifecycle"
|
|
@@ -7,18 +7,24 @@
|
|
|
7
7
|
# No state in this pipeline inlines another pipeline's state graph (no-nesting principle,
|
|
8
8
|
# design §System Principles 4).
|
|
9
9
|
#
|
|
10
|
-
# Shape: start -> discovery -> feature-create -> ac-generate -> feature-check
|
|
11
|
-
# -> system-design (conditional: needs_design signal
|
|
10
|
+
# Shape: start -> discovery -> idea-eval -> feature-create -> ac-generate -> feature-check
|
|
11
|
+
# -> system-design (conditional: needs_design signal)
|
|
12
12
|
# -> design-approval (taste HITL gate; not auto-clicked by --auto)
|
|
13
13
|
# -> decompose -> batch-create -> handoff
|
|
14
|
+
# (idea-eval rejection -> cancelled)
|
|
14
15
|
# (feature-check failure routes back to ac-generate; batch-create failure to decompose).
|
|
15
16
|
#
|
|
16
17
|
# Vars (passed as a JSON object via `--vars`):
|
|
17
18
|
# idea — the idea text (required), e.g. --vars '{"idea":"add a --dry-run flag to dev-wrap"}'
|
|
18
19
|
# profile — set --vars '{"profile":"auto"}' to skip objective HITL gates (feature-check, batch-create)
|
|
19
|
-
# design — "auto" (default, signal-driven)
|
|
20
|
-
#
|
|
20
|
+
# design — "auto" (default, signal-driven) or "skip" (--skip-design). No force path.
|
|
21
|
+
# Unified: skip also means omit per-task Design in batch-create (scaffold only;
|
|
22
|
+
# refine fills later). Default: decompose must author batch item `design`.
|
|
23
|
+
# design_approved — "true" when taste pre-cleared (CLI --approve-taste or alias --design-approved);
|
|
21
24
|
# lets profile=auto route around the design-approval taste gate (default "false")
|
|
25
|
+
# idea_approved — "true" when taste pre-cleared (CLI --approve-taste or alias --idea-approved);
|
|
26
|
+
# lets profile=auto route around the idea-eval taste gate (default "false")
|
|
27
|
+
# CLI --approve-taste sets both design_approved and idea_approved to true.
|
|
22
28
|
# spurBin — PATH-independent spur invocation (overridden by CLI at run start)
|
|
23
29
|
# agent — agent for agent.run steps (default: omp)
|
|
24
30
|
#
|
|
@@ -27,9 +33,9 @@
|
|
|
27
33
|
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
28
34
|
kind: state-machine
|
|
29
35
|
name: idea-pipeline
|
|
30
|
-
description: "Idea to feature + AC + task batch: discovery, feature-create, ac-generate, feature-check, system-design, decompose, batch-create, handoff"
|
|
31
|
-
# Worst legal auto path with advertised caps: start/discovery/feature/ac plus 2 AC
|
|
32
|
-
# design, one design rejection, decompose plus 2 batch retries, handoff ≈
|
|
36
|
+
description: "Idea to feature + AC + task batch: discovery, idea-eval, feature-create, ac-generate, feature-check, system-design, decompose, batch-create, handoff"
|
|
37
|
+
# Worst legal auto path with advertised caps: start/discovery/idea-eval/feature/ac plus 2 AC
|
|
38
|
+
# retries, design, one design rejection, decompose plus 2 batch retries, handoff ≈24 transitions.
|
|
33
39
|
# Keep a small cushion so the explicit retry caps fail first, not the engine bound.
|
|
34
40
|
iterationBound: 25
|
|
35
41
|
initialState: start
|
|
@@ -42,9 +48,12 @@ vars:
|
|
|
42
48
|
profile: "standard"
|
|
43
49
|
design: "auto"
|
|
44
50
|
design_approved: "false"
|
|
51
|
+
idea_approved: "false"
|
|
45
52
|
featureId: ""
|
|
46
53
|
__hitlAnswer: ""
|
|
47
54
|
spurBin: "spur"
|
|
55
|
+
# R8 (0366): injected by WorkflowAppService.run(); stamps discovery artifact provenance.
|
|
56
|
+
__runId: ""
|
|
48
57
|
agent: "omp"
|
|
49
58
|
stepTimeoutMs: "600000"
|
|
50
59
|
|
|
@@ -62,7 +71,7 @@ states:
|
|
|
62
71
|
command: "${vars.spurBin} agent doctor ${vars.agent}"
|
|
63
72
|
- kind: shell
|
|
64
73
|
options:
|
|
65
|
-
command: 'mkdir -p .spur/run && rm -f .spur/run/idea-ac-retry-count .spur/run/idea-decompose-retry-count .spur/run/idea-feature-id.txt .spur/run/idea-ac-content.md .spur/run/idea-ac-done.txt .spur/run/idea-task-batch.json .spur/run/idea-batch-create.done .spur/run/idea-batch-create.failed'
|
|
74
|
+
command: 'mkdir -p .spur/run && { [ -f .spur/run/idea-eval-report.md ] || [ -f .spur/run/idea-needs-design.json ]; } && { a=".spur/run/idea-archive/$(date +%Y%m%d-%H%M%S)"; mkdir -p "$a"; mv -f .spur/run/idea-eval-report.md "$a/" 2>/dev/null; mv -f .spur/run/idea-needs-design.json "$a/" 2>/dev/null; } ; rm -f .spur/run/idea-ac-retry-count .spur/run/idea-decompose-retry-count .spur/run/idea-feature-id.txt .spur/run/idea-ac-content.md .spur/run/idea-ac-done.txt .spur/run/idea-task-batch.json .spur/run/idea-batch-create.done .spur/run/idea-batch-create.failed'
|
|
66
75
|
|
|
67
76
|
- id: discovery
|
|
68
77
|
description: >
|
|
@@ -70,24 +79,41 @@ states:
|
|
|
70
79
|
and record a design summary. The brainstorm ALWAYS records a design summary
|
|
71
80
|
("nothing is too simple" pattern). The brainstorm also emits a needs_design
|
|
72
81
|
boolean signal written to .spur/run/idea-needs-design.json — this determines
|
|
73
|
-
whether the system-design state runs.
|
|
82
|
+
whether the system-design state runs. As its terminal artifact for the idea path,
|
|
83
|
+
brainstorm also emits the idea-evaluation report to .spur/run/idea-eval-report.md
|
|
84
|
+
(template: plugins/sp/skills/spur-dev/references/idea-evaluation.md).
|
|
74
85
|
onEnter:
|
|
75
86
|
- kind: agent.run
|
|
76
87
|
options:
|
|
77
88
|
agent: ${vars.agent}
|
|
78
|
-
input: "Run sp:brainstorm for the idea: ${vars.idea}. The skill owns the approach-generation, design summary, and `needs_design` signal criteria; emit .spur/run/idea-needs-design.json ({\"needs_design\": true|false}) and the design summary per the skill's `Design Approval Gate` and `The needs_design signal` sections."
|
|
89
|
+
input: "Run sp:brainstorm for the idea: ${vars.idea}. The skill owns the approach-generation, design summary, and `needs_design` signal criteria; emit .spur/run/idea-needs-design.json ({\"needs_design\": true|false}) and the design summary per the skill's `Design Approval Gate` and `The needs_design signal` sections. Also emit the idea-evaluation report to .spur/run/idea-eval-report.md per plugins/sp/skills/spur-dev/references/idea-evaluation.md (urgency/necessity 0–5, premises, pros/cons, alternatives, enhanced idea, recommendation). At the END of the report, append a provenance footer block of the exact form: `---\\nrun_id: ${vars.__runId}\\ngenerated_at: <RFC3339 timestamp>\\n---` (omit the footer only if run_id is empty)."
|
|
79
90
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
80
91
|
|
|
92
|
+
- id: idea-eval
|
|
93
|
+
description: >
|
|
94
|
+
HITL taste gate. Discovery has produced the idea-evaluation report
|
|
95
|
+
(.spur/run/idea-eval-report.md) with urgency/necessity scores, premises,
|
|
96
|
+
pros/cons, and a recommendation. The operator reviews and approves or
|
|
97
|
+
rejects. This gate is NOT auto-clicked by --auto (taste gate, like
|
|
98
|
+
design-approval). Only routes around when vars.idea_approved=true
|
|
99
|
+
(explicit prior approval).
|
|
100
|
+
pause: true
|
|
101
|
+
onEnter:
|
|
102
|
+
- kind: hitl.confirm
|
|
103
|
+
options:
|
|
104
|
+
prompt: "Review the idea evaluation report (.spur/run/idea-eval-report.md). Approve to create a feature, or reject to cancel? (Reject creates no feature.)"
|
|
105
|
+
|
|
81
106
|
- id: feature-create
|
|
82
107
|
description: >
|
|
83
108
|
Create a feature via spur feature create, or select an existing feature id.
|
|
84
109
|
The agent writes the feature id to .spur/run/idea-feature-id.txt for subsequent
|
|
85
|
-
states to read.
|
|
110
|
+
states to read. Prefer the enhanced idea from .spur/run/idea-eval-report.md as
|
|
111
|
+
context; do not overwrite vars.idea.
|
|
86
112
|
onEnter:
|
|
87
113
|
- kind: agent.run
|
|
88
114
|
options:
|
|
89
115
|
agent: ${vars.agent}
|
|
90
|
-
input: "Create a feature for the idea: ${vars.idea}. Use 'spur feature create \"<name>\" --json' to create it. Write the feature id to .spur/run/idea-feature-id.txt. If an existing feature is appropriate, use its id instead."
|
|
116
|
+
input: "Create a feature for the idea: ${vars.idea}. Read .spur/run/idea-eval-report.md if present for the enhanced idea and scores. Use 'spur feature create \"<name>\" --json' to create it. Write the feature id to .spur/run/idea-feature-id.txt. If an existing feature is appropriate, use its id instead."
|
|
91
117
|
expectFile: .spur/run/idea-feature-id.txt
|
|
92
118
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
93
119
|
- kind: file.read.into-var
|
|
@@ -138,7 +164,7 @@ states:
|
|
|
138
164
|
- id: system-design
|
|
139
165
|
description: >
|
|
140
166
|
Dispatch sp:sys-architecture to produce the system design. This state runs
|
|
141
|
-
only when needs_design=true (
|
|
167
|
+
only when needs_design=true (design=auto signal path). The agent creates ADR
|
|
142
168
|
entries, architecture updates, and design satellites through constitution rules.
|
|
143
169
|
The design-approval state follows (taste gate).
|
|
144
170
|
onEnter:
|
|
@@ -230,13 +256,47 @@ transitions:
|
|
|
230
256
|
guard:
|
|
231
257
|
kind: always
|
|
232
258
|
|
|
233
|
-
# ── discovery
|
|
259
|
+
# ── discovery: auto-skip (profile=auto + idea_approved) OR enter idea-eval taste gate ──
|
|
260
|
+
# Declaration order: auto-skip FIRST (same pattern as system-design → design-approval).
|
|
261
|
+
# Without this edge, discovery always enters idea-eval (pause: true), rendering the prompt
|
|
262
|
+
# and persisting an avoidable pause before the in-state auto-skip guard can fire (0366 R4/R5).
|
|
234
263
|
- from: discovery
|
|
235
264
|
to: feature-create
|
|
236
|
-
description:
|
|
265
|
+
description: profile=auto AND idea_approved=true — skip idea-eval taste gate entirely.
|
|
266
|
+
guard:
|
|
267
|
+
kind: shell
|
|
268
|
+
options:
|
|
269
|
+
command: 'test "${vars.profile}" = auto && test "${vars.idea_approved}" = true'
|
|
270
|
+
- from: discovery
|
|
271
|
+
to: idea-eval
|
|
272
|
+
description: Discovery complete — gate on idea evaluation taste decision.
|
|
237
273
|
guard:
|
|
238
274
|
kind: always
|
|
239
275
|
|
|
276
|
+
# ── idea-eval: auto-skip (profile=auto + idea_approved) OR approve/reject HITL ──
|
|
277
|
+
# Declaration order: auto-skip FIRST (same pattern as system-design → design-approval).
|
|
278
|
+
- from: idea-eval
|
|
279
|
+
to: feature-create
|
|
280
|
+
description: profile=auto AND idea_approved=true — skip idea-eval taste gate.
|
|
281
|
+
guard:
|
|
282
|
+
kind: shell
|
|
283
|
+
options:
|
|
284
|
+
command: 'test "${vars.profile}" = auto && test "${vars.idea_approved}" = true'
|
|
285
|
+
- from: idea-eval
|
|
286
|
+
to: feature-create
|
|
287
|
+
description: Idea evaluation approved — create or select a feature.
|
|
288
|
+
guard:
|
|
289
|
+
kind: shell
|
|
290
|
+
options:
|
|
291
|
+
command: 'test "${vars.__hitlAnswer}" = yes'
|
|
292
|
+
- from: idea-eval
|
|
293
|
+
to: cancelled
|
|
294
|
+
description: Idea evaluation rejected or cancelled — no feature created.
|
|
295
|
+
guard:
|
|
296
|
+
kind: shell
|
|
297
|
+
options:
|
|
298
|
+
command: 'test "${vars.__hitlAnswer}" = no || test "${vars.__hitlAnswer}" = cancel'
|
|
299
|
+
|
|
240
300
|
# ── feature-create -> ac-generate ──
|
|
241
301
|
- from: feature-create
|
|
242
302
|
to: ac-generate
|
|
@@ -250,14 +310,14 @@ transitions:
|
|
|
250
310
|
# routes directly to the appropriate next state. Under interactive, the always fallback enters
|
|
251
311
|
# the feature-check state whose onEnter hitl.confirm pauses for operator confirmation.
|
|
252
312
|
#
|
|
253
|
-
# Auto-skip 1: pass + design route → system-design
|
|
313
|
+
# Auto-skip 1: pass + design route → system-design (design=auto + needs_design != false)
|
|
254
314
|
- from: ac-generate
|
|
255
315
|
to: system-design
|
|
256
316
|
description: "profile=auto, check passed, design route — run system design."
|
|
257
317
|
guard:
|
|
258
318
|
kind: shell
|
|
259
319
|
options:
|
|
260
|
-
command: 'test "${vars.profile}" = auto && ${vars.spurBin} feature check ${vars.featureId} --strict &&
|
|
320
|
+
command: 'test "${vars.profile}" = auto && ${vars.spurBin} feature check ${vars.featureId} --strict && test "${vars.design}" = auto && test "$(jq -r .needs_design .spur/run/idea-needs-design.json 2>/dev/null)" != false'
|
|
261
321
|
# Auto-skip 2: pass + skip-design route → decompose
|
|
262
322
|
- from: ac-generate
|
|
263
323
|
to: decompose
|
|
@@ -297,7 +357,7 @@ transitions:
|
|
|
297
357
|
guard:
|
|
298
358
|
kind: shell
|
|
299
359
|
options:
|
|
300
|
-
command: 'test "${vars.__hitlAnswer}" = yes && ${vars.spurBin} feature check ${vars.featureId} --strict &&
|
|
360
|
+
command: 'test "${vars.__hitlAnswer}" = yes && ${vars.spurBin} feature check ${vars.featureId} --strict && test "${vars.design}" = auto && test "$(jq -r .needs_design .spur/run/idea-needs-design.json 2>/dev/null)" != false'
|
|
301
361
|
- from: feature-check
|
|
302
362
|
to: decompose
|
|
303
363
|
description: Feature check passed, skip-design route — go directly to decompose.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.25",
|
|
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",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@commander-js/extra-typings": "^14.0.0",
|
|
53
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
54
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
55
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
56
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
57
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
53
|
+
"@gobing-ai/ts-db": "^0.4.14",
|
|
54
|
+
"@gobing-ai/ts-ai-runner": "^0.4.14",
|
|
55
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.14",
|
|
56
|
+
"@gobing-ai/ts-infra": "^0.4.14",
|
|
57
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.14",
|
|
58
|
+
"@gobing-ai/ts-rule-engine": "^0.4.14",
|
|
59
|
+
"@gobing-ai/ts-runtime": "^0.4.14",
|
|
60
|
+
"@gobing-ai/ts-utils": "^0.4.14",
|
|
61
61
|
"@types/bun": "1.3.14",
|
|
62
62
|
"@types/figlet": "^1.7.0",
|
|
63
63
|
"@types/node-notifier": "8.0.5",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"version": {
|
|
14
14
|
"type": "string",
|
|
15
|
-
"description": "Config schema version.
|
|
15
|
+
"description": "Config schema version (string, not integer). Current recommended: '1.1' (ADR-033 executor tiers + planning blocks). '1' remains accepted for backward compatibility."
|
|
16
16
|
},
|
|
17
17
|
"name": {
|
|
18
18
|
"type": "string",
|
|
@@ -129,15 +129,15 @@
|
|
|
129
129
|
},
|
|
130
130
|
"tier": {
|
|
131
131
|
"type": "string",
|
|
132
|
-
"enum": ["cheap", "standard", "capable"],
|
|
133
|
-
"description": "Capability tier for stage-registry adaptive model routing (ADR-033). A stage starts on the cheapest eligible executor meeting its model_policy min_tier
|
|
132
|
+
"enum": ["cheap", "standard", "capable-1", "capable-2", "capable-3"],
|
|
133
|
+
"description": "Capability tier for stage-registry adaptive model routing (ADR-033, 0343). Live values: cheap | standard | capable-1 | capable-2 | capable-3 (1=low output quality, 3=high within the capable band). A stage starts on the cheapest eligible executor meeting its model_policy min_tier. Bare legacy `capable` is accepted at runtime (zod preprocess → capable-1) during the deprecation window but is not part of this editor enum."
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
},
|
|
138
138
|
"default-by-phase": {
|
|
139
139
|
"type": "object",
|
|
140
|
-
"description": "
|
|
140
|
+
"description": "DEPRECATED (ADR-033). Backward-compat map of dev phase (e.g. dev-run, dev-review) to executor selector. Prefer executor `tier` + stage-registry model_policy. When present, a matching phase mapping is still authoritative (fail-fast; no fall back to `default`) and shadows stage routing for that phase.",
|
|
141
141
|
"additionalProperties": {
|
|
142
142
|
"type": "string"
|
|
143
143
|
}
|
|
@@ -22,6 +22,18 @@
|
|
|
22
22
|
"type": "string",
|
|
23
23
|
"description": "R-numbered requirement items (R1. R2. …) — a referenceable list."
|
|
24
24
|
},
|
|
25
|
+
"design": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Pre-filled ### Design body (WHAT/WHY decision record). Default for plan/decompose unless --skip-design."
|
|
28
|
+
},
|
|
29
|
+
"plan": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Pre-filled ### Plan body (ordered checklist)."
|
|
32
|
+
},
|
|
33
|
+
"acceptance_criteria": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Pre-filled ### Acceptance Criteria body (Gherkin or checklist)."
|
|
36
|
+
},
|
|
25
37
|
"feature_id": {
|
|
26
38
|
"type": "string",
|
|
27
39
|
"pattern": "^[A-Z][1-9]*$",
|