intentdocs 0.8.0 → 0.10.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 +2 -1
- package/bin/intentdocs.js +2 -0
- package/dist/{chunk-4OWPN2RE.js → chunk-5USVG4DW.js} +24 -43
- package/dist/{chunk-IKF3ZLHK.js → chunk-EEKEF2FD.js} +65 -101
- package/dist/chunk-HEHHSSUM.js +43 -0
- package/dist/chunk-IDNUBI2P.js +317 -0
- package/dist/chunk-LQTPZL2Y.js +15 -0
- package/dist/chunk-LXQXJULN.js +105 -0
- package/dist/{chunk-6FGYJ3W2.js → chunk-NFIXRIHM.js} +43 -4
- package/dist/{chunk-ICOMMHKG.js → chunk-UF535HZL.js} +12 -1
- package/dist/{chunk-ITQUQYWB.js → chunk-UR73WX5I.js} +1 -1
- package/dist/chunk-UYTVTYNB.js +11 -0
- package/dist/{chunk-WPVDURTJ.js → chunk-WRRUCCVZ.js} +27 -3
- package/dist/chunk-YUW3W43S.js +170 -0
- package/dist/ci-LBOCMRKZ.js +11 -0
- package/dist/{complexity-NSSYVT54.js → complexity-ZOB3BPVD.js} +12 -7
- package/dist/{import-prd-CKV3R67G.js → import-prd-MJUCIMHX.js} +13 -11
- package/dist/index.js +420 -179
- package/dist/{keys-EDWET3WG.js → keys-5PA3D6CX.js} +8 -7
- package/dist/log-EVLWM64C.js +206 -0
- package/dist/{map-extract-I3AACTGL.js → map-extract-W6WJLVOF.js} +2 -1
- package/dist/{map-import-IYUMRASO.js → map-import-LL4AIAQE.js} +12 -10
- package/dist/{map-schema-JVL3O2TJ.js → map-schema-6GL2UKZQ.js} +1 -1
- package/dist/projects-F7GMH66U.js +37 -0
- package/dist/{prompt-WAWCRGHN.js → prompt-GOAFIKBZ.js} +3 -1
- package/dist/{research-6SXJ37TI.js → research-4ASCZSZN.js} +12 -10
- package/dist/scope-S3LZZ3KB.js +11 -0
- package/dist/setup-YLUPBLK6.js +14 -0
- package/package.json +4 -2
- package/dist/chunk-6XKB6RTU.js +0 -123
- package/dist/chunk-PCNDP5SX.js +0 -34
- package/dist/log-TT2UCJP7.js +0 -94
- package/dist/scope-OGKQ472D.js +0 -10
- package/dist/setup-SOI2HQAL.js +0 -11
package/README.md
CHANGED
|
@@ -106,8 +106,9 @@ intent sync --context # Regenerate CLAUDE.md from your project page
|
|
|
106
106
|
|
|
107
107
|
| Command | Description |
|
|
108
108
|
|---|---|
|
|
109
|
-
| `intent login` | Authenticate (opens browser) |
|
|
109
|
+
| `intent login` | Authenticate (opens browser) — choose the workspace the token is bound to |
|
|
110
110
|
| `intent logout` | Log out |
|
|
111
|
+
| `intent projects` | List the projects your token can reach — the whole workspace it is bound to |
|
|
111
112
|
| `intent init` | Connect project directory to a story map + generate CLAUDE.md |
|
|
112
113
|
| `intent setup` | Configure Claude Code / Cursor with slash commands |
|
|
113
114
|
| `intent sync` | Refresh `INTENT.md` with latest stories |
|
|
@@ -1,37 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getContext
|
|
3
|
+
} from "./chunk-YUW3W43S.js";
|
|
4
|
+
import {
|
|
5
|
+
writeConfig
|
|
6
|
+
} from "./chunk-UF535HZL.js";
|
|
1
7
|
import {
|
|
2
8
|
ask,
|
|
3
9
|
closePrompt,
|
|
4
10
|
confirm
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
getContext
|
|
8
|
-
} from "./chunk-6XKB6RTU.js";
|
|
11
|
+
} from "./chunk-WRRUCCVZ.js";
|
|
9
12
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
authenticatedFetch,
|
|
14
|
+
requireValidAuth
|
|
15
|
+
} from "./chunk-LXQXJULN.js";
|
|
12
16
|
import {
|
|
13
|
-
API_BASE
|
|
14
|
-
|
|
15
|
-
} from "./chunk-PCNDP5SX.js";
|
|
17
|
+
API_BASE
|
|
18
|
+
} from "./chunk-UYTVTYNB.js";
|
|
16
19
|
|
|
17
20
|
// src/commands/scope.ts
|
|
18
21
|
import { writeFileSync, existsSync } from "fs";
|
|
19
22
|
import { join } from "path";
|
|
20
|
-
async function apiFetch(path, token, opts = {}) {
|
|
21
|
-
return fetch(`${API_BASE}${path}`, {
|
|
22
|
-
...opts,
|
|
23
|
-
headers: {
|
|
24
|
-
"Content-Type": "application/json",
|
|
25
|
-
Authorization: `Bearer ${token}`,
|
|
26
|
-
...opts.headers ?? {}
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
23
|
async function scope(projectId) {
|
|
31
|
-
|
|
32
|
-
const { token } = auth;
|
|
24
|
+
await requireValidAuth();
|
|
33
25
|
if (!projectId) {
|
|
34
|
-
projectId = await ask(" Project ID (from `
|
|
26
|
+
projectId = await ask(" Project ID (from `intentdocs start`): ");
|
|
35
27
|
}
|
|
36
28
|
if (!projectId?.trim()) {
|
|
37
29
|
console.log(" Project ID required.");
|
|
@@ -60,7 +52,7 @@ async function scope(projectId) {
|
|
|
60
52
|
mvp ? `MVP scope: ${mvp}` : "",
|
|
61
53
|
constraints ? `Technical constraints: ${constraints}` : ""
|
|
62
54
|
].filter(Boolean).join("\n");
|
|
63
|
-
const res = await
|
|
55
|
+
const res = await authenticatedFetch("/api/blueprint/generate", {
|
|
64
56
|
method: "POST",
|
|
65
57
|
body: JSON.stringify({
|
|
66
58
|
projectId,
|
|
@@ -120,30 +112,19 @@ async function scope(projectId) {
|
|
|
120
112
|
console.log(" \u2713 Blueprint generated (couldn't parse summary)\n");
|
|
121
113
|
}
|
|
122
114
|
console.log("\n Connecting project to your codebase...");
|
|
123
|
-
const mapsRes = await
|
|
124
|
-
`/api/storymapper/project/${projectId}
|
|
125
|
-
token
|
|
115
|
+
const mapsRes = await authenticatedFetch(
|
|
116
|
+
`/api/storymapper/project/${projectId}`
|
|
126
117
|
);
|
|
127
|
-
let
|
|
118
|
+
let mapId = null;
|
|
128
119
|
if (mapsRes.ok) {
|
|
129
120
|
const mapData = await mapsRes.json();
|
|
130
|
-
if (mapData.mapId)
|
|
131
|
-
const tokenRes = await apiFetch(
|
|
132
|
-
`/api/storymapper/${mapData.mapId}/sync-token`,
|
|
133
|
-
token,
|
|
134
|
-
{ method: "POST" }
|
|
135
|
-
);
|
|
136
|
-
if (tokenRes.ok) {
|
|
137
|
-
const tokenData = await tokenRes.json();
|
|
138
|
-
syncToken = tokenData.sync_token;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
121
|
+
if (mapData.mapId) mapId = mapData.mapId;
|
|
141
122
|
}
|
|
142
|
-
if (
|
|
143
|
-
|
|
123
|
+
if (mapId) {
|
|
124
|
+
const config = { apiBase: API_BASE, projectId, mapId };
|
|
125
|
+
writeConfig(config);
|
|
144
126
|
console.log(" \u2713 Connected\n");
|
|
145
127
|
try {
|
|
146
|
-
const config = { syncToken, apiBase: API_BASE };
|
|
147
128
|
const md = await getContext(config);
|
|
148
129
|
writeFileSync(join(process.cwd(), "INTENT.md"), md);
|
|
149
130
|
console.log(" \u2713 Downloaded INTENT.md\n");
|
|
@@ -190,12 +171,12 @@ async function scope(projectId) {
|
|
|
190
171
|
}
|
|
191
172
|
}
|
|
192
173
|
}
|
|
193
|
-
const { confirm: confirmSetup } = await import("./prompt-
|
|
174
|
+
const { confirm: confirmSetup } = await import("./prompt-GOAFIKBZ.js");
|
|
194
175
|
const wantSetup = await confirmSetup(
|
|
195
176
|
" Configure your AI tool (Claude Code / Cursor) with intentdocs agent workflows?"
|
|
196
177
|
);
|
|
197
178
|
if (wantSetup) {
|
|
198
|
-
const { setup } = await import("./setup-
|
|
179
|
+
const { setup } = await import("./setup-YLUPBLK6.js");
|
|
199
180
|
await setup();
|
|
200
181
|
return;
|
|
201
182
|
}
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
captureCli,
|
|
3
|
+
shutdownCliAnalytics
|
|
4
|
+
} from "./chunk-HEHHSSUM.js";
|
|
4
5
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from "./chunk-WPVDURTJ.js";
|
|
6
|
+
writeStoryContext
|
|
7
|
+
} from "./chunk-NFIXRIHM.js";
|
|
8
8
|
import {
|
|
9
9
|
apiFetch,
|
|
10
10
|
getContext,
|
|
11
11
|
listStories
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-YUW3W43S.js";
|
|
13
13
|
import {
|
|
14
14
|
hasConfig,
|
|
15
15
|
requireConfig
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-UF535HZL.js";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "./chunk-
|
|
18
|
+
choose,
|
|
19
|
+
closePrompt
|
|
20
|
+
} from "./chunk-WRRUCCVZ.js";
|
|
21
|
+
import {
|
|
22
|
+
requireValidAuth
|
|
23
|
+
} from "./chunk-LXQXJULN.js";
|
|
21
24
|
|
|
22
25
|
// src/commands/setup.ts
|
|
23
26
|
import { existsSync as existsSync2, mkdirSync, writeFileSync as writeFileSync2, readFileSync, unlinkSync } from "fs";
|
|
@@ -27,43 +30,6 @@ import { homedir } from "os";
|
|
|
27
30
|
// src/commands/sync.ts
|
|
28
31
|
import { writeFileSync, readdirSync, existsSync, statSync } from "fs";
|
|
29
32
|
import { join } from "path";
|
|
30
|
-
|
|
31
|
-
// src/lib/analytics.ts
|
|
32
|
-
import { PostHog } from "posthog-node";
|
|
33
|
-
var client = null;
|
|
34
|
-
function getClient() {
|
|
35
|
-
if (client) return client;
|
|
36
|
-
const auth = getAuth();
|
|
37
|
-
if (!auth?.posthogKey) return null;
|
|
38
|
-
client = new PostHog(auth.posthogKey, {
|
|
39
|
-
host: auth.posthogHost ?? "https://eu.i.posthog.com",
|
|
40
|
-
flushAt: 1,
|
|
41
|
-
flushInterval: 0
|
|
42
|
-
});
|
|
43
|
-
return client;
|
|
44
|
-
}
|
|
45
|
-
function getDistinctId() {
|
|
46
|
-
return getAuth()?.userId ?? null;
|
|
47
|
-
}
|
|
48
|
-
function captureCli(event, properties, groups) {
|
|
49
|
-
const posthog = getClient();
|
|
50
|
-
const distinctId = getDistinctId();
|
|
51
|
-
if (!posthog || !distinctId) return;
|
|
52
|
-
posthog.capture({
|
|
53
|
-
distinctId,
|
|
54
|
-
event,
|
|
55
|
-
properties: {
|
|
56
|
-
...properties,
|
|
57
|
-
...groups?.project ? { project_id: groups.project } : {}
|
|
58
|
-
},
|
|
59
|
-
...groups ? { groups } : {}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
async function shutdownCliAnalytics() {
|
|
63
|
-
if (client) await client.shutdown();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// src/commands/sync.ts
|
|
67
33
|
async function syncContextFile(config) {
|
|
68
34
|
const res = await apiFetch(config, "/context-file?format=claude");
|
|
69
35
|
const { content } = await res.json();
|
|
@@ -156,9 +122,9 @@ async function sync(opts) {
|
|
|
156
122
|
|
|
157
123
|
// src/commands/setup.ts
|
|
158
124
|
async function setup() {
|
|
159
|
-
|
|
125
|
+
await requireValidAuth();
|
|
160
126
|
if (!hasConfig()) {
|
|
161
|
-
console.log(" Not connected to a project. Run `
|
|
127
|
+
console.log(" Not connected to a project. Run `intentdocs init` first.");
|
|
162
128
|
closePrompt();
|
|
163
129
|
return;
|
|
164
130
|
}
|
|
@@ -170,13 +136,13 @@ async function setup() {
|
|
|
170
136
|
]);
|
|
171
137
|
const tools = idx === 0 ? ["claude"] : idx === 1 ? ["cursor"] : ["claude", "cursor"];
|
|
172
138
|
for (const tool of tools) {
|
|
173
|
-
if (tool === "claude") setupClaudeCode(
|
|
174
|
-
if (tool === "cursor") setupCursor(
|
|
139
|
+
if (tool === "claude") setupClaudeCode();
|
|
140
|
+
if (tool === "cursor") setupCursor();
|
|
175
141
|
}
|
|
176
142
|
try {
|
|
177
143
|
await syncContextFile(config);
|
|
178
144
|
} catch {
|
|
179
|
-
console.log(" \u26A0 Could not fetch project context (run `
|
|
145
|
+
console.log(" \u26A0 Could not fetch project context (run `intentdocs sync --context` to retry)");
|
|
180
146
|
}
|
|
181
147
|
generateAgentDocs();
|
|
182
148
|
console.log(`
|
|
@@ -206,27 +172,27 @@ async function setup() {
|
|
|
206
172
|
`);
|
|
207
173
|
closePrompt();
|
|
208
174
|
}
|
|
209
|
-
function setupClaudeCode(
|
|
175
|
+
function setupClaudeCode() {
|
|
210
176
|
const cwd = process.cwd();
|
|
211
177
|
const claudeMdPath = join2(cwd, "CLAUDE.md");
|
|
212
178
|
const claudeBlock = `
|
|
213
179
|
# intentdocs Integration
|
|
214
180
|
|
|
215
181
|
This project is connected to a intentdocs story map.
|
|
216
|
-
Run \`
|
|
182
|
+
Run \`intentdocs sync --context\` to generate the full CLAUDE.md with your project's instructions,
|
|
217
183
|
story map, decisions, examples, tools, and guardrails.
|
|
218
184
|
|
|
219
185
|
## Quick reference
|
|
220
186
|
|
|
221
187
|
| Command | What it does |
|
|
222
188
|
|---|---|
|
|
223
|
-
| \`
|
|
224
|
-
| \`
|
|
225
|
-
| \`
|
|
226
|
-
| \`
|
|
227
|
-
| \`
|
|
228
|
-
| \`
|
|
229
|
-
| \`
|
|
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 |
|
|
230
196
|
`;
|
|
231
197
|
if (existsSync2(claudeMdPath)) {
|
|
232
198
|
const existing = readFileSync(claudeMdPath, "utf-8");
|
|
@@ -253,7 +219,7 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
253
219
|
join2(commandsDir, "intent-next.md"),
|
|
254
220
|
`# Pick up the next story
|
|
255
221
|
|
|
256
|
-
1. Run \`
|
|
222
|
+
1. Run \`intentdocs next\` to get the highest-priority story
|
|
257
223
|
2. Read the acceptance criteria carefully \u2014 these define "done"
|
|
258
224
|
3. Check ARCHITECTURE.md for relevant technical decisions
|
|
259
225
|
4. Read CONVENTIONS.md for coding patterns to follow
|
|
@@ -267,7 +233,7 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
267
233
|
|
|
268
234
|
## Context to load first
|
|
269
235
|
1. Read CLAUDE.md \u2014 your full project harness (instructions, decisions, examples, tools, guardrails)
|
|
270
|
-
2. Run \`
|
|
236
|
+
2. Run \`intentdocs next\` if you don't have a story yet
|
|
271
237
|
3. Review the "Done when" acceptance criteria \u2014 each one carries a priority
|
|
272
238
|
(\`must\`/\`should\`) and a verification method: \`[executable]\` gives you a
|
|
273
239
|
\`check:\` command to run, \`[self-check]\`/\`[visual]\`/\`[founder]\` give you
|
|
@@ -288,18 +254,18 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
288
254
|
\`must\` criterion fails 3 times, call \`raise_blocker\` with what you
|
|
289
255
|
attempted, what's failing, and the single decision the founder needs to
|
|
290
256
|
make \u2014 then stop working on this story.
|
|
291
|
-
10. Never call \`mark_done\` (or \`
|
|
257
|
+
10. Never call \`mark_done\` (or \`intentdocs done\`) while a \`must\` criterion is
|
|
292
258
|
still failing or has never been reported \u2014 both will warn you and
|
|
293
259
|
require an explicit override if you try.
|
|
294
260
|
|
|
295
261
|
## Write back to intentdocs
|
|
296
262
|
11. Add implementation notes:
|
|
297
|
-
\`
|
|
298
|
-
12. Log decisions: \`
|
|
299
|
-
13. Log useful patterns: \`
|
|
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\`
|
|
300
266
|
14. If you discovered new requirements:
|
|
301
|
-
\`
|
|
302
|
-
15. Mark done: \`
|
|
267
|
+
\`intentdocs add "title" --activity "Activity" --priority should\`
|
|
268
|
+
15. Mark done: \`intentdocs done <story-id>\`
|
|
303
269
|
16. Commit: \`git commit -m "feat: description [SC-<id>]"\`
|
|
304
270
|
|
|
305
271
|
## Rules
|
|
@@ -333,9 +299,9 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
333
299
|
- Decisions made and trade-offs
|
|
334
300
|
- How to test it manually
|
|
335
301
|
4. Log decisions to intentdocs:
|
|
336
|
-
\`
|
|
302
|
+
\`intentdocs decide "Title" -d "Description" -c architecture\`
|
|
337
303
|
5. Add implementation notes:
|
|
338
|
-
\`
|
|
304
|
+
\`intentdocs note <story-id> "Summary of how it works"\`
|
|
339
305
|
6. Update ARCHITECTURE.md if needed
|
|
340
306
|
7. Update CONVENTIONS.md if new patterns were introduced
|
|
341
307
|
`
|
|
@@ -344,7 +310,7 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
344
310
|
join2(commandsDir, "intent-test.md"),
|
|
345
311
|
`# Write tests for a story
|
|
346
312
|
|
|
347
|
-
1. Get the story details: \`
|
|
313
|
+
1. Get the story details: \`intentdocs next\` or provided story ID
|
|
348
314
|
2. Each acceptance criterion becomes at least one test
|
|
349
315
|
3. Also consider: error cases, boundary conditions, integration points
|
|
350
316
|
4. Follow testing patterns in CONVENTIONS.md
|
|
@@ -353,16 +319,16 @@ story map, decisions, examples, tools, and guardrails.
|
|
|
353
319
|
);
|
|
354
320
|
writeFileSync2(
|
|
355
321
|
join2(commandsDir, "intent-status.md"),
|
|
356
|
-
`Run \`
|
|
322
|
+
`Run \`intentdocs status\` and \`intentdocs stories --filter todo\` to show current progress and remaining backlog. Summarise what's done and what's left.`
|
|
357
323
|
);
|
|
358
324
|
writeFileSync2(
|
|
359
325
|
join2(commandsDir, "intent-done.md"),
|
|
360
|
-
`Ask which story was just completed, then run \`
|
|
361
|
-
\`
|
|
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
|
|
362
328
|
never reported via \`report_criteria\`, it will list them and ask "Mark done anyway?" \u2014 only confirm that
|
|
363
|
-
if the founder explicitly wants to override; otherwise go fix the failing criterion and re-run \`
|
|
329
|
+
if the founder explicitly wants to override; otherwise go fix the failing criterion and re-run \`intentdocs done\`.
|
|
364
330
|
The CLI will prompt for an optional decision or lesson learned \u2014 encourage the user to capture it.
|
|
365
|
-
Also ask if there are implementation notes to add: \`
|
|
331
|
+
Also ask if there are implementation notes to add: \`intentdocs note <id> "..."\`
|
|
366
332
|
Both decisions and notes flow back to the project page on intentdocs.com.`
|
|
367
333
|
);
|
|
368
334
|
writeFileSync2(
|
|
@@ -370,10 +336,10 @@ Both decisions and notes flow back to the project page on intentdocs.com.`
|
|
|
370
336
|
`# Refresh context from intentdocs
|
|
371
337
|
|
|
372
338
|
## Refresh story map summary
|
|
373
|
-
Run \`
|
|
339
|
+
Run \`intentdocs sync\` \u2014 updates INTENT.md with the latest stories and their status.
|
|
374
340
|
|
|
375
341
|
## Regenerate the full CLAUDE.md harness
|
|
376
|
-
Run \`
|
|
342
|
+
Run \`intentdocs sync --context\` \u2014 rebuilds CLAUDE.md from your project page, pulling in:
|
|
377
343
|
- Role & Goals (Instructions section)
|
|
378
344
|
- Scope (all story maps + story counts)
|
|
379
345
|
- Decisions & Memory (last 10 decisions)
|
|
@@ -381,7 +347,7 @@ Run \`intent sync --context\` \u2014 rebuilds CLAUDE.md from your project page,
|
|
|
381
347
|
- Tools & Stack (structured tool registry + MCP config)
|
|
382
348
|
- Guardrails (hard constraints)
|
|
383
349
|
|
|
384
|
-
Run \`
|
|
350
|
+
Run \`intentdocs sync --context\` after updating any section on intentdocs.com.`
|
|
385
351
|
);
|
|
386
352
|
writeFileSync2(
|
|
387
353
|
join2(commandsDir, "intent-propose.md"),
|
|
@@ -394,18 +360,18 @@ stories there AND saves a local spec for the AI to reference during implementati
|
|
|
394
360
|
## Process
|
|
395
361
|
1. Ask the user: "What do you want to build or change? Describe the problem and the solution."
|
|
396
362
|
2. Help them break it into 2-5 stories with clear acceptance criteria (each AC is testable)
|
|
397
|
-
3. Run: \`
|
|
363
|
+
3. Run: \`intentdocs propose <change-name>\`
|
|
398
364
|
- The CLI will guide through: problem, solution, activity, priority, stories + ACs
|
|
399
365
|
- Stories are created in the live story map at intentdocs.com
|
|
400
366
|
- A local spec is saved to \`intent-changes/<name>/proposal.md\`
|
|
401
|
-
4. Once done: \`
|
|
402
|
-
5. Run \`
|
|
367
|
+
4. Once done: \`intentdocs sync\` to pull the new stories into INTENT.md
|
|
368
|
+
5. Run \`intentdocs next\` to start implementing
|
|
403
369
|
|
|
404
370
|
## Tips
|
|
405
371
|
- Change names should be kebab-case: add-dark-mode, fix-auth-flow, onboarding-revamp
|
|
406
372
|
- Keep stories small \u2014 one story = one deployable increment
|
|
407
373
|
- Write ACs as testable outcomes: "Given X, when Y, then Z" or "User can..."
|
|
408
|
-
- If the change is already defined in the UI, just run \`
|
|
374
|
+
- If the change is already defined in the UI, just run \`intentdocs sync\` instead
|
|
409
375
|
`
|
|
410
376
|
);
|
|
411
377
|
writeFileSync2(
|
|
@@ -420,13 +386,13 @@ Use this to focus on a single story without loading the full story map.
|
|
|
420
386
|
- When you need a clean, focused view of ACs and notes
|
|
421
387
|
|
|
422
388
|
## Process
|
|
423
|
-
1. Run \`
|
|
389
|
+
1. Run \`intentdocs next\` to get the active story \u2014 this automatically writes the context file to \`.intent/stories/<id>.md\`
|
|
424
390
|
2. Read that file \u2014 it contains: title, user story, acceptance criteria (as checkboxes), notes, and space for relevant files
|
|
425
391
|
3. Use it as your working document throughout implementation:
|
|
426
392
|
- Check off ACs as you satisfy them
|
|
427
393
|
- Add file paths under "Relevant files" as you discover them
|
|
428
|
-
- Run \`
|
|
429
|
-
4. When all ACs are checked: \`
|
|
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>\`
|
|
430
396
|
|
|
431
397
|
## If you already know the story ID
|
|
432
398
|
The file is at \`.intent/stories/<full-story-id>.md\` \u2014 read it directly.
|
|
@@ -438,13 +404,13 @@ The file is at \`.intent/stories/<full-story-id>.md\` \u2014 read it directly.
|
|
|
438
404
|
|
|
439
405
|
Use this when you've made a decision that future agents (or teammates) should know about.
|
|
440
406
|
|
|
441
|
-
Run \`
|
|
407
|
+
Run \`intentdocs decide\` \u2014 the CLI will prompt for:
|
|
442
408
|
- Title: short, specific description of the decision
|
|
443
409
|
- Description: what was decided and why (include trade-offs considered)
|
|
444
410
|
- Category: architecture / product / technical / trade-off
|
|
445
411
|
|
|
446
412
|
Decisions appear in the Memory section of the project page at intentdocs.com
|
|
447
|
-
and are included in CLAUDE.md the next time you run \`
|
|
413
|
+
and are included in CLAUDE.md the next time you run \`intentdocs sync --context\`.
|
|
448
414
|
|
|
449
415
|
Good decisions to log:
|
|
450
416
|
- "Chose X over Y because..."
|
|
@@ -457,7 +423,7 @@ Good decisions to log:
|
|
|
457
423
|
|
|
458
424
|
Use this when you've written code that represents the right way to do something in this project.
|
|
459
425
|
|
|
460
|
-
Run \`
|
|
426
|
+
Run \`intentdocs example\` \u2014 the CLI will prompt for:
|
|
461
427
|
- Title: what the pattern is
|
|
462
428
|
- Description: when to use it
|
|
463
429
|
- Language: typescript / python / bash / other
|
|
@@ -465,7 +431,7 @@ Run \`intent example\` \u2014 the CLI will prompt for:
|
|
|
465
431
|
- After code: the correct pattern to follow
|
|
466
432
|
|
|
467
433
|
Examples appear in the Knowledge > Examples section of the project page
|
|
468
|
-
and are included in CLAUDE.md as Reference Patterns the next time you run \`
|
|
434
|
+
and are included in CLAUDE.md as Reference Patterns the next time you run \`intentdocs sync --context\`.`
|
|
469
435
|
);
|
|
470
436
|
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");
|
|
471
437
|
registerMcpWithClaudeCode();
|
|
@@ -486,7 +452,7 @@ function registerMcpWithClaudeCode() {
|
|
|
486
452
|
writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
487
453
|
console.log(" \u2713 Registered MCP server in ~/.claude/settings.json \u2014 restart Claude Code to activate");
|
|
488
454
|
}
|
|
489
|
-
function setupCursor(
|
|
455
|
+
function setupCursor() {
|
|
490
456
|
const cwd = process.cwd();
|
|
491
457
|
const cursorRulesPath = join2(cwd, ".cursorrules");
|
|
492
458
|
const cursorBlock = `
|
|
@@ -498,12 +464,12 @@ function setupCursor(syncToken) {
|
|
|
498
464
|
3. **CONVENTIONS.md** \u2014 coding patterns, naming, file structure
|
|
499
465
|
|
|
500
466
|
## Workflow
|
|
501
|
-
- Next story: \`
|
|
502
|
-
- Mark done: \`
|
|
503
|
-
- Add notes: \`
|
|
504
|
-
- Log decisions: \`
|
|
505
|
-
- Create stories: \`
|
|
506
|
-
- Refresh context: \`
|
|
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\`
|
|
507
473
|
|
|
508
474
|
## The acceptance-criteria loop
|
|
509
475
|
- Each "Done when" criterion carries a priority (\`must\`/\`should\`) and a
|
|
@@ -514,7 +480,7 @@ function setupCursor(syncToken) {
|
|
|
514
480
|
- For a failing \`must\` criterion: fix and re-check. If the same \`must\`
|
|
515
481
|
fails 3 times, call \`raise_blocker\` with what you attempted, what's
|
|
516
482
|
failing, and the single decision needed \u2014 then stop.
|
|
517
|
-
- Never call \`mark_done\`/\`
|
|
483
|
+
- Never call \`mark_done\`/\`intentdocs done\` while a \`must\` criterion is still
|
|
518
484
|
failing or unreported \u2014 both warn and require an explicit override.
|
|
519
485
|
|
|
520
486
|
## Rules
|
|
@@ -614,8 +580,6 @@ _Linting, formatting, style preferences._
|
|
|
614
580
|
}
|
|
615
581
|
|
|
616
582
|
export {
|
|
617
|
-
captureCli,
|
|
618
|
-
shutdownCliAnalytics,
|
|
619
583
|
sync,
|
|
620
584
|
setup
|
|
621
585
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAuth
|
|
3
|
+
} from "./chunk-LXQXJULN.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/analytics.ts
|
|
6
|
+
import { PostHog } from "posthog-node";
|
|
7
|
+
var client = null;
|
|
8
|
+
function getClient() {
|
|
9
|
+
if (client) return client;
|
|
10
|
+
const auth = getAuth();
|
|
11
|
+
if (!auth?.posthogKey) return null;
|
|
12
|
+
client = new PostHog(auth.posthogKey, {
|
|
13
|
+
host: auth.posthogHost ?? "https://eu.i.posthog.com",
|
|
14
|
+
flushAt: 1,
|
|
15
|
+
flushInterval: 0
|
|
16
|
+
});
|
|
17
|
+
return client;
|
|
18
|
+
}
|
|
19
|
+
function getDistinctId() {
|
|
20
|
+
return getAuth()?.userId ?? null;
|
|
21
|
+
}
|
|
22
|
+
function captureCli(event, properties, groups) {
|
|
23
|
+
const posthog = getClient();
|
|
24
|
+
const distinctId = getDistinctId();
|
|
25
|
+
if (!posthog || !distinctId) return;
|
|
26
|
+
posthog.capture({
|
|
27
|
+
distinctId,
|
|
28
|
+
event,
|
|
29
|
+
properties: {
|
|
30
|
+
...properties,
|
|
31
|
+
...groups?.project ? { project_id: groups.project } : {}
|
|
32
|
+
},
|
|
33
|
+
...groups ? { groups } : {}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async function shutdownCliAnalytics() {
|
|
37
|
+
if (client) await client.shutdown();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
captureCli,
|
|
42
|
+
shutdownCliAnalytics
|
|
43
|
+
};
|