@benjaminthomas/spec-driven-dev 1.7.0 → 1.8.0
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/README.md
CHANGED
|
@@ -97,14 +97,26 @@ words in quotes.
|
|
|
97
97
|
**deep**, based on how much it touches and how risky it is (data, security, concurrency, public
|
|
98
98
|
contracts, unclear requirements). `spec-implement` then runs each task on the model for its tier:
|
|
99
99
|
|
|
100
|
-
| Tier | Typical task | Claude Code
|
|
101
|
-
|
|
102
|
-
| light | copy change, config value, small UI tweak following an existing pattern | `haiku` |
|
|
103
|
-
| standard | a normal feature slice: route + service + tests | `sonnet` |
|
|
104
|
-
| deep | migrations with backfills, auth/permissions, concurrency, cross-repo contracts | `opus` |
|
|
100
|
+
| Tier | Typical task | Claude Code | Codex CLI | Effort |
|
|
101
|
+
|---|---|---|---|---|
|
|
102
|
+
| light | copy change, config value, small UI tweak following an existing pattern | `haiku` | `gpt-6-luna` | low |
|
|
103
|
+
| standard | a normal feature slice: route + service + tests | `sonnet` | `gpt-6.1-sol` | medium |
|
|
104
|
+
| deep | migrations with backfills, auth/permissions, concurrency, cross-repo contracts | `opus` | `gpt-6.1-sol` | high |
|
|
105
|
+
| escalate | a deep task that still fails after a fix round | `fable` (asks first, as it may use usage credits) | (session model) | xhigh |
|
|
105
106
|
|
|
106
107
|
- **Reviews:** each batch's review runs on at least `standard`, and on the batch's highest tier.
|
|
107
|
-
- **Escalation:** a task that still fails after a fix round is retried one tier up.
|
|
108
|
+
- **Escalation:** a task that still fails after a fix round is retried one tier up. A deep task
|
|
109
|
+
that still fails goes to the `escalate` model.
|
|
110
|
+
- **Fallback:** if a model isn't available on your plan or provider, that task runs on your current
|
|
111
|
+
model and the report says so.
|
|
112
|
+
- **Where the defaults come from:** they were checked on 2026-11-06 against
|
|
113
|
+
[Claude Code's model docs](https://code.claude.com/docs/en/model-config) (on Bedrock, Google Cloud,
|
|
114
|
+
and Foundry, `sonnet`/`haiku` point to older versions),
|
|
115
|
+
[Anthropic's model overview](https://platform.claude.com/docs/en/about-claude/models/overview),
|
|
116
|
+
[Codex's config docs](https://developers.openai.com/codex/config-basic), and
|
|
117
|
+
[Cursor's model list](https://cursor.com/help/models-and-usage/available-models). Claude Code
|
|
118
|
+
uses family aliases, which always point to the newest model. Cursor's models depend on your plan,
|
|
119
|
+
so it uses your current model until you fill in the models you can see in its picker.
|
|
108
120
|
- **Tools that run one model per session** (Cursor, Codex) don't switch silently. Before a heavier
|
|
109
121
|
batch, they pause and tell you which model to switch to.
|
|
110
122
|
- **Changing the models:** edit the `models:` section of `.spec-driven.yml`, for example to use a
|
|
@@ -156,7 +168,7 @@ straight away, so you can fix it before moving on. Press Enter on an empty line
|
|
|
156
168
|
| Lint / typecheck / test / build / dev commands | `package.json` scripts and lockfile (per repo or package) | `pnpm run lint` |
|
|
157
169
|
| Where specs go | (you choose) | `specs/` |
|
|
158
170
|
| After you approve a spec | (you choose) | `stop` (wait at each stage) or `run-through` |
|
|
159
|
-
| Model per task tier | written with defaults
|
|
171
|
+
| Model and effort per task tier | written with the defaults above | edit `models:` / `effort:` later |
|
|
160
172
|
|
|
161
173
|
**Where the file lives, by layout:**
|
|
162
174
|
|
|
@@ -563,12 +575,12 @@ skips that step rather than failing.
|
|
|
563
575
|
| `spec-setup` | 0 · configure | 117 | 1,068 | 1 |
|
|
564
576
|
| `spec-investigate` | 1 · understand | 330 | 2,794 | 1 |
|
|
565
577
|
| `spec-create` | 2 · plan | 166 | 1,503 | 5 |
|
|
566
|
-
| `spec-implement` | 3 · build |
|
|
578
|
+
| `spec-implement` | 3 · build | 303 | 2,458 | 3 |
|
|
567
579
|
| `spec-verify` | 4 · prove | 155 | 1,492 | 1 |
|
|
568
580
|
| `spec-checkpoint` | 5 · commit | 108 | 795 | 0 |
|
|
569
581
|
| `spec-ship` | 6 · PR | 220 | 1,268 | 0 |
|
|
570
582
|
| `generative-seo` | standalone | 255 | 2,209 | 7 |
|
|
571
|
-
| **Total** | | **1,
|
|
583
|
+
| **Total** | | **1,654** | **13,587** | **18** |
|
|
572
584
|
|
|
573
585
|
- **8** skills: **1** setup + **6** workflow stages + **1** standalone
|
|
574
586
|
- **4** tools supported natively (Claude Code, Codex CLI, Cursor, Antigravity), plus an MCP fallback
|
package/bin/cli.mjs
CHANGED
|
@@ -235,22 +235,30 @@ function toYaml(c) {
|
|
|
235
235
|
out += `tracker:\n type: ${c.tracker.type}\n key: ${y(c.tracker.key)}\n url: ${y(c.tracker.url)}\n`;
|
|
236
236
|
out += `git:\n${cmds(c.git, " ")}\n`;
|
|
237
237
|
out += `commands:\n${cmds(c.commands, " ")}\n dev_url: ${y(c.devUrl)}\n`;
|
|
238
|
-
out += "models: # model per task tier
|
|
239
|
-
.map(([tool, m]) => ` ${tool}:\n` +
|
|
238
|
+
out += "models: # model per task tier; \"default\" = the session's model; escalate = last resort for repeat failures\n" + Object.entries(MODEL_DEFAULTS)
|
|
239
|
+
.map(([tool, m]) => ` ${tool}:\n` + MODEL_KEYS.map((t) => ` ${t}: ${m[t]}\n`).join("")).join("");
|
|
240
|
+
out += "effort: # effort / reasoning level per tier (Claude Code, Codex): low | medium | high | xhigh | max | default\n"
|
|
241
|
+
+ MODEL_KEYS.map((t) => ` ${t}: ${EFFORT_DEFAULTS[t]}\n`).join("");
|
|
240
242
|
out += `pipeline:\n after_approval: ${c.afterApproval || "stop"} # stop | run-through (implement → verify → checkpoint; ship always asks)\n`;
|
|
241
243
|
return out + `specs_dir: ${y(c.specsDir)}\n`;
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
const LAYOUTS = ["single", "monorepo", "multi-repo"];
|
|
245
247
|
const TIERS = ["light", "standard", "deep"];
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
const MODEL_KEYS = [...TIERS, "escalate"]; // escalate: optional last resort when a deep task keeps failing
|
|
249
|
+
const EFFORTS = ["low", "medium", "high", "xhigh", "max", "default"];
|
|
250
|
+
// Checked against the vendors' docs on 2026-11-06 (Claude Code model-config, OpenAI Codex config,
|
|
251
|
+
// Cursor models page). Claude Code aliases track the newest model per family on your provider.
|
|
252
|
+
// Cursor's models depend on your plan, so it defaults to the session's model.
|
|
253
|
+
// shortcut: model names go stale; refresh these defaults (and the README table) when vendors ship new lines.
|
|
248
254
|
const MODEL_DEFAULTS = {
|
|
249
|
-
claude: { light: "haiku", standard: "sonnet", deep: "opus" },
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
antigravity: { light: "default", standard: "default", deep: "default" },
|
|
255
|
+
claude: { light: "haiku", standard: "sonnet", deep: "opus", escalate: "fable" },
|
|
256
|
+
codex: { light: "gpt-6-luna", standard: "gpt-6.1-sol", deep: "gpt-6.1-sol", escalate: "default" },
|
|
257
|
+
cursor: { light: "default", standard: "default", deep: "default", escalate: "default" },
|
|
258
|
+
antigravity: { light: "default", standard: "default", deep: "default", escalate: "default" },
|
|
253
259
|
};
|
|
260
|
+
// Effort / reasoning level per tier, for tools that support it (Claude Code, Codex).
|
|
261
|
+
const EFFORT_DEFAULTS = { light: "low", standard: "medium", deep: "high", escalate: "xhigh" };
|
|
254
262
|
const splitList = (v) => (v || "").split(",").map((x) => x.trim()).filter(Boolean);
|
|
255
263
|
// Paths are stored relative to the config's folder when inside it, absolute otherwise.
|
|
256
264
|
const real = (p) => { try { return fs.realpathSync(p); } catch { return p; } }; // /var vs /private/var etc.
|
|
@@ -514,7 +522,11 @@ function doctor() {
|
|
|
514
522
|
for (const [tool, m] of Object.entries(c.models || {})) {
|
|
515
523
|
if (typeof m !== "object") { problems.push(`models.${tool} must list light / standard / deep`); continue; }
|
|
516
524
|
for (const t of TIERS) if (!m[t]) problems.push(`models.${tool}.${t} is missing (use "default" for the session's model)`);
|
|
517
|
-
for (const k of Object.keys(m)) if (!
|
|
525
|
+
for (const k of Object.keys(m)) if (!MODEL_KEYS.includes(k)) problems.push(`models.${tool}.${k}: unknown tier (use light, standard, deep, escalate)`);
|
|
526
|
+
}
|
|
527
|
+
for (const [k, v] of Object.entries(c.effort || {})) {
|
|
528
|
+
if (!MODEL_KEYS.includes(k)) problems.push(`effort.${k}: unknown tier (use light, standard, deep, escalate)`);
|
|
529
|
+
else if (!EFFORTS.includes(v)) problems.push(`effort.${k} "${v}" must be one of ${EFFORTS.join(", ")}`);
|
|
518
530
|
}
|
|
519
531
|
if (c.pipeline?.after_approval && !["stop", "run-through"].includes(c.pipeline.after_approval)) problems.push(`pipeline.after_approval "${c.pipeline.after_approval}" must be stop or run-through`);
|
|
520
532
|
if (c.git?.branch_name && !/\{(ticket|slug)\}/.test(c.git.branch_name)) problems.push(`git.branch_name "${c.git.branch_name}" needs {ticket} or {slug}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@benjaminthomas/spec-driven-dev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Spec-driven AI development workflow (investigate → spec → implement → verify → ship) as Agent Skills for Claude Code, Cursor, Codex CLI and Antigravity.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -108,14 +108,17 @@ Read `references/coder-prompt-template.md` and construct each agent's prompt by
|
|
|
108
108
|
|
|
109
109
|
The coder agents should NOT commit their changes — the orchestrator handles commits after review.
|
|
110
110
|
|
|
111
|
-
**Pick each coder's model from the task's tier.** Read the task's `## Complexity` tier
|
|
112
|
-
missing tier as `standard`)
|
|
113
|
-
where `<tool>` is the host you're running in (`claude`, `codex`, `cursor`,
|
|
114
|
-
`
|
|
115
|
-
`deep → opus
|
|
116
|
-
|
|
117
|
-
- **Host can set a model per agent** (e.g. Claude Code's Agent tool `model`
|
|
118
|
-
each coder with its tier's model.
|
|
111
|
+
**Pick each coder's model and effort from the task's tier.** Read the task's `## Complexity` tier
|
|
112
|
+
(treat a missing tier as `standard`), then look up `.spec-driven.yml` → `models.<tool>.<tier>` and
|
|
113
|
+
`effort.<tier>`, where `<tool>` is the host you're running in (`claude`, `codex`, `cursor`,
|
|
114
|
+
`antigravity`). Without those sections, use these defaults: Claude Code `light → haiku/low`,
|
|
115
|
+
`standard → sonnet/medium`, `deep → opus/high`; other hosts use the session's model.
|
|
116
|
+
|
|
117
|
+
- **Host can set a model per agent** (e.g. Claude Code's Agent tool `model` and `effort`
|
|
118
|
+
parameters): dispatch each coder with its tier's model and effort.
|
|
119
|
+
- **Model not available** (not on your plan or provider, or rejected by the host): fall back to the
|
|
120
|
+
session's model, say which task fell back and why, and suggest fixing `models:`. Don't stop the
|
|
121
|
+
batch for this.
|
|
119
122
|
- **Host can't** (one model per session, as in Cursor or Codex): don't silently run deep tasks on a
|
|
120
123
|
light model. Before dispatching a batch, compare its highest tier with the model you're running
|
|
121
124
|
on. If the batch needs a stronger one, stop and say:
|
|
@@ -183,8 +186,10 @@ If the review returns **FAIL**:
|
|
|
183
186
|
- **{task_content}**: the original task file for context
|
|
184
187
|
4. After fix agents complete, re-run the review (Step 6)
|
|
185
188
|
5. **Escalate on repeat failure.** If a task's issues survive a fix cycle, run its next fix one tier
|
|
186
|
-
higher (`light → standard → deep`).
|
|
187
|
-
|
|
189
|
+
higher (`light → standard → deep`). A `deep` task that still fails goes to `models.<tool>.escalate`
|
|
190
|
+
(e.g. `fable`) at `effort.escalate`, if it's set and not `default`. Ask first if that model can
|
|
191
|
+
bill to usage credits, as Fable can on some plans. Note every escalation in the batch report:
|
|
192
|
+
a task that needed escalating was probably under-rated, which is useful feedback for future specs.
|
|
188
193
|
|
|
189
194
|
**Cap at 3 review cycles per batch.** If the third review still fails, stop and report to the user:
|
|
190
195
|
|
|
@@ -51,7 +51,7 @@ Copy this structure into `specs/{feature-slug}/investigation.md`.
|
|
|
51
51
|
## Complexity Estimate
|
|
52
52
|
- Overall tier: (light / standard / deep): the tier of the hardest part of the work
|
|
53
53
|
- Signals: (which of spread, new design, data, concurrency, security, public contract, ambiguity, hard to verify apply, each with its evidence)
|
|
54
|
-
- Suggested model for planning this: (
|
|
54
|
+
- Suggested model for planning this: (`models.<tool>.deep` at `effort.deep` if the tier is deep, or the `escalate` model for very ambiguous, long-horizon work; otherwise the session's model is fine)
|
|
55
55
|
|
|
56
56
|
## Recommended Implementation Direction
|
|
57
57
|
## References
|
|
@@ -44,25 +44,36 @@ commands:
|
|
|
44
44
|
|
|
45
45
|
# Which model runs each task tier (spec-create rates every task light / standard / deep).
|
|
46
46
|
# Values are whatever your tool accepts; "default" means "whatever model the session is using".
|
|
47
|
-
#
|
|
48
|
-
#
|
|
47
|
+
# escalate = optional last resort when a deep task still fails review after a fix round.
|
|
48
|
+
# Defaults checked against vendor docs on 2026-11-06 — refresh when vendors ship new models.
|
|
49
49
|
models:
|
|
50
|
-
claude:
|
|
50
|
+
claude: # Claude Code aliases follow the newest model per family on your provider
|
|
51
51
|
light: haiku
|
|
52
52
|
standard: sonnet
|
|
53
53
|
deep: opus
|
|
54
|
-
|
|
55
|
-
light: default
|
|
56
|
-
standard: default
|
|
57
|
-
deep: default
|
|
54
|
+
escalate: fable # Fable: hardest/long-running work; may bill to usage credits on some plans
|
|
58
55
|
codex:
|
|
56
|
+
light: gpt-6-luna
|
|
57
|
+
standard: gpt-6.1-sol
|
|
58
|
+
deep: gpt-6.1-sol # same model, higher reasoning effort (see effort:)
|
|
59
|
+
escalate: default
|
|
60
|
+
cursor: # depends on your Cursor plan; set models you can see in the model picker
|
|
59
61
|
light: default
|
|
60
62
|
standard: default
|
|
61
63
|
deep: default
|
|
64
|
+
escalate: default
|
|
62
65
|
antigravity:
|
|
63
66
|
light: default
|
|
64
67
|
standard: default
|
|
65
68
|
deep: default
|
|
69
|
+
escalate: default
|
|
70
|
+
|
|
71
|
+
# Effort / reasoning level per tier, for tools that support it (Claude Code, Codex).
|
|
72
|
+
effort:
|
|
73
|
+
light: low
|
|
74
|
+
standard: medium
|
|
75
|
+
deep: high
|
|
76
|
+
escalate: xhigh
|
|
66
77
|
|
|
67
78
|
pipeline:
|
|
68
79
|
# stop — every stage waits for you (default)
|