intentdocs 0.10.0 → 0.11.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.
Files changed (30) hide show
  1. package/README.md +6 -1
  2. package/dist/chunk-64I7RLP3.js +171 -0
  3. package/dist/{chunk-IDNUBI2P.js → chunk-65EDM7QH.js} +6 -6
  4. package/dist/{chunk-NFIXRIHM.js → chunk-BNEU6TLJ.js} +55 -21
  5. package/dist/chunk-GFKZ5CRL.js +12 -0
  6. package/dist/{chunk-5USVG4DW.js → chunk-ID4B5RZ2.js} +42 -21
  7. package/dist/{chunk-EEKEF2FD.js → chunk-IORMKLAQ.js} +178 -121
  8. package/dist/{chunk-UF535HZL.js → chunk-K5SNF6CG.js} +13 -2
  9. package/dist/{chunk-HEHHSSUM.js → chunk-KPQ42YE6.js} +1 -1
  10. package/dist/{chunk-YUW3W43S.js → chunk-KTGQO3AE.js} +31 -8
  11. package/dist/{chunk-UR73WX5I.js → chunk-UQDMUKLP.js} +2 -2
  12. package/dist/{chunk-LXQXJULN.js → chunk-XZE2XP6O.js} +3 -3
  13. package/dist/ci-NOCV3XUV.js +11 -0
  14. package/dist/{complexity-ZOB3BPVD.js → complexity-OJVM37NF.js} +4 -4
  15. package/dist/{import-prd-MJUCIMHX.js → import-prd-5FCVXCYO.js} +14 -7
  16. package/dist/index.js +377 -359
  17. package/dist/{keys-5PA3D6CX.js → keys-2W5V56FS.js} +32 -11
  18. package/dist/{log-EVLWM64C.js → log-DFCCAAJN.js} +23 -7
  19. package/dist/{map-extract-W6WJLVOF.js → map-extract-YUCFLGJS.js} +2 -2
  20. package/dist/{map-import-LL4AIAQE.js → map-import-7RN2NEUZ.js} +7 -6
  21. package/dist/{map-schema-6GL2UKZQ.js → map-schema-5BEIJM2J.js} +1 -1
  22. package/dist/{projects-F7GMH66U.js → projects-AYAYVFKL.js} +2 -2
  23. package/dist/push-33V7ANJW.js +462 -0
  24. package/dist/{research-4ASCZSZN.js → research-SHO5SXVQ.js} +4 -4
  25. package/dist/scope-RRGJHS2G.js +13 -0
  26. package/dist/setup-UILQVYIB.js +14 -0
  27. package/package.json +6 -5
  28. package/dist/ci-LBOCMRKZ.js +0 -11
  29. package/dist/scope-S3LZZ3KB.js +0 -11
  30. package/dist/setup-YLUPBLK6.js +0 -14
@@ -1,31 +1,30 @@
1
+ import {
2
+ writeStoryContext
3
+ } from "./chunk-BNEU6TLJ.js";
1
4
  import {
2
5
  captureCli,
3
6
  shutdownCliAnalytics
4
- } from "./chunk-HEHHSSUM.js";
5
- import {
6
- writeStoryContext
7
- } from "./chunk-NFIXRIHM.js";
7
+ } from "./chunk-KPQ42YE6.js";
8
8
  import {
9
9
  apiFetch,
10
10
  getContext,
11
11
  listStories
12
- } from "./chunk-YUW3W43S.js";
12
+ } from "./chunk-KTGQO3AE.js";
13
13
  import {
14
14
  hasConfig,
15
15
  requireConfig
16
- } from "./chunk-UF535HZL.js";
16
+ } from "./chunk-K5SNF6CG.js";
17
17
  import {
18
18
  choose,
19
19
  closePrompt
20
20
  } from "./chunk-WRRUCCVZ.js";
21
21
  import {
22
22
  requireValidAuth
23
- } from "./chunk-LXQXJULN.js";
23
+ } from "./chunk-XZE2XP6O.js";
24
24
 
25
25
  // src/commands/setup.ts
26
- import { existsSync as existsSync2, mkdirSync, writeFileSync as writeFileSync2, readFileSync, unlinkSync } from "fs";
27
- import { join as join2, dirname } from "path";
28
- import { homedir } from "os";
26
+ import { existsSync as existsSync3, mkdirSync, writeFileSync as writeFileSync3, readFileSync as readFileSync2, unlinkSync } from "fs";
27
+ import { join as join3 } from "path";
29
28
 
30
29
  // src/commands/sync.ts
31
30
  import { writeFileSync, readdirSync, existsSync, statSync } from "fs";
@@ -120,11 +119,66 @@ async function sync(opts) {
120
119
  await shutdownCliAnalytics();
121
120
  }
122
121
 
122
+ // src/lib/claude-mcp-config.ts
123
+ import { existsSync as existsSync2, readFileSync, writeFileSync as writeFileSync2 } from "fs";
124
+ import { join as join2 } from "path";
125
+ import { homedir } from "os";
126
+ var LOCAL_SERVER_NAME = "intent";
127
+ var LOCAL_SERVER_ENTRY = { type: "stdio", command: "npx", args: ["intentdocs", "mcp"], env: {} };
128
+ var CLAUDE_MCP_ADD_COMMAND = `claude mcp add --scope project ${LOCAL_SERVER_NAME} -- npx intentdocs mcp`;
129
+ function sameEntry(a, b) {
130
+ return JSON.stringify(a) === JSON.stringify(b);
131
+ }
132
+ function registerLocalServerInMcpJson(cwd = process.cwd()) {
133
+ const path = join2(cwd, ".mcp.json");
134
+ let config = {};
135
+ if (existsSync2(path)) {
136
+ try {
137
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
138
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return { status: "unreadable", path };
139
+ config = parsed;
140
+ } catch {
141
+ return { status: "unreadable", path };
142
+ }
143
+ }
144
+ const rawServers = config.mcpServers;
145
+ if (rawServers !== void 0 && (typeof rawServers !== "object" || rawServers === null || Array.isArray(rawServers))) {
146
+ return { status: "unreadable", path };
147
+ }
148
+ const servers = { ...rawServers ?? {} };
149
+ const before = servers[LOCAL_SERVER_NAME];
150
+ if (sameEntry(before, LOCAL_SERVER_ENTRY)) return { status: "unchanged", path };
151
+ servers[LOCAL_SERVER_NAME] = { ...LOCAL_SERVER_ENTRY, args: [...LOCAL_SERVER_ENTRY.args], env: {} };
152
+ writeFileSync2(path, JSON.stringify({ ...config, mcpServers: servers }, null, 2) + "\n");
153
+ return { status: before === void 0 ? "added" : "updated", path };
154
+ }
155
+ var LEGACY_SETTINGS_ENTRY = { command: "npx", args: ["intentdocs", "mcp"] };
156
+ function removeLegacySettingsEntry(home = homedir()) {
157
+ const path = join2(home, ".claude", "settings.json");
158
+ if (!existsSync2(path)) return false;
159
+ let settings;
160
+ try {
161
+ settings = JSON.parse(readFileSync(path, "utf-8"));
162
+ } catch {
163
+ return false;
164
+ }
165
+ if (!settings || typeof settings !== "object" || Array.isArray(settings)) return false;
166
+ const servers = settings.mcpServers;
167
+ if (!servers || typeof servers !== "object" || !sameEntry(servers[LOCAL_SERVER_NAME], LEGACY_SETTINGS_ENTRY)) return false;
168
+ const rest = { ...servers };
169
+ delete rest[LOCAL_SERVER_NAME];
170
+ const next = { ...settings };
171
+ if (Object.keys(rest).length > 0) next.mcpServers = rest;
172
+ else delete next.mcpServers;
173
+ writeFileSync2(path, JSON.stringify(next, null, 2) + "\n");
174
+ return true;
175
+ }
176
+
123
177
  // src/commands/setup.ts
124
178
  async function setup() {
125
179
  await requireValidAuth();
126
180
  if (!hasConfig()) {
127
- console.log(" Not connected to a project. Run `intentdocs init` first.");
181
+ console.log(" Not connected to a project. Run `npx intentdocs init` first.");
128
182
  closePrompt();
129
183
  return;
130
184
  }
@@ -142,7 +196,7 @@ async function setup() {
142
196
  try {
143
197
  await syncContextFile(config);
144
198
  } catch {
145
- console.log(" \u26A0 Could not fetch project context (run `intentdocs sync --context` to retry)");
199
+ console.log(" \u26A0 Could not fetch project context (run `npx intentdocs sync --context` to retry)");
146
200
  }
147
201
  generateAgentDocs();
148
202
  console.log(`
@@ -162,64 +216,64 @@ async function setup() {
162
216
  /intent-sync Refresh context from intentdocs
163
217
 
164
218
  Terminal commands:
165
- intent next Next priority story
166
- intent done <id> Mark done + log decision/lesson
167
- intent decide Log an architectural decision
168
- intent example Log a reference pattern
169
- intent sync Refresh INTENT.md
170
- intent sync --context Regenerate CLAUDE.md from intentdocs
171
- intent status Recent activity
219
+ npx intentdocs next Next priority story
220
+ npx intentdocs done <id> Mark done + log decision/lesson
221
+ npx intentdocs decide Log an architectural decision
222
+ npx intentdocs example Log a reference pattern
223
+ npx intentdocs sync Refresh INTENT.md
224
+ npx intentdocs sync --context Regenerate CLAUDE.md from intentdocs
225
+ npx intentdocs status Recent activity
172
226
  `);
173
227
  closePrompt();
174
228
  }
175
229
  function setupClaudeCode() {
176
230
  const cwd = process.cwd();
177
- const claudeMdPath = join2(cwd, "CLAUDE.md");
231
+ const claudeMdPath = join3(cwd, "CLAUDE.md");
178
232
  const claudeBlock = `
179
233
  # intentdocs Integration
180
234
 
181
235
  This project is connected to a intentdocs story map.
182
- Run \`intentdocs sync --context\` to generate the full CLAUDE.md with your project's instructions,
236
+ Run \`npx intentdocs sync --context\` to generate the full CLAUDE.md with your project's instructions,
183
237
  story map, decisions, examples, tools, and guardrails.
184
238
 
185
239
  ## Quick reference
186
240
 
187
241
  | Command | What it does |
188
242
  |---|---|
189
- | \`intentdocs next\` | Pick up the next priority story |
190
- | \`intentdocs done <id>\` | Mark a story done + log a decision |
191
- | \`intentdocs decide\` | Log an architectural or product decision |
192
- | \`intentdocs example\` | Log a reference pattern for this codebase |
193
- | \`intentdocs sync\` | Refresh story map + INTENT.md |
194
- | \`intentdocs sync --context\` | Regenerate this file from intentdocs |
195
- | \`intentdocs status\` | Show recent activity |
243
+ | \`npx intentdocs next\` | Pick up the next priority story |
244
+ | \`npx intentdocs done <id>\` | Mark a story done + log a decision |
245
+ | \`npx intentdocs decide\` | Log an architectural or product decision |
246
+ | \`npx intentdocs example\` | Log a reference pattern for this codebase |
247
+ | \`npx intentdocs sync\` | Refresh story map + INTENT.md |
248
+ | \`npx intentdocs sync --context\` | Regenerate this file from intentdocs |
249
+ | \`npx intentdocs status\` | Show recent activity |
196
250
  `;
197
- if (existsSync2(claudeMdPath)) {
198
- const existing = readFileSync(claudeMdPath, "utf-8");
251
+ if (existsSync3(claudeMdPath)) {
252
+ const existing = readFileSync2(claudeMdPath, "utf-8");
199
253
  if (!existing.includes("intentdocs Integration")) {
200
- writeFileSync2(claudeMdPath, existing + "\n" + claudeBlock);
254
+ writeFileSync3(claudeMdPath, existing + "\n" + claudeBlock);
201
255
  console.log(" \u2713 Updated CLAUDE.md with intentdocs agent workflow");
202
256
  } else {
203
257
  console.log(" \u2713 CLAUDE.md already configured");
204
258
  }
205
259
  } else {
206
- writeFileSync2(claudeMdPath, claudeBlock.trim() + "\n");
260
+ writeFileSync3(claudeMdPath, claudeBlock.trim() + "\n");
207
261
  console.log(" \u2713 Created CLAUDE.md with intentdocs agent workflow");
208
262
  }
209
- const commandsDir = join2(cwd, ".claude", "commands");
210
- if (!existsSync2(commandsDir)) mkdirSync(commandsDir, { recursive: true });
263
+ const commandsDir = join3(cwd, ".claude", "commands");
264
+ if (!existsSync3(commandsDir)) mkdirSync(commandsDir, { recursive: true });
211
265
  const oldPbCommands = ["pb-next", "pb-implement", "pb-review", "pb-document", "pb-test", "pb-status", "pb-done", "pb-sync", "pb-propose", "pb-context"];
212
266
  for (const name of oldPbCommands) {
213
- const oldPath = join2(commandsDir, name + ".md");
214
- if (existsSync2(oldPath)) {
267
+ const oldPath = join3(commandsDir, name + ".md");
268
+ if (existsSync3(oldPath)) {
215
269
  unlinkSync(oldPath);
216
270
  }
217
271
  }
218
- writeFileSync2(
219
- join2(commandsDir, "intent-next.md"),
272
+ writeFileSync3(
273
+ join3(commandsDir, "intent-next.md"),
220
274
  `# Pick up the next story
221
275
 
222
- 1. Run \`intentdocs next\` to get the highest-priority story
276
+ 1. Run \`npx intentdocs next\` to get the highest-priority story
223
277
  2. Read the acceptance criteria carefully \u2014 these define "done"
224
278
  3. Check ARCHITECTURE.md for relevant technical decisions
225
279
  4. Read CONVENTIONS.md for coding patterns to follow
@@ -227,13 +281,13 @@ story map, decisions, examples, tools, and guardrails.
227
281
  6. Ask for confirmation before proceeding
228
282
  `
229
283
  );
230
- writeFileSync2(
231
- join2(commandsDir, "intent-implement.md"),
284
+ writeFileSync3(
285
+ join3(commandsDir, "intent-implement.md"),
232
286
  `# Implement a story
233
287
 
234
288
  ## Context to load first
235
289
  1. Read CLAUDE.md \u2014 your full project harness (instructions, decisions, examples, tools, guardrails)
236
- 2. Run \`intentdocs next\` if you don't have a story yet
290
+ 2. Run \`npx intentdocs next\` if you don't have a story yet
237
291
  3. Review the "Done when" acceptance criteria \u2014 each one carries a priority
238
292
  (\`must\`/\`should\`) and a verification method: \`[executable]\` gives you a
239
293
  \`check:\` command to run, \`[self-check]\`/\`[visual]\`/\`[founder]\` give you
@@ -254,18 +308,18 @@ story map, decisions, examples, tools, and guardrails.
254
308
  \`must\` criterion fails 3 times, call \`raise_blocker\` with what you
255
309
  attempted, what's failing, and the single decision the founder needs to
256
310
  make \u2014 then stop working on this story.
257
- 10. Never call \`mark_done\` (or \`intentdocs done\`) while a \`must\` criterion is
311
+ 10. Never call \`mark_done\` (or \`npx intentdocs done\`) while a \`must\` criterion is
258
312
  still failing or has never been reported \u2014 both will warn you and
259
313
  require an explicit override if you try.
260
314
 
261
315
  ## Write back to intentdocs
262
316
  11. Add implementation notes:
263
- \`intentdocs note <story-id> "How this was implemented"\`
264
- 12. Log decisions: \`intentdocs decide "Title" -d "What and why" -c architecture\`
265
- 13. Log useful patterns: \`intentdocs example\`
317
+ \`npx intentdocs note <story-id> "How this was implemented"\`
318
+ 12. Log decisions: \`npx intentdocs decide "Title" -d "What and why" -c architecture\`
319
+ 13. Log useful patterns: \`npx intentdocs example\`
266
320
  14. If you discovered new requirements:
267
- \`intentdocs add "title" --activity "Activity" --priority should\`
268
- 15. Mark done: \`intentdocs done <story-id>\`
321
+ \`npx intentdocs add "title" --activity "Activity" --priority should\`
322
+ 15. Mark done: \`npx intentdocs done <story-id>\`
269
323
  16. Commit: \`git commit -m "feat: description [SC-<id>]"\`
270
324
 
271
325
  ## Rules
@@ -275,8 +329,8 @@ story map, decisions, examples, tools, and guardrails.
275
329
  - Never mark a story done with a failing or unreported \`must\` criterion.
276
330
  `
277
331
  );
278
- writeFileSync2(
279
- join2(commandsDir, "intent-review.md"),
332
+ writeFileSync3(
333
+ join3(commandsDir, "intent-review.md"),
280
334
  `# Review against acceptance criteria
281
335
 
282
336
  1. Identify the story being worked on
@@ -287,8 +341,8 @@ story map, decisions, examples, tools, and guardrails.
287
341
  4. Summarise: what's done, what needs work, any concerns
288
342
  `
289
343
  );
290
- writeFileSync2(
291
- join2(commandsDir, "intent-document.md"),
344
+ writeFileSync3(
345
+ join3(commandsDir, "intent-document.md"),
292
346
  `# Document a feature
293
347
 
294
348
  1. Check which story was just completed
@@ -299,47 +353,47 @@ story map, decisions, examples, tools, and guardrails.
299
353
  - Decisions made and trade-offs
300
354
  - How to test it manually
301
355
  4. Log decisions to intentdocs:
302
- \`intentdocs decide "Title" -d "Description" -c architecture\`
356
+ \`npx intentdocs decide "Title" -d "Description" -c architecture\`
303
357
  5. Add implementation notes:
304
- \`intentdocs note <story-id> "Summary of how it works"\`
358
+ \`npx intentdocs note <story-id> "Summary of how it works"\`
305
359
  6. Update ARCHITECTURE.md if needed
306
360
  7. Update CONVENTIONS.md if new patterns were introduced
307
361
  `
308
362
  );
309
- writeFileSync2(
310
- join2(commandsDir, "intent-test.md"),
363
+ writeFileSync3(
364
+ join3(commandsDir, "intent-test.md"),
311
365
  `# Write tests for a story
312
366
 
313
- 1. Get the story details: \`intentdocs next\` or provided story ID
367
+ 1. Get the story details: \`npx intentdocs next\` or provided story ID
314
368
  2. Each acceptance criterion becomes at least one test
315
369
  3. Also consider: error cases, boundary conditions, integration points
316
370
  4. Follow testing patterns in CONVENTIONS.md
317
371
  5. Run the tests to verify they pass
318
372
  `
319
373
  );
320
- writeFileSync2(
321
- join2(commandsDir, "intent-status.md"),
322
- `Run \`intentdocs status\` and \`intentdocs stories --filter todo\` to show current progress and remaining backlog. Summarise what's done and what's left.`
374
+ writeFileSync3(
375
+ join3(commandsDir, "intent-status.md"),
376
+ `Run \`npx intentdocs status\` and \`npx intentdocs stories --filter todo\` to show current progress and remaining backlog. Summarise what's done and what's left.`
323
377
  );
324
- writeFileSync2(
325
- join2(commandsDir, "intent-done.md"),
326
- `Ask which story was just completed, then run \`intentdocs done <id>\`.
327
- \`intentdocs done\` prints the acceptance-criteria table first. If any \`must\` criterion is still failing or was
378
+ writeFileSync3(
379
+ join3(commandsDir, "intent-done.md"),
380
+ `Ask which story was just completed, then run \`npx intentdocs done <id>\`.
381
+ \`npx intentdocs done\` prints the acceptance-criteria table first. If any \`must\` criterion is still failing or was
328
382
  never reported via \`report_criteria\`, it will list them and ask "Mark done anyway?" \u2014 only confirm that
329
- if the founder explicitly wants to override; otherwise go fix the failing criterion and re-run \`intentdocs done\`.
383
+ if the founder explicitly wants to override; otherwise go fix the failing criterion and re-run \`npx intentdocs done\`.
330
384
  The CLI will prompt for an optional decision or lesson learned \u2014 encourage the user to capture it.
331
- Also ask if there are implementation notes to add: \`intentdocs note <id> "..."\`
385
+ Also ask if there are implementation notes to add: \`npx intentdocs note <id> "..."\`
332
386
  Both decisions and notes flow back to the project page on intentdocs.com.`
333
387
  );
334
- writeFileSync2(
335
- join2(commandsDir, "intent-sync.md"),
388
+ writeFileSync3(
389
+ join3(commandsDir, "intent-sync.md"),
336
390
  `# Refresh context from intentdocs
337
391
 
338
392
  ## Refresh story map summary
339
- Run \`intentdocs sync\` \u2014 updates INTENT.md with the latest stories and their status.
393
+ Run \`npx intentdocs sync\` \u2014 updates INTENT.md with the latest stories and their status.
340
394
 
341
395
  ## Regenerate the full CLAUDE.md harness
342
- Run \`intentdocs sync --context\` \u2014 rebuilds CLAUDE.md from your project page, pulling in:
396
+ Run \`npx intentdocs sync --context\` \u2014 rebuilds CLAUDE.md from your project page, pulling in:
343
397
  - Role & Goals (Instructions section)
344
398
  - Scope (all story maps + story counts)
345
399
  - Decisions & Memory (last 10 decisions)
@@ -347,10 +401,10 @@ Run \`intentdocs sync --context\` \u2014 rebuilds CLAUDE.md from your project pa
347
401
  - Tools & Stack (structured tool registry + MCP config)
348
402
  - Guardrails (hard constraints)
349
403
 
350
- Run \`intentdocs sync --context\` after updating any section on intentdocs.com.`
404
+ Run \`npx intentdocs sync --context\` after updating any section on intentdocs.com.`
351
405
  );
352
- writeFileSync2(
353
- join2(commandsDir, "intent-propose.md"),
406
+ writeFileSync3(
407
+ join3(commandsDir, "intent-propose.md"),
354
408
  `# Propose a new change
355
409
 
356
410
  Use this when you want to plan a new feature, improvement, or fix before writing code.
@@ -360,22 +414,22 @@ stories there AND saves a local spec for the AI to reference during implementati
360
414
  ## Process
361
415
  1. Ask the user: "What do you want to build or change? Describe the problem and the solution."
362
416
  2. Help them break it into 2-5 stories with clear acceptance criteria (each AC is testable)
363
- 3. Run: \`intentdocs propose <change-name>\`
417
+ 3. Run: \`npx intentdocs propose <change-name>\`
364
418
  - The CLI will guide through: problem, solution, activity, priority, stories + ACs
365
419
  - Stories are created in the live story map at intentdocs.com
366
420
  - A local spec is saved to \`intent-changes/<name>/proposal.md\`
367
- 4. Once done: \`intentdocs sync\` to pull the new stories into INTENT.md
368
- 5. Run \`intentdocs next\` to start implementing
421
+ 4. Once done: \`npx intentdocs sync\` to pull the new stories into INTENT.md
422
+ 5. Run \`npx intentdocs next\` to start implementing
369
423
 
370
424
  ## Tips
371
425
  - Change names should be kebab-case: add-dark-mode, fix-auth-flow, onboarding-revamp
372
426
  - Keep stories small \u2014 one story = one deployable increment
373
427
  - Write ACs as testable outcomes: "Given X, when Y, then Z" or "User can..."
374
- - If the change is already defined in the UI, just run \`intentdocs sync\` instead
428
+ - If the change is already defined in the UI, just run \`npx intentdocs sync\` instead
375
429
  `
376
430
  );
377
- writeFileSync2(
378
- join2(commandsDir, "intent-context.md"),
431
+ writeFileSync3(
432
+ join3(commandsDir, "intent-context.md"),
379
433
  `# Load current story context
380
434
 
381
435
  Use this to focus on a single story without loading the full story map.
@@ -386,44 +440,44 @@ Use this to focus on a single story without loading the full story map.
386
440
  - When you need a clean, focused view of ACs and notes
387
441
 
388
442
  ## Process
389
- 1. Run \`intentdocs next\` to get the active story \u2014 this automatically writes the context file to \`.intent/stories/<id>.md\`
443
+ 1. Run \`npx intentdocs next\` to get the active story \u2014 this automatically writes the context file to \`.intent/stories/<id>.md\`
390
444
  2. Read that file \u2014 it contains: title, user story, acceptance criteria (as checkboxes), notes, and space for relevant files
391
445
  3. Use it as your working document throughout implementation:
392
446
  - Check off ACs as you satisfy them
393
447
  - Add file paths under "Relevant files" as you discover them
394
- - Run \`intentdocs note <id> "..."\` to log notes (updates both remote map and local file)
395
- 4. When all ACs are checked: \`intentdocs done <id>\`
448
+ - Run \`npx intentdocs note <id> "..."\` to log notes (updates both remote map and local file)
449
+ 4. When all ACs are checked: \`npx intentdocs done <id>\`
396
450
 
397
451
  ## If you already know the story ID
398
452
  The file is at \`.intent/stories/<full-story-id>.md\` \u2014 read it directly.
399
453
  `
400
454
  );
401
- writeFileSync2(
402
- join2(commandsDir, "intent-decide.md"),
455
+ writeFileSync3(
456
+ join3(commandsDir, "intent-decide.md"),
403
457
  `# Log an architectural or product decision
404
458
 
405
459
  Use this when you've made a decision that future agents (or teammates) should know about.
406
460
 
407
- Run \`intentdocs decide\` \u2014 the CLI will prompt for:
461
+ Run \`npx intentdocs decide\` \u2014 the CLI will prompt for:
408
462
  - Title: short, specific description of the decision
409
463
  - Description: what was decided and why (include trade-offs considered)
410
464
  - Category: architecture / product / technical / trade-off
411
465
 
412
466
  Decisions appear in the Memory section of the project page at intentdocs.com
413
- and are included in CLAUDE.md the next time you run \`intentdocs sync --context\`.
467
+ and are included in CLAUDE.md the next time you run \`npx intentdocs sync --context\`.
414
468
 
415
469
  Good decisions to log:
416
470
  - "Chose X over Y because..."
417
471
  - "Decided not to do Z because..."
418
472
  - "This pattern is used throughout because..."`
419
473
  );
420
- writeFileSync2(
421
- join2(commandsDir, "intent-example.md"),
474
+ writeFileSync3(
475
+ join3(commandsDir, "intent-example.md"),
422
476
  `# Log a reference pattern for this codebase
423
477
 
424
478
  Use this when you've written code that represents the right way to do something in this project.
425
479
 
426
- Run \`intentdocs example\` \u2014 the CLI will prompt for:
480
+ Run \`npx intentdocs example\` \u2014 the CLI will prompt for:
427
481
  - Title: what the pattern is
428
482
  - Description: when to use it
429
483
  - Language: typescript / python / bash / other
@@ -431,30 +485,28 @@ Run \`intentdocs example\` \u2014 the CLI will prompt for:
431
485
  - After code: the correct pattern to follow
432
486
 
433
487
  Examples appear in the Knowledge > Examples section of the project page
434
- and are included in CLAUDE.md as Reference Patterns the next time you run \`intentdocs sync --context\`.`
488
+ and are included in CLAUDE.md as Reference Patterns the next time you run \`npx intentdocs sync --context\`.`
435
489
  );
436
490
  console.log(" \u2713 Created slash commands: /intent-propose, /intent-next, /intent-implement, /intent-review, /intent-document, /intent-test, /intent-status, /intent-done, /intent-sync, /intent-context, /intent-decide, /intent-example");
437
491
  registerMcpWithClaudeCode();
438
492
  }
439
493
  function registerMcpWithClaudeCode() {
440
- const settingsPath = join2(homedir(), ".claude", "settings.json");
441
- let settings = {};
442
- if (existsSync2(settingsPath)) {
443
- try {
444
- settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
445
- } catch {
446
- }
494
+ const result = registerLocalServerInMcpJson(process.cwd());
495
+ if (result.status === "unreadable") {
496
+ console.log(` \u26A0 Couldn't read ${result.path}, so it was left as it is. Add the IntentDocs server yourself:`);
497
+ console.log(` ${CLAUDE_MCP_ADD_COMMAND}`);
498
+ } else if (result.status === "unchanged") {
499
+ console.log(` \u2713 MCP server "${LOCAL_SERVER_NAME}" already registered in .mcp.json`);
500
+ } else {
501
+ console.log(` \u2713 Registered MCP server "${LOCAL_SERVER_NAME}" in .mcp.json \u2014 restart Claude Code and approve it when asked`);
502
+ }
503
+ if (removeLegacySettingsEntry()) {
504
+ console.log(" \u2713 Removed the old entry from ~/.claude/settings.json, where Claude Code doesn't read MCP servers");
447
505
  }
448
- const servers = settings.mcpServers ?? {};
449
- servers.intent = { command: "npx", args: ["intentdocs", "mcp"] };
450
- settings.mcpServers = servers;
451
- mkdirSync(dirname(settingsPath), { recursive: true });
452
- writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
453
- console.log(" \u2713 Registered MCP server in ~/.claude/settings.json \u2014 restart Claude Code to activate");
454
506
  }
455
507
  function setupCursor() {
456
508
  const cwd = process.cwd();
457
- const cursorRulesPath = join2(cwd, ".cursorrules");
509
+ const cursorRulesPath = join3(cwd, ".cursorrules");
458
510
  const cursorBlock = `
459
511
  # intentdocs Integration
460
512
 
@@ -463,13 +515,18 @@ function setupCursor() {
463
515
  2. **ARCHITECTURE.md** \u2014 technical decisions and system structure
464
516
  3. **CONVENTIONS.md** \u2014 coding patterns, naming, file structure
465
517
 
518
+ ## First run
519
+ - No story started yet? The founder's next step is their first story:
520
+ claim it with \`npx intentdocs next\` (or \`start_story\` over MCP), build it,
521
+ report each criterion, then mark it done.
522
+
466
523
  ## Workflow
467
- - Next story: \`intentdocs next\`
468
- - Mark done: \`intentdocs done <id>\`
469
- - Add notes: \`intentdocs note <id> "..."\`
470
- - Log decisions: \`intentdocs decide "Title" -d "Why"\`
471
- - Create stories: \`intentdocs add "title" --activity "Name"\`
472
- - Refresh context: \`intentdocs sync\`
524
+ - Next story: \`npx intentdocs next\`
525
+ - Mark done: \`npx intentdocs done <id>\`
526
+ - Add notes: \`npx intentdocs note <id> "..."\`
527
+ - Log decisions: \`npx intentdocs decide "Title" -d "Why"\`
528
+ - Create stories: \`npx intentdocs add "title" --activity "Name"\`
529
+ - Refresh context: \`npx intentdocs sync\`
473
530
 
474
531
  ## The acceptance-criteria loop
475
532
  - Each "Done when" criterion carries a priority (\`must\`/\`should\`) and a
@@ -480,7 +537,7 @@ function setupCursor() {
480
537
  - For a failing \`must\` criterion: fix and re-check. If the same \`must\`
481
538
  fails 3 times, call \`raise_blocker\` with what you attempted, what's
482
539
  failing, and the single decision needed \u2014 then stop.
483
- - Never call \`mark_done\`/\`intentdocs done\` while a \`must\` criterion is still
540
+ - Never call \`mark_done\`/\`npx intentdocs done\` while a \`must\` criterion is still
484
541
  failing or unreported \u2014 both warn and require an explicit override.
485
542
 
486
543
  ## Rules
@@ -489,14 +546,14 @@ function setupCursor() {
489
546
  - Log decisions and trade-offs back to intentdocs
490
547
  - Follow patterns in CONVENTIONS.md
491
548
  `;
492
- if (existsSync2(cursorRulesPath)) {
493
- const existing = readFileSync(cursorRulesPath, "utf-8");
549
+ if (existsSync3(cursorRulesPath)) {
550
+ const existing = readFileSync2(cursorRulesPath, "utf-8");
494
551
  if (!existing.includes("intentdocs Integration")) {
495
- writeFileSync2(cursorRulesPath, existing + "\n" + cursorBlock);
552
+ writeFileSync3(cursorRulesPath, existing + "\n" + cursorBlock);
496
553
  console.log(" \u2713 Updated .cursorrules");
497
554
  }
498
555
  } else {
499
- writeFileSync2(cursorRulesPath, cursorBlock.trim() + "\n");
556
+ writeFileSync3(cursorRulesPath, cursorBlock.trim() + "\n");
500
557
  console.log(" \u2713 Created .cursorrules");
501
558
  }
502
559
  console.log(`
@@ -515,9 +572,9 @@ function setupCursor() {
515
572
  }
516
573
  function generateAgentDocs() {
517
574
  const cwd = process.cwd();
518
- const archPath = join2(cwd, "ARCHITECTURE.md");
519
- if (!existsSync2(archPath)) {
520
- writeFileSync2(
575
+ const archPath = join3(cwd, "ARCHITECTURE.md");
576
+ if (!existsSync3(archPath)) {
577
+ writeFileSync3(
521
578
  archPath,
522
579
  `# Architecture
523
580
 
@@ -544,9 +601,9 @@ _Record trade-offs and why._
544
601
  );
545
602
  console.log(" \u2713 Created ARCHITECTURE.md scaffold");
546
603
  }
547
- const convPath = join2(cwd, "CONVENTIONS.md");
548
- if (!existsSync2(convPath)) {
549
- writeFileSync2(
604
+ const convPath = join3(cwd, "CONVENTIONS.md");
605
+ if (!existsSync3(convPath)) {
606
+ writeFileSync3(
550
607
  convPath,
551
608
  `# Conventions
552
609
 
@@ -5,6 +5,16 @@ import {
5
5
  // src/lib/config.ts
6
6
  import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
7
7
  import { join, dirname } from "path";
8
+ function checkoutConfig(input) {
9
+ return {
10
+ apiBase: input.apiBase,
11
+ mapTitle: input.map.title,
12
+ projectId: input.project.id,
13
+ mapId: input.map.id,
14
+ workspace: input.project.workspace ? { orgId: input.project.workspace.orgId, name: input.project.workspace.name } : { orgId: null, name: null },
15
+ ...input.appUrl && { appUrl: input.appUrl }
16
+ };
17
+ }
8
18
  var CONFIG_DIR = ".intent";
9
19
  var CONFIG_FILE = "config.json";
10
20
  function configPath() {
@@ -39,12 +49,12 @@ function writeConfig(config) {
39
49
  function requireConfig() {
40
50
  const config = readConfig();
41
51
  if (!config) {
42
- console.error("Not initialized. Run: intent init");
52
+ console.error("Not initialized. Run: npx intentdocs init");
43
53
  process.exit(1);
44
54
  }
45
55
  if (!config.mapId) {
46
56
  console.error(
47
- "This checkout was connected with a sync token, which has been retired: every sync now runs as you.\nRemove .intent/config.json and run `intentdocs login` then `intentdocs init` to reconnect."
57
+ "This checkout was connected with a sync token, which has been retired: every sync now runs as you.\nRemove .intent/config.json and run `npx intentdocs login` then `npx intentdocs init` to reconnect."
48
58
  );
49
59
  process.exit(1);
50
60
  }
@@ -52,6 +62,7 @@ function requireConfig() {
52
62
  }
53
63
 
54
64
  export {
65
+ checkoutConfig,
55
66
  hasConfig,
56
67
  readConfig,
57
68
  writeConfig,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getAuth
3
- } from "./chunk-LXQXJULN.js";
3
+ } from "./chunk-XZE2XP6O.js";
4
4
 
5
5
  // src/lib/analytics.ts
6
6
  import { PostHog } from "posthog-node";