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.
- package/README.md +6 -1
- package/dist/chunk-64I7RLP3.js +171 -0
- package/dist/{chunk-IDNUBI2P.js → chunk-65EDM7QH.js} +6 -6
- package/dist/{chunk-NFIXRIHM.js → chunk-BNEU6TLJ.js} +55 -21
- package/dist/chunk-GFKZ5CRL.js +12 -0
- package/dist/{chunk-5USVG4DW.js → chunk-ID4B5RZ2.js} +42 -21
- package/dist/{chunk-EEKEF2FD.js → chunk-IORMKLAQ.js} +178 -121
- package/dist/{chunk-UF535HZL.js → chunk-K5SNF6CG.js} +13 -2
- package/dist/{chunk-HEHHSSUM.js → chunk-KPQ42YE6.js} +1 -1
- package/dist/{chunk-YUW3W43S.js → chunk-KTGQO3AE.js} +31 -8
- package/dist/{chunk-UR73WX5I.js → chunk-UQDMUKLP.js} +2 -2
- package/dist/{chunk-LXQXJULN.js → chunk-XZE2XP6O.js} +3 -3
- package/dist/ci-NOCV3XUV.js +11 -0
- package/dist/{complexity-ZOB3BPVD.js → complexity-OJVM37NF.js} +4 -4
- package/dist/{import-prd-MJUCIMHX.js → import-prd-5FCVXCYO.js} +14 -7
- package/dist/index.js +377 -359
- package/dist/{keys-5PA3D6CX.js → keys-2W5V56FS.js} +32 -11
- package/dist/{log-EVLWM64C.js → log-DFCCAAJN.js} +23 -7
- package/dist/{map-extract-W6WJLVOF.js → map-extract-YUCFLGJS.js} +2 -2
- package/dist/{map-import-LL4AIAQE.js → map-import-7RN2NEUZ.js} +7 -6
- package/dist/{map-schema-6GL2UKZQ.js → map-schema-5BEIJM2J.js} +1 -1
- package/dist/{projects-F7GMH66U.js → projects-AYAYVFKL.js} +2 -2
- package/dist/push-33V7ANJW.js +462 -0
- package/dist/{research-4ASCZSZN.js → research-SHO5SXVQ.js} +4 -4
- package/dist/scope-RRGJHS2G.js +13 -0
- package/dist/setup-UILQVYIB.js +14 -0
- package/package.json +6 -5
- package/dist/ci-LBOCMRKZ.js +0 -11
- package/dist/scope-S3LZZ3KB.js +0 -11
- 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-
|
|
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-
|
|
12
|
+
} from "./chunk-KTGQO3AE.js";
|
|
13
13
|
import {
|
|
14
14
|
hasConfig,
|
|
15
15
|
requireConfig
|
|
16
|
-
} from "./chunk-
|
|
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-
|
|
23
|
+
} from "./chunk-XZE2XP6O.js";
|
|
24
24
|
|
|
25
25
|
// src/commands/setup.ts
|
|
26
|
-
import { existsSync as
|
|
27
|
-
import { join as
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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 =
|
|
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 (
|
|
198
|
-
const existing =
|
|
251
|
+
if (existsSync3(claudeMdPath)) {
|
|
252
|
+
const existing = readFileSync2(claudeMdPath, "utf-8");
|
|
199
253
|
if (!existing.includes("intentdocs Integration")) {
|
|
200
|
-
|
|
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
|
-
|
|
260
|
+
writeFileSync3(claudeMdPath, claudeBlock.trim() + "\n");
|
|
207
261
|
console.log(" \u2713 Created CLAUDE.md with intentdocs agent workflow");
|
|
208
262
|
}
|
|
209
|
-
const commandsDir =
|
|
210
|
-
if (!
|
|
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 =
|
|
214
|
-
if (
|
|
267
|
+
const oldPath = join3(commandsDir, name + ".md");
|
|
268
|
+
if (existsSync3(oldPath)) {
|
|
215
269
|
unlinkSync(oldPath);
|
|
216
270
|
}
|
|
217
271
|
}
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
|
|
231
|
-
|
|
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
|
-
|
|
279
|
-
|
|
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
|
-
|
|
291
|
-
|
|
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
|
-
|
|
310
|
-
|
|
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
|
-
|
|
321
|
-
|
|
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
|
-
|
|
325
|
-
|
|
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
|
-
|
|
335
|
-
|
|
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
|
-
|
|
353
|
-
|
|
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
|
-
|
|
378
|
-
|
|
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
|
-
|
|
402
|
-
|
|
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
|
-
|
|
421
|
-
|
|
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
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
}
|
|
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 =
|
|
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 (
|
|
493
|
-
const existing =
|
|
549
|
+
if (existsSync3(cursorRulesPath)) {
|
|
550
|
+
const existing = readFileSync2(cursorRulesPath, "utf-8");
|
|
494
551
|
if (!existing.includes("intentdocs Integration")) {
|
|
495
|
-
|
|
552
|
+
writeFileSync3(cursorRulesPath, existing + "\n" + cursorBlock);
|
|
496
553
|
console.log(" \u2713 Updated .cursorrules");
|
|
497
554
|
}
|
|
498
555
|
} else {
|
|
499
|
-
|
|
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 =
|
|
519
|
-
if (!
|
|
520
|
-
|
|
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 =
|
|
548
|
-
if (!
|
|
549
|
-
|
|
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:
|
|
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,
|