@infinitedusky/indusk-mcp 0.3.0 → 0.4.1
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/dist/bin/commands/init.js +15 -3
- package/dist/bin/commands/update.js +11 -7
- package/dist/server/index.js +2 -0
- package/dist/tools/graph-tools.d.ts +6 -0
- package/dist/tools/graph-tools.js +116 -0
- package/package.json +1 -1
- package/skills/context.md +1 -0
- package/skills/document.md +2 -0
- package/skills/plan.md +6 -1
- package/skills/retrospective.md +15 -6
- package/skills/toolbelt.md +23 -1
- package/skills/verify.md +1 -1
- package/skills/work.md +4 -4
|
@@ -196,6 +196,19 @@ export async function init(projectRoot, options = {}) {
|
|
|
196
196
|
console.info(" missing: Docker — install Docker or OrbStack to enable FalkorDB");
|
|
197
197
|
}
|
|
198
198
|
const cgcInstalled = checkCGC();
|
|
199
|
+
// 9. Auto-index the codebase into the graph
|
|
200
|
+
if (dockerAvailable && cgcInstalled) {
|
|
201
|
+
console.info("\n[Code Graph]");
|
|
202
|
+
console.info(" indexing: scanning codebase...");
|
|
203
|
+
const { indexProject } = await import("../../tools/graph-tools.js");
|
|
204
|
+
const result = indexProject(projectRoot);
|
|
205
|
+
if (result.success) {
|
|
206
|
+
console.info(` done: ${result.output}`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
console.info(` error: ${result.output}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
199
212
|
// Summary
|
|
200
213
|
console.info("\nDone!");
|
|
201
214
|
if (!cgcInstalled || !dockerAvailable) {
|
|
@@ -210,7 +223,6 @@ export async function init(projectRoot, options = {}) {
|
|
|
210
223
|
}
|
|
211
224
|
console.info("\nNext steps:");
|
|
212
225
|
console.info(" 1. Edit CLAUDE.md with your project details");
|
|
213
|
-
console.info(" 2.
|
|
214
|
-
console.info(" 3. Start
|
|
215
|
-
console.info(" 4. Start planning: /plan your-first-feature");
|
|
226
|
+
console.info(" 2. Start a Claude Code session — MCP tools will be available");
|
|
227
|
+
console.info(" 3. Start planning: /plan your-first-feature");
|
|
216
228
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { cpSync, existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { globSync } from "glob";
|
|
@@ -14,21 +14,25 @@ export async function update(projectRoot) {
|
|
|
14
14
|
const skillsTarget = join(projectRoot, ".claude/skills");
|
|
15
15
|
const skillFiles = globSync("*.md", { cwd: skillsSource });
|
|
16
16
|
let updated = 0;
|
|
17
|
-
let
|
|
17
|
+
let added = 0;
|
|
18
|
+
let current = 0;
|
|
18
19
|
for (const file of skillFiles) {
|
|
19
20
|
const skillName = file.replace(".md", "");
|
|
20
21
|
const sourceFile = join(skillsSource, file);
|
|
21
|
-
const
|
|
22
|
+
const targetDir = join(skillsTarget, skillName);
|
|
23
|
+
const targetFile = join(targetDir, "SKILL.md");
|
|
22
24
|
if (!existsSync(targetFile)) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
mkdirSync(targetDir, { recursive: true });
|
|
26
|
+
cpSync(sourceFile, targetFile);
|
|
27
|
+
console.info(` added: ${skillName} (new skill)`);
|
|
28
|
+
added++;
|
|
25
29
|
continue;
|
|
26
30
|
}
|
|
27
31
|
const sourceHash = fileHash(sourceFile);
|
|
28
32
|
const targetHash = fileHash(targetFile);
|
|
29
33
|
if (sourceHash === targetHash) {
|
|
30
34
|
console.info(` current: ${skillName}`);
|
|
31
|
-
|
|
35
|
+
current++;
|
|
32
36
|
}
|
|
33
37
|
else {
|
|
34
38
|
cpSync(sourceFile, targetFile);
|
|
@@ -36,5 +40,5 @@ export async function update(projectRoot) {
|
|
|
36
40
|
updated++;
|
|
37
41
|
}
|
|
38
42
|
}
|
|
39
|
-
console.info(`\n${updated} updated, ${
|
|
43
|
+
console.info(`\n${added} added, ${updated} updated, ${current} current.`);
|
|
40
44
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { registerContextTools } from "../tools/context-tools.js";
|
|
5
5
|
import { registerDocumentTools } from "../tools/document-tools.js";
|
|
6
|
+
import { registerGraphTools } from "../tools/graph-tools.js";
|
|
6
7
|
import { registerPlanTools } from "../tools/plan-tools.js";
|
|
7
8
|
import { registerQualityTools } from "../tools/quality-tools.js";
|
|
8
9
|
import { registerSystemTools } from "../tools/system-tools.js";
|
|
@@ -17,6 +18,7 @@ export async function startServer() {
|
|
|
17
18
|
registerQualityTools(server, projectRoot);
|
|
18
19
|
registerDocumentTools(server, projectRoot);
|
|
19
20
|
registerSystemTools(server, projectRoot);
|
|
21
|
+
registerGraphTools(server, projectRoot);
|
|
20
22
|
const transport = new StdioServerTransport();
|
|
21
23
|
await server.connect(transport);
|
|
22
24
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
export declare function indexProject(projectRoot: string): {
|
|
3
|
+
success: boolean;
|
|
4
|
+
output: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function registerGraphTools(server: McpServer, projectRoot: string): void;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
function cgcPath() {
|
|
6
|
+
const paths = [join(process.env.HOME ?? "", ".local/bin/cgc"), "/usr/local/bin/cgc"];
|
|
7
|
+
return paths.find((p) => existsSync(p)) ?? null;
|
|
8
|
+
}
|
|
9
|
+
function runCgc(args, projectRoot) {
|
|
10
|
+
const cgc = cgcPath();
|
|
11
|
+
if (!cgc) {
|
|
12
|
+
return JSON.stringify({ error: "CGC not installed — run: pipx install codegraphcontext" });
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
return execSync(`${cgc} ${args}`, {
|
|
16
|
+
encoding: "utf-8",
|
|
17
|
+
timeout: 60000,
|
|
18
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
19
|
+
cwd: projectRoot,
|
|
20
|
+
env: {
|
|
21
|
+
...process.env,
|
|
22
|
+
DATABASE_TYPE: "falkordb-remote",
|
|
23
|
+
FALKORDB_HOST: process.env.FALKORDB_HOST ?? "localhost",
|
|
24
|
+
FALKORDB_PORT: process.env.FALKORDB_PORT ?? "6379",
|
|
25
|
+
FALKORDB_GRAPH_NAME: process.env.FALKORDB_GRAPH_NAME ?? basename(projectRoot),
|
|
26
|
+
},
|
|
27
|
+
}).trim();
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const execErr = err;
|
|
31
|
+
return JSON.stringify({
|
|
32
|
+
error: execErr.stderr?.trim() || execErr.message || "CGC command failed",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export function indexProject(projectRoot) {
|
|
37
|
+
const cgc = cgcPath();
|
|
38
|
+
if (!cgc) {
|
|
39
|
+
return { success: false, output: "CGC not installed — run: pipx install codegraphcontext" };
|
|
40
|
+
}
|
|
41
|
+
const graphName = process.env.FALKORDB_GRAPH_NAME ?? basename(projectRoot);
|
|
42
|
+
try {
|
|
43
|
+
// Check if .cgcignore exists
|
|
44
|
+
const hasIgnore = existsSync(join(projectRoot, ".cgcignore"));
|
|
45
|
+
const output = execSync(`${cgc} index ${projectRoot}`, {
|
|
46
|
+
encoding: "utf-8",
|
|
47
|
+
timeout: 120000,
|
|
48
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
49
|
+
env: {
|
|
50
|
+
...process.env,
|
|
51
|
+
DATABASE_TYPE: "falkordb-remote",
|
|
52
|
+
FALKORDB_HOST: process.env.FALKORDB_HOST ?? "localhost",
|
|
53
|
+
FALKORDB_PORT: process.env.FALKORDB_PORT ?? "6379",
|
|
54
|
+
FALKORDB_GRAPH_NAME: graphName,
|
|
55
|
+
},
|
|
56
|
+
}).trim();
|
|
57
|
+
return {
|
|
58
|
+
success: true,
|
|
59
|
+
output: `Indexed into graph '${graphName}'${hasIgnore ? " (with .cgcignore)" : " (no .cgcignore — consider creating one)"}. ${output}`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const execErr = err;
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
output: execErr.stderr?.trim() || execErr.message || "Index failed",
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export function registerGraphTools(server, projectRoot) {
|
|
71
|
+
server.registerTool("index_project", {
|
|
72
|
+
description: "Index the project codebase into the code graph. Run this after init or when the codebase has changed significantly. Uses CGC under the hood.",
|
|
73
|
+
}, async () => {
|
|
74
|
+
const result = indexProject(projectRoot);
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
77
|
+
isError: !result.success,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
server.registerTool("query_dependencies", {
|
|
81
|
+
description: "Query what depends on a file or module, and what it depends on. Use BEFORE modifying any file to understand blast radius.",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
target: z.string().describe("File path, function name, or module to query"),
|
|
84
|
+
direction: z
|
|
85
|
+
.enum(["dependents", "dependencies", "both"])
|
|
86
|
+
.default("both")
|
|
87
|
+
.describe("Direction: what depends on this (dependents), what this depends on (dependencies), or both"),
|
|
88
|
+
},
|
|
89
|
+
}, async ({ target, direction }) => {
|
|
90
|
+
let query;
|
|
91
|
+
if (direction === "dependents") {
|
|
92
|
+
query = `MATCH (dependent)-[r]->(target) WHERE target.name CONTAINS '${target}' RETURN dependent.name as dependent, type(r) as relationship, target.name as target`;
|
|
93
|
+
}
|
|
94
|
+
else if (direction === "dependencies") {
|
|
95
|
+
query = `MATCH (source)-[r]->(dep) WHERE source.name CONTAINS '${target}' RETURN source.name as source, type(r) as relationship, dep.name as dependency`;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
query = `MATCH (a)-[r]-(b) WHERE a.name CONTAINS '${target}' RETURN a.name as source, type(r) as relationship, b.name as related ORDER BY relationship`;
|
|
99
|
+
}
|
|
100
|
+
const output = runCgc(`query "${query}"`, projectRoot);
|
|
101
|
+
return {
|
|
102
|
+
content: [{ type: "text", text: output }],
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
server.registerTool("query_graph", {
|
|
106
|
+
description: "Run a custom Cypher query against the code graph. Use for advanced structural queries not covered by query_dependencies.",
|
|
107
|
+
inputSchema: {
|
|
108
|
+
cypher: z.string().describe("Cypher query to execute (read-only)"),
|
|
109
|
+
},
|
|
110
|
+
}, async ({ cypher }) => {
|
|
111
|
+
const output = runCgc(`query "${cypher}"`, projectRoot);
|
|
112
|
+
return {
|
|
113
|
+
content: [{ type: "text", text: output }],
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
package/package.json
CHANGED
package/skills/context.md
CHANGED
|
@@ -78,6 +78,7 @@ After writing a retrospective, read the "Insights Worth Carrying Forward" and "W
|
|
|
78
78
|
- If it changes the project's architecture or structure → update **Architecture**
|
|
79
79
|
- Update **Current State** to reflect the plan's completion
|
|
80
80
|
- If the retrospective's "Quality Ratchet" section adds a new Biome rule, also add the enforced pattern to **Conventions**
|
|
81
|
+
- **REQUIRED: Query the code graph** — call `query_dependencies` on the key files that changed to verify the Architecture section still reflects reality. If the plan changed how modules connect, update Architecture with the new relationships.
|
|
81
82
|
|
|
82
83
|
Do this immediately after writing the retrospective, before moving on.
|
|
83
84
|
|
package/skills/document.md
CHANGED
|
@@ -18,6 +18,8 @@ After context items are done, the document gate asks one question:
|
|
|
18
18
|
|
|
19
19
|
**"Does this phase change something a user or developer needs to know?"**
|
|
20
20
|
|
|
21
|
+
To answer this accurately, **REQUIRED: call `query_dependencies`** on the key files changed in this phase. If the change affects files with many dependents, it likely needs documentation. If it's internal with no downstream consumers, it might not.
|
|
22
|
+
|
|
21
23
|
- If **yes**: write or update the relevant page in `apps/indusk-docs/src/`
|
|
22
24
|
- If **no**: skip — not every phase produces documentation. The gate asks the question but doesn't always produce output.
|
|
23
25
|
|
package/skills/plan.md
CHANGED
|
@@ -31,7 +31,12 @@ General-purpose research (insights useful across plans) also lives in `research/
|
|
|
31
31
|
|
|
32
32
|
1. **Figure out where things stand.** If a plan folder already exists, read what's there. Check frontmatter statuses. The next document to write is the first one that's missing or incomplete.
|
|
33
33
|
|
|
34
|
-
2. **If starting fresh**, create the plan folder and start with research. Explore the problem space — read code, search the web, check Context7 for library docs. **Query the code graph
|
|
34
|
+
2. **If starting fresh**, create the plan folder and start with research. Explore the problem space — read code, search the web, check Context7 for library docs. **REQUIRED: Query the code graph before scoping:**
|
|
35
|
+
- Call `query_dependencies` on the target area to understand what depends on it and what it depends on
|
|
36
|
+
- Call `find_code` to find existing implementations you might reuse or need to modify
|
|
37
|
+
- Call `get_repository_stats` to understand the size of the area you're about to scope
|
|
38
|
+
- Include the graph findings in research.md — concrete numbers like "X has 12 dependents across 3 apps"
|
|
39
|
+
Document what you find. The research doc records findings and analysis, but saves the recommendation for the brief.
|
|
35
40
|
|
|
36
41
|
3. **If research is done**, write the brief. This is where a direction emerges from the research. The brief proposes what we're building and why, informed by what the research uncovered. Present for review.
|
|
37
42
|
|
package/skills/retrospective.md
CHANGED
|
@@ -40,7 +40,16 @@ Key sections to fill in honestly:
|
|
|
40
40
|
- **What We'd Do Differently** — hindsight decisions
|
|
41
41
|
- **Insights Worth Carrying Forward** — takeaways for future plans
|
|
42
42
|
|
|
43
|
-
### Step 2:
|
|
43
|
+
### Step 2: Structural Audit (Code Graph)
|
|
44
|
+
|
|
45
|
+
**REQUIRED:** Before reviewing docs or tests, query the code graph to understand what actually changed:
|
|
46
|
+
|
|
47
|
+
1. Call `query_dependencies` on the key files from this plan — verify the dependency relationships match what was designed
|
|
48
|
+
2. Call `find_most_complex_functions` — check if the plan introduced high-complexity code that should be refactored
|
|
49
|
+
3. Call `find_dead_code` — check if the plan left behind unused functions from refactoring
|
|
50
|
+
4. Include findings in the retrospective under "What Actually Happened" — e.g., "Plan touched 8 files with 23 downstream dependents"
|
|
51
|
+
|
|
52
|
+
### Step 3: Docs Audit
|
|
44
53
|
|
|
45
54
|
Review every documentation page that was written or updated during this plan's impl phases.
|
|
46
55
|
|
|
@@ -52,7 +61,7 @@ For each page:
|
|
|
52
61
|
|
|
53
62
|
Fix any discrepancies found. Plans often diverge from their impl during execution — the docs must reflect reality.
|
|
54
63
|
|
|
55
|
-
### Step
|
|
64
|
+
### Step 4: Test Audit
|
|
56
65
|
|
|
57
66
|
Review the test files created or modified during this plan.
|
|
58
67
|
|
|
@@ -62,7 +71,7 @@ Review the test files created or modified during this plan.
|
|
|
62
71
|
|
|
63
72
|
Flag gaps but don't necessarily fix them all now — add them as items to a follow-up plan if they're significant.
|
|
64
73
|
|
|
65
|
-
### Step
|
|
74
|
+
### Step 5: Quality Audit
|
|
66
75
|
|
|
67
76
|
Review mistakes made during this plan's implementation.
|
|
68
77
|
|
|
@@ -72,7 +81,7 @@ Review mistakes made during this plan's implementation.
|
|
|
72
81
|
|
|
73
82
|
The quality ratchet only gets tighter. Every retrospective is an opportunity to prevent the same class of mistake from happening again.
|
|
74
83
|
|
|
75
|
-
### Step
|
|
84
|
+
### Step 6: Context Audit
|
|
76
85
|
|
|
77
86
|
Re-read CLAUDE.md in full. After the entire impl is done, verify:
|
|
78
87
|
|
|
@@ -84,7 +93,7 @@ Re-read CLAUDE.md in full. After the entire impl is done, verify:
|
|
|
84
93
|
|
|
85
94
|
Fix any inaccuracies. The impl may have changed things that weren't anticipated in the per-phase context updates.
|
|
86
95
|
|
|
87
|
-
### Step
|
|
96
|
+
### Step 7: Knowledge Handoff
|
|
88
97
|
|
|
89
98
|
Distill planning artifacts into the docs site so the knowledge survives archival.
|
|
90
99
|
|
|
@@ -103,7 +112,7 @@ Not every plan produces a lessons page — only create one if the insights are g
|
|
|
103
112
|
|
|
104
113
|
**Update sidebar:** Add new decision/lesson pages to the VitePress sidebar config in `apps/indusk-docs/src/.vitepress/config.ts`.
|
|
105
114
|
|
|
106
|
-
### Step
|
|
115
|
+
### Step 8: Archival
|
|
107
116
|
|
|
108
117
|
Move the planning artifacts to the archive:
|
|
109
118
|
|
package/skills/toolbelt.md
CHANGED
|
@@ -57,24 +57,46 @@ These come from the codegraphcontext MCP server:
|
|
|
57
57
|
| Check for dead code | `find_dead_code` |
|
|
58
58
|
| Scope a plan during research | `analyze_code_relationships` on the target area |
|
|
59
59
|
| Custom graph queries | `execute_cypher_query` |
|
|
60
|
+
| Visualize the graph | `visualize_graph_query` — returns a browser link to view the graph |
|
|
61
|
+
| Get repo stats | `get_repository_stats` |
|
|
62
|
+
| See what's indexed | `list_indexed_repositories` |
|
|
63
|
+
|
|
64
|
+
### Visualizing the Code Graph
|
|
65
|
+
|
|
66
|
+
When the user asks to "show the graph", "display dependencies", or "visualize":
|
|
67
|
+
|
|
68
|
+
1. Call `visualize_graph_query` with a Cypher query like `MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 100` — this returns a URL to open in the browser.
|
|
69
|
+
2. For a specific file's dependencies: `MATCH (n)-[r]->(m) WHERE n.name CONTAINS 'filename' RETURN n, r, m`
|
|
70
|
+
3. For the full project overview: `MATCH (n) RETURN n LIMIT 200`
|
|
71
|
+
|
|
72
|
+
If the user wants text-based output instead, use `execute_cypher_query` directly and format the results as a table or list.
|
|
60
73
|
|
|
61
74
|
## Tool Reference
|
|
62
75
|
|
|
63
|
-
### indusk (
|
|
76
|
+
### indusk (17 tools)
|
|
64
77
|
|
|
65
78
|
| Tool | When to use |
|
|
66
79
|
|------|-------------|
|
|
80
|
+
| **Graph (use these constantly)** | |
|
|
81
|
+
| `index_project` | After init, or when codebase changed significantly |
|
|
82
|
+
| `query_dependencies` | **BEFORE modifying any file** — understand blast radius |
|
|
83
|
+
| `query_graph` | Custom Cypher queries for advanced structural analysis |
|
|
84
|
+
| **Plans** | |
|
|
67
85
|
| `list_plans` | Session start, orientation |
|
|
68
86
|
| `get_plan_status` | Before working on a plan, checking progress |
|
|
69
87
|
| `advance_plan` | End of every phase — validates all gates |
|
|
70
88
|
| `order_plans` | Understanding plan dependencies |
|
|
89
|
+
| **Context** | |
|
|
71
90
|
| `get_context` | Session start, after context updates |
|
|
72
91
|
| `update_context` | Updating CLAUDE.md sections programmatically |
|
|
92
|
+
| **Quality** | |
|
|
73
93
|
| `get_quality_config` | Reviewing Biome rules, after retros |
|
|
74
94
|
| `suggest_rule` | Finding Biome rules for new patterns |
|
|
75
95
|
| `quality_check` | After verification items, before advancing |
|
|
96
|
+
| **Docs** | |
|
|
76
97
|
| `list_docs` | After document items, checking coverage |
|
|
77
98
|
| `check_docs_coverage` | After retros, finding doc gaps |
|
|
99
|
+
| **System** | |
|
|
78
100
|
| `get_system_version` | Debugging, version checks |
|
|
79
101
|
| `get_skill_versions` | Checking for outdated skills |
|
|
80
102
|
| `check_health` | Session start, debugging connectivity |
|
package/skills/verify.md
CHANGED
|
@@ -56,7 +56,7 @@ When the work skill is executing an impl and reaches verification items, run che
|
|
|
56
56
|
- Skip for: markdown changes, config-only changes with no test files
|
|
57
57
|
- Catches: behavioral regressions, broken logic
|
|
58
58
|
- Run affected app's tests, not the full suite
|
|
59
|
-
- **Use the code graph to find affected tests** —
|
|
59
|
+
- **REQUIRED: Use the code graph to find affected tests** — call `query_dependencies` on the changed file with direction "dependents" to discover which test files import or depend on it. Run those tests specifically rather than guessing. Do not skip this step.
|
|
60
60
|
|
|
61
61
|
4. **Build** — `pnpm turbo build --filter={app}`
|
|
62
62
|
- Only for: shared package changes, build config changes
|
package/skills/work.md
CHANGED
|
@@ -25,12 +25,12 @@ Implementation plans live in `planning/{plan-name}/impl.md` as checklists. Your
|
|
|
25
25
|
5. **Work through the checklist in order.**
|
|
26
26
|
- Start from the first unchecked item (`- [ ]`)
|
|
27
27
|
- For each item:
|
|
28
|
-
a. **Query the code graph
|
|
29
|
-
b. **Check for existing code** — before writing new functions,
|
|
28
|
+
a. **REQUIRED: Query the code graph** — before modifying ANY file, call `query_dependencies` on that file. Review the dependents list. If >3 dependents, flag the blast radius to the user before proceeding. This is not optional.
|
|
29
|
+
b. **REQUIRED: Check for existing code** — before writing new functions, call `find_code` to search for functions that already do what you need. Reuse and extend existing code rather than duplicating. Stay DRY.
|
|
30
30
|
c. Read the relevant source files
|
|
31
31
|
d. Implement the change
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
e. Immediately edit impl.md to check the item off (`- [ ]` → `- [x]`)
|
|
33
|
+
f. Move to the next item
|
|
34
34
|
- Do NOT skip ahead or work out of order unless there's a dependency reason
|
|
35
35
|
- Do NOT batch checklist updates — check each off as soon as it's done
|
|
36
36
|
|