specstocode 0.7.1 → 0.7.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.
@@ -1,9 +1,17 @@
1
1
  // src/lib/config.ts
2
2
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
3
- import { join } from "path";
3
+ import { join, dirname } from "path";
4
4
  var CONFIG_DIR = ".specstocode";
5
5
  var CONFIG_FILE = "config.json";
6
6
  function configPath() {
7
+ let dir = process.cwd();
8
+ while (true) {
9
+ const candidate = join(dir, CONFIG_DIR, CONFIG_FILE);
10
+ if (existsSync(candidate)) return candidate;
11
+ const parent = dirname(dir);
12
+ if (parent === dir) break;
13
+ dir = parent;
14
+ }
7
15
  return join(process.cwd(), CONFIG_DIR, CONFIG_FILE);
8
16
  }
9
17
  function hasConfig() {
@@ -20,7 +28,7 @@ function readConfig() {
20
28
  function writeConfig(config) {
21
29
  const dir = join(process.cwd(), CONFIG_DIR);
22
30
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
23
- writeFileSync(configPath(), JSON.stringify(config, null, 2) + "\n");
31
+ writeFileSync(join(dir, CONFIG_FILE), JSON.stringify(config, null, 2) + "\n");
24
32
  }
25
33
  function requireConfig() {
26
34
  const config = readConfig();
@@ -8,12 +8,12 @@ import {
8
8
  import {
9
9
  hasConfig,
10
10
  requireConfig
11
- } from "./chunk-ZLSV4CRF.js";
11
+ } from "./chunk-DBZNNVVE.js";
12
12
 
13
13
  // src/commands/setup.ts
14
14
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
15
- import { execSync } from "child_process";
16
- import { join } from "path";
15
+ import { join, dirname } from "path";
16
+ import { homedir } from "os";
17
17
  async function setup() {
18
18
  requireAuth();
19
19
  if (!hasConfig()) {
@@ -43,16 +43,16 @@ async function setup() {
43
43
  \u2022 Architecture and conventions scaffolding
44
44
 
45
45
  Slash commands (use inside Claude Code / Cursor, not the terminal):
46
- /pb-propose Propose a new change \u2014 creates stories + local spec
47
- /pb-next Pick up the next story
48
- /pb-implement Full implementation playbook
49
- /pb-review Review against acceptance criteria
50
- /pb-document Document what was built
51
- /pb-test Generate tests from ACs
52
- /pb-status Show progress
53
- /pb-done Mark a story as done
54
- /pb-sync Refresh product context
55
- /pb-context Load focused context for the current story
46
+ /stc-propose Propose a new change \u2014 creates stories + local spec
47
+ /stc-next Pick up the next story
48
+ /stc-implement Full implementation playbook
49
+ /stc-review Review against acceptance criteria
50
+ /stc-document Document what was built
51
+ /stc-test Generate tests from ACs
52
+ /stc-status Show progress
53
+ /stc-done Mark a story as done
54
+ /stc-sync Refresh product context
55
+ /stc-context Load focused context for the current story
56
56
 
57
57
  Terminal commands (use anywhere):
58
58
  stc status Show story map progress
@@ -123,7 +123,7 @@ Everything you record flows back to the story map so the team has context:
123
123
  const commandsDir = join(cwd, ".claude", "commands");
124
124
  if (!existsSync(commandsDir)) mkdirSync(commandsDir, { recursive: true });
125
125
  writeFileSync(
126
- join(commandsDir, "pb-next.md"),
126
+ join(commandsDir, "stc-next.md"),
127
127
  `# Pick up the next story
128
128
 
129
129
  1. Run \`stc next\` to get the highest-priority story
@@ -135,7 +135,7 @@ Everything you record flows back to the story map so the team has context:
135
135
  `
136
136
  );
137
137
  writeFileSync(
138
- join(commandsDir, "pb-implement.md"),
138
+ join(commandsDir, "stc-implement.md"),
139
139
  `# Implement a story
140
140
 
141
141
  ## Process
@@ -167,7 +167,7 @@ Everything you record flows back to the story map so the team has context:
167
167
  `
168
168
  );
169
169
  writeFileSync(
170
- join(commandsDir, "pb-review.md"),
170
+ join(commandsDir, "stc-review.md"),
171
171
  `# Review against acceptance criteria
172
172
 
173
173
  1. Identify the story being worked on
@@ -179,7 +179,7 @@ Everything you record flows back to the story map so the team has context:
179
179
  `
180
180
  );
181
181
  writeFileSync(
182
- join(commandsDir, "pb-document.md"),
182
+ join(commandsDir, "stc-document.md"),
183
183
  `# Document a feature
184
184
 
185
185
  1. Check which story was just completed
@@ -198,7 +198,7 @@ Everything you record flows back to the story map so the team has context:
198
198
  `
199
199
  );
200
200
  writeFileSync(
201
- join(commandsDir, "pb-test.md"),
201
+ join(commandsDir, "stc-test.md"),
202
202
  `# Write tests for a story
203
203
 
204
204
  1. Get the story details: \`stc next\` or provided story ID
@@ -209,19 +209,19 @@ Everything you record flows back to the story map so the team has context:
209
209
  `
210
210
  );
211
211
  writeFileSync(
212
- join(commandsDir, "pb-status.md"),
212
+ join(commandsDir, "stc-status.md"),
213
213
  `Run \`stc status\` and \`stc stories --filter todo\` to show current progress and remaining backlog. Summarise what's done and what's left.`
214
214
  );
215
215
  writeFileSync(
216
- join(commandsDir, "pb-done.md"),
216
+ join(commandsDir, "stc-done.md"),
217
217
  `Ask which story was just completed, then run \`stc done <id>\`. Also ask if there are any implementation notes to add: \`stc note <id> "..."\``
218
218
  );
219
219
  writeFileSync(
220
- join(commandsDir, "pb-sync.md"),
220
+ join(commandsDir, "stc-sync.md"),
221
221
  `Run \`stc sync\` to refresh SPECSTOCODE.md with the latest story map. Then re-read SPECSTOCODE.md to update your context.`
222
222
  );
223
223
  writeFileSync(
224
- join(commandsDir, "pb-propose.md"),
224
+ join(commandsDir, "stc-propose.md"),
225
225
  `# Propose a new change
226
226
 
227
227
  Use this when you want to plan a new feature, improvement, or fix before writing code.
@@ -246,7 +246,7 @@ stories there AND saves a local spec for the AI to reference during implementati
246
246
  `
247
247
  );
248
248
  writeFileSync(
249
- join(commandsDir, "pb-context.md"),
249
+ join(commandsDir, "stc-context.md"),
250
250
  `# Load current story context
251
251
 
252
252
  Use this to focus on a single story without loading the full story map.
@@ -269,33 +269,24 @@ Use this to focus on a single story without loading the full story map.
269
269
  The file is at \`.specstocode/stories/<full-story-id>.md\` \u2014 read it directly.
270
270
  `
271
271
  );
272
- console.log(" \u2713 Created slash commands: /pb-propose, /pb-next, /pb-implement, /pb-review, /pb-document, /pb-test, /pb-status, /pb-done, /pb-sync, /pb-context");
273
- try {
274
- execSync("openclaw --version", { stdio: "ignore" });
275
- const registration = JSON.stringify({
276
- command: "npx",
277
- args: ["specstocode", "mcp"],
278
- cwd
279
- });
280
- execSync(`openclaw mcp set specstocode '${registration}'`, { stdio: "inherit" });
281
- console.log(" \u2713 Registered with OpenClaw MCP \u2014 coding agents can now access your story map live");
282
- } catch {
283
- console.log(`
284
- To enable MCP tools (recommended), add to your Claude Code MCP config:
285
-
286
- {
287
- "mcpServers": {
288
- "specstocode": {
289
- "command": "npx",
290
- "args": ["specstocode", "mcp"],
291
- "cwd": "${cwd}"
292
- }
272
+ console.log(" \u2713 Created slash commands: /stc-propose, /stc-next, /stc-implement, /stc-review, /stc-document, /stc-test, /stc-status, /stc-done, /stc-sync, /stc-context");
273
+ registerMcpWithClaudeCode();
274
+ }
275
+ function registerMcpWithClaudeCode() {
276
+ const settingsPath = join(homedir(), ".claude", "settings.json");
277
+ let settings = {};
278
+ if (existsSync(settingsPath)) {
279
+ try {
280
+ settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
281
+ } catch {
293
282
  }
294
283
  }
295
-
296
- Or if you use OpenClaw: stc openclaw-register
297
- `);
298
- }
284
+ const servers = settings.mcpServers ?? {};
285
+ servers.specstocode = { command: "npx", args: ["specstocode", "mcp"] };
286
+ settings.mcpServers = servers;
287
+ mkdirSync(dirname(settingsPath), { recursive: true });
288
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
289
+ console.log(" \u2713 Registered MCP server in ~/.claude/settings.json \u2014 restart Claude Code to activate");
299
290
  }
300
291
  function setupCursor(syncToken) {
301
292
  const cwd = process.cwd();
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-WPVDURTJ.js";
13
13
  import {
14
14
  writeConfig
15
- } from "./chunk-ZLSV4CRF.js";
15
+ } from "./chunk-DBZNNVVE.js";
16
16
 
17
17
  // src/commands/scope.ts
18
18
  import { writeFileSync, existsSync } from "fs";
@@ -195,7 +195,7 @@ async function scope(projectId) {
195
195
  " Configure your AI tool (Claude Code / Cursor) with specstocode agent workflows?"
196
196
  );
197
197
  if (wantSetup) {
198
- const { setup } = await import("./setup-ZJCK6JB4.js");
198
+ const { setup } = await import("./setup-U6SABQNQ.js");
199
199
  await setup();
200
200
  return;
201
201
  }
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-XFT36SZE.js";
8
8
  import {
9
9
  requireConfig
10
- } from "./chunk-ZLSV4CRF.js";
10
+ } from "./chunk-DBZNNVVE.js";
11
11
 
12
12
  // src/commands/complexity.ts
13
13
  import ora from "ora";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-XFT36SZE.js";
9
9
  import {
10
10
  requireConfig
11
- } from "./chunk-ZLSV4CRF.js";
11
+ } from "./chunk-DBZNNVVE.js";
12
12
 
13
13
  // src/commands/import-prd.ts
14
14
  import { readFileSync, existsSync } from "fs";
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  setup
4
- } from "./chunk-T46QKLGM.js";
4
+ } from "./chunk-J6CQ4DQD.js";
5
5
  import {
6
6
  scope
7
- } from "./chunk-2FQUCTDE.js";
7
+ } from "./chunk-LRLG4Q6Q.js";
8
8
  import {
9
9
  API_BASE,
10
10
  getAuth,
@@ -36,7 +36,7 @@ import {
36
36
  readConfig,
37
37
  requireConfig,
38
38
  writeConfig
39
- } from "./chunk-ZLSV4CRF.js";
39
+ } from "./chunk-DBZNNVVE.js";
40
40
 
41
41
  // src/index.ts
42
42
  import { Command } from "commander";
@@ -839,7 +839,7 @@ async function start() {
839
839
  closePrompt();
840
840
  return;
841
841
  }
842
- const { scope: scope2 } = await import("./scope-NBFWSZEP.js");
842
+ const { scope: scope2 } = await import("./scope-HWAU4XT2.js");
843
843
  await scope2(projectId);
844
844
  }
845
845
 
@@ -1776,19 +1776,19 @@ program.command("show <id>").description("Show the full spec for a story (accept
1776
1776
  program.command("done <id>").description("Mark a story as done (accepts ID prefix)").action((id) => void done(id));
1777
1777
  program.command("add <title>").description("Create a new story").option("-a, --activity <activity>", "Activity to add the story under").option("-p, --priority <priority>", "Priority: must, should, could", "should").option("-e, --effort <effort>", "Effort: S, M, L, XL", "M").action((title, opts) => void add(title, opts));
1778
1778
  program.command("decide [title]").description("Log an architectural or product decision").option("-d, --description <desc>", "Decision description").option("-c, --category <cat>", "Category: architecture, product, technical, trade-off", "technical").option("-s, --story <id>", "Link to a story ID").action((title, opts) => {
1779
- import("./log-4OBVVVVF.js").then((m) => void m.logDecision(title, opts));
1779
+ import("./log-LOMAPAMN.js").then((m) => void m.logDecision(title, opts));
1780
1780
  });
1781
1781
  program.command("note <storyId> [note]").description("Add implementation notes to a story").action((storyId, note) => {
1782
- import("./log-4OBVVVVF.js").then((m) => void m.logNote(storyId, note));
1782
+ import("./log-LOMAPAMN.js").then((m) => void m.logNote(storyId, note));
1783
1783
  });
1784
1784
  program.command("complexity [storyId]").description("Analyze story complexity with AI \u2014 scores, risks, effort estimates").action((id) => {
1785
- import("./complexity-MFKA2RFZ.js").then((m) => void m.complexity(id));
1785
+ import("./complexity-ZPBJG3HN.js").then((m) => void m.complexity(id));
1786
1786
  });
1787
1787
  program.command("research [query]").description("Research a topic with AI using your project context").action((query) => {
1788
- import("./research-FKISZ323.js").then((m) => void m.research(query));
1788
+ import("./research-TVMC62XK.js").then((m) => void m.research(query));
1789
1789
  });
1790
1790
  program.command("import [file]").description("Import a PRD or spec into your story map as stories").action((file) => {
1791
- import("./import-prd-SJWUNW5M.js").then((m) => void m.importPrd(file));
1791
+ import("./import-prd-M2VNDEMJ.js").then((m) => void m.importPrd(file));
1792
1792
  });
1793
1793
  program.command("mcp").description("Start MCP server for Claude Code / Cursor integration").option("-m, --mode <mode>", "Tool mode: core, standard, all", "all").action((opts) => void startMcpServer(opts.mode));
1794
1794
  program.command("openclaw-register").description("Register this project with OpenClaw MCP \u2014 gives spawned coding agents access to your story map").action(() => void openclawRegister());
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-WPVDURTJ.js";
9
9
  import {
10
10
  requireConfig
11
- } from "./chunk-ZLSV4CRF.js";
11
+ } from "./chunk-DBZNNVVE.js";
12
12
 
13
13
  // src/commands/log.ts
14
14
  async function logDecision(title, opts) {
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-XFT36SZE.js";
9
9
  import {
10
10
  requireConfig
11
- } from "./chunk-ZLSV4CRF.js";
11
+ } from "./chunk-DBZNNVVE.js";
12
12
 
13
13
  // src/commands/research.ts
14
14
  import ora from "ora";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  scope
3
- } from "./chunk-2FQUCTDE.js";
3
+ } from "./chunk-LRLG4Q6Q.js";
4
4
  import "./chunk-WJOIFYIA.js";
5
5
  import "./chunk-QKMZ2SBR.js";
6
6
  import "./chunk-WPVDURTJ.js";
7
- import "./chunk-ZLSV4CRF.js";
7
+ import "./chunk-DBZNNVVE.js";
8
8
  export {
9
9
  scope
10
10
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  setup
3
- } from "./chunk-T46QKLGM.js";
3
+ } from "./chunk-J6CQ4DQD.js";
4
4
  import "./chunk-WJOIFYIA.js";
5
5
  import "./chunk-WPVDURTJ.js";
6
- import "./chunk-ZLSV4CRF.js";
6
+ import "./chunk-DBZNNVVE.js";
7
7
  export {
8
8
  setup
9
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specstocode",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "CLI for specstocode.com — connect your codebase to your product story map",
5
5
  "bin": {
6
6
  "specstocode": "bin/specstocode.js",