@benjaminthomas/spec-driven-dev 1.11.1 → 1.11.2

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
@@ -63,9 +63,11 @@ start a new session and continue where you left off.
63
63
  npx @benjaminthomas/spec-driven-dev@latest
64
64
  ```
65
65
 
66
- This one command downloads the tool, installs the skills, and sets up the project. It asks its
67
- questions in your terminal, so run it in a real terminal, not through another tool. If there's no
68
- terminal to answer in, it says so and uses the detected values.
66
+ This one command downloads the tool, installs the skills, and sets up the project. In a terminal
67
+ window it asks its setup questions there. Run it with `!` inside Claude Code (or any other place
68
+ without a terminal to answer in) and it installs the skills for the AI tools it finds, then tells
69
+ you to say **"run spec-setup"**, which asks the same questions in the chat. It never writes the
70
+ settings file from guesses.
69
71
 
70
72
  > **Why not `npm install -g`?** npm doesn't let a package ask questions while it installs, and an
71
73
  > install doesn't know which project it's for. That's why setup is a separate step you run inside
@@ -579,8 +581,9 @@ STP-123" or "ship it" picks the right skill.
579
581
  Update to 1.5.1 or later (`npx @benjaminthomas/spec-driven-dev@latest --version`). Earlier versions
580
582
  crashed on Node 14 or 16, which nvm often switches to inside older projects, and wrote a config
581
583
  silently when there was no terminal. Now it runs on Node 14+. With no terminal to answer in (a `!`
582
- command in Claude Code, an editor task, piped input), it stops, changes nothing, and tells you to run
583
- it in a terminal window or pass flags such as `--layout=multi-repo --repos=…`.
584
+ command in Claude Code, an editor task, piped input), it installs the skills and hands the questions
585
+ to your AI tool: say "run spec-setup" there. `spec-driven-dev setup` on its own still needs a
586
+ terminal, or flags such as `--layout=multi-repo --repos=…`.
584
587
 
585
588
  **Setup didn't ask me about repos.**
586
589
  It only asks about repos for a multi-repo or monorepo layout. If it detected `single`, type
@@ -802,7 +805,7 @@ plugin/evals/ `claude plugin eval` cases
802
805
  1. Increase `version` in both `package.json` and `plugin/.claude-plugin/plugin.json` (the check fails if
803
806
  they differ).
804
807
  2. Add a `CHANGELOG.md` entry, then commit and push.
805
- 3. Tag the release and push the tag: `git tag v1.11.1 && git push origin v1.11.1`.
808
+ 3. Tag the release and push the tag: `git tag v1.11.2 && git push origin v1.11.2`.
806
809
  4. Watch the **publish** run in the repo's Actions tab. When it's green, the new version is on
807
810
  npm. Claude Code plugin users get it from the marketplace once the commit is on `main`.
808
811
 
package/bin/cli.mjs CHANGED
@@ -48,13 +48,19 @@ if (flag("version") || flag("v")) {
48
48
  // No terminal to answer in (e.g. `!` in Claude Code, an IDE task, a pipe) and nothing passed explicitly:
49
49
  // stop rather than write a config from guesses.
50
50
  const ANSWER_FLAGS = ["risk", "yes", "y", "layout", "repos", "packages", "tools", "workspace", "after-approval", "skills", "global", "no-setup", "project"];
51
- if (["install", "setup", "settings"].includes(command) && !process.stdin.isTTY && !args.some((a) => ANSWER_FLAGS.some((f) => a === `--${f}` || a.startsWith(`--${f}=`)))) {
51
+ const NO_TTY = !process.stdin.isTTY && !args.some((a) => ANSWER_FLAGS.some((f) => a === `--${f}` || a.startsWith(`--${f}=`)));
52
+ // Installing the skills needs no answers, so the default command still does that without a terminal
53
+ // (e.g. `!` in Claude Code) and hands the questions to the spec-setup skill, which asks them in the chat.
54
+ const HANDOFF = command === "install" && NO_TTY;
55
+ if (["setup", "settings"].includes(command) && NO_TTY) {
52
56
  console.log(`✗ No interactive terminal, so ${command === "settings" ? "the settings menu can't open" : "setup can't ask its questions"}. Nothing was changed.
53
57
 
54
58
  This happens when it runs through another program: a "!" command in Claude Code, an editor task,
55
59
  or piped input. Either:
56
60
  • run it yourself in a terminal window (Terminal, iTerm, or your editor's terminal panel):
57
- npx @benjaminthomas/spec-driven-dev@latest ${command === "install" ? "" : command}
61
+ npx @benjaminthomas/spec-driven-dev@latest ${command}${command === "setup" ? `
62
+ • or, in your AI tool (Claude Code, Cursor, Codex), say "run spec-setup": it asks the same
63
+ questions in the chat` : ""}
58
64
  • or give the answers as flags, for example:
59
65
  npx @benjaminthomas/spec-driven-dev@latest ${command === "settings" ? "settings --risk=off" : "setup --layout=multi-repo --repos=~/Projects/frontend,~/Projects/backend"}
60
66
  (add --yes to accept everything it detects)`);
@@ -137,7 +143,8 @@ async function install() {
137
143
  }
138
144
  console.log(`✓ ${skills.length} skills → ${dest}`);
139
145
  }
140
- if (!dests.length) console.log("• No tools selected — nothing installed.");
146
+ if (!dests.length) console.log(HANDOFF ? "• No AI coding tools found (Claude Code, Cursor, Codex or Antigravity). Install one, or pass --tools=claude,cursor." : "• No tools selected — nothing installed.");
147
+ return dests.length;
141
148
  }
142
149
 
143
150
  // ---------- discovery ----------
@@ -788,12 +795,20 @@ try {
788
795
  else if (command === "risk") risk();
789
796
  else if (command === "settings") await settings();
790
797
  else if (command === "risk-eval") await riskEvalCmd();
791
- else if (command === "install") {
798
+ else if (command === "install" && HANDOFF) {
799
+ console.log("No interactive terminal (for example a \"!\" command in Claude Code), so this installs the skills\nwith the detected defaults and leaves the setup questions to your AI tool.\n");
800
+ const n = await install();
801
+ if (n) console.log(`
802
+ Next: in your AI tool, say "run spec-setup". It asks the setup questions in the chat
803
+ (single repo, monorepo or multi-repo, tracker, branches) and writes .spec-driven.yml.
804
+ If your AI tool doesn't recognise it yet, start a new session so it loads the new skills.
805
+ To answer in a terminal instead, open Terminal or iTerm and run: npx @benjaminthomas/spec-driven-dev setup`);
806
+ } else if (command === "install") {
792
807
  await install();
793
808
  if (!flag("no-setup") && (await askConfirm("Set up this project now?", true))) await setup();
794
809
  } else if (command === "setup") await setup();
795
810
  else throw new Error(`Unknown command "${command}" — use install (default), setup, settings, doctor, status, context, risk, or risk-eval`);
796
- if (["install", "setup"].includes(command)) console.log('\nNext: in your AI tool, say "investigate <ticket>" or "create a spec".');
811
+ if (["install", "setup"].includes(command) && !HANDOFF) console.log('\nNext: in your AI tool, say "investigate <ticket>" or "create a spec".');
797
812
  } catch (e) {
798
813
  console.error(`✗ ${e.message}`);
799
814
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benjaminthomas/spec-driven-dev",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "description": "Spec-driven AI development workflow (investigate → spec → implement → verify → review → ship) as Agent Skills for Claude Code, Cursor, Codex CLI and Antigravity.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ticket-to-pr",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "description": "Parallel-batch spec-driven feature workflow (spec-setup, spec-investigate, spec-create, spec-implement, spec-verify, spec-review, spec-checkpoint, spec-ship) plus a portable SEO/GEO operations skill (generative-seo) for any codebase.",
5
5
  "author": {
6
6
  "name": "Benjamin Thomas",