typegraph-mcp 0.9.32 → 0.9.34
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 +1 -1
- package/check.ts +48 -2
- package/cli.ts +35 -24
- package/dist/check.js +36 -2
- package/dist/cli.js +68 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,7 +142,7 @@ npx typegraph-mcp check
|
|
|
142
142
|
| Symptom | Fix |
|
|
143
143
|
|---|---|
|
|
144
144
|
| Server won't start | `cd plugins/typegraph-mcp && npm install --include=optional` |
|
|
145
|
-
| "TypeScript not found" |
|
|
145
|
+
| "TypeScript not found" | Run `pnpm install` or `npm install`; if TypeScript is not declared, add it to devDependencies first |
|
|
146
146
|
| Tools return empty results | Check `TYPEGRAPH_TSCONFIG` points to the right tsconfig |
|
|
147
147
|
| Build errors from plugins/ | Add `"plugins/**"` to tsconfig.json `exclude` array |
|
|
148
148
|
| `@esbuild/*` or `@rollup/*` package missing | Reinstall with Node 22: `npm install --include=optional` |
|
package/check.ts
CHANGED
|
@@ -162,6 +162,45 @@ function hasTrustedCodexProject(projectRoot: string): boolean | null {
|
|
|
162
162
|
return matchesTrustedProject();
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
function readProjectPackageJson(projectRoot: string): Record<string, unknown> | null {
|
|
166
|
+
const packageJsonPath = path.resolve(projectRoot, "package.json");
|
|
167
|
+
if (!fs.existsSync(packageJsonPath)) return null;
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
return JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) as Record<string, unknown>;
|
|
171
|
+
} catch {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getProjectInstallCommand(projectRoot: string, packageJson: Record<string, unknown> | null): string {
|
|
177
|
+
const packageManager = typeof packageJson?.["packageManager"] === "string"
|
|
178
|
+
? packageJson["packageManager"]
|
|
179
|
+
: "";
|
|
180
|
+
|
|
181
|
+
if (packageManager.startsWith("pnpm@") || fs.existsSync(path.join(projectRoot, "pnpm-lock.yaml"))) {
|
|
182
|
+
return "pnpm install";
|
|
183
|
+
}
|
|
184
|
+
if (packageManager.startsWith("yarn@") || fs.existsSync(path.join(projectRoot, "yarn.lock"))) {
|
|
185
|
+
return "yarn install";
|
|
186
|
+
}
|
|
187
|
+
return "npm install";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function hasDeclaredDependency(packageJson: Record<string, unknown> | null, packageName: string): boolean {
|
|
191
|
+
const depKeys = [
|
|
192
|
+
"dependencies",
|
|
193
|
+
"devDependencies",
|
|
194
|
+
"peerDependencies",
|
|
195
|
+
"optionalDependencies",
|
|
196
|
+
] as const;
|
|
197
|
+
|
|
198
|
+
return depKeys.some((key) => {
|
|
199
|
+
const deps = packageJson?.[key];
|
|
200
|
+
return typeof deps === "object" && deps !== null && packageName in deps;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
165
204
|
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
166
205
|
|
|
167
206
|
export async function main(configOverride?: TypegraphConfig): Promise<CheckResult> {
|
|
@@ -171,6 +210,8 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
|
|
|
171
210
|
let passed = 0;
|
|
172
211
|
let failed = 0;
|
|
173
212
|
let warned = 0;
|
|
213
|
+
const projectPackageJson = readProjectPackageJson(projectRoot);
|
|
214
|
+
const installCommand = getProjectInstallCommand(projectRoot, projectPackageJson);
|
|
174
215
|
|
|
175
216
|
function pass(msg: string): void {
|
|
176
217
|
console.log(` \u2713 ${msg}`);
|
|
@@ -228,9 +269,14 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
|
|
|
228
269
|
tsVersion = tsPkg.version;
|
|
229
270
|
pass(`TypeScript found (v${tsVersion})`);
|
|
230
271
|
} catch {
|
|
272
|
+
const hasDeclaredTs = hasDeclaredDependency(projectPackageJson, "typescript");
|
|
231
273
|
fail(
|
|
232
|
-
|
|
233
|
-
|
|
274
|
+
hasDeclaredTs
|
|
275
|
+
? "TypeScript is declared but not installed in project"
|
|
276
|
+
: "TypeScript not found in project",
|
|
277
|
+
hasDeclaredTs
|
|
278
|
+
? `Run \`${installCommand}\` to install project dependencies`
|
|
279
|
+
: `Add \`typescript\` to devDependencies and run \`${installCommand}\``
|
|
234
280
|
);
|
|
235
281
|
}
|
|
236
282
|
|
package/cli.ts
CHANGED
|
@@ -40,10 +40,25 @@ interface AgentDef {
|
|
|
40
40
|
const AGENT_SNIPPET = `
|
|
41
41
|
## TypeScript Navigation (typegraph-mcp)
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Where suitable, use the \`ts_*\` MCP tools instead of grep/glob for navigating TypeScript code. They resolve through barrel files, re-exports, and project references and return semantic results instead of string matches.
|
|
44
44
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
45
|
+
- Point queries: \`ts_find_symbol\`, \`ts_definition\`, \`ts_references\`, \`ts_type_info\`, \`ts_navigate_to\`, \`ts_trace_chain\`, \`ts_blast_radius\`, \`ts_module_exports\`
|
|
46
|
+
- Graph queries: \`ts_dependency_tree\`, \`ts_dependents\`, \`ts_import_cycles\`, \`ts_shortest_path\`, \`ts_subgraph\`, \`ts_module_boundary\`
|
|
47
|
+
|
|
48
|
+
Start with the navigation tools before reading entire files. Use direct file reads only after the MCP tools identify the exact symbols or lines that matter.
|
|
49
|
+
|
|
50
|
+
Use \`rg\` or \`grep\` when semantic symbol navigation is not the right tool, especially for:
|
|
51
|
+
|
|
52
|
+
- docs, config, SQL, migrations, JSON, env vars, route strings, and other non-TypeScript assets
|
|
53
|
+
- broad text discovery when you do not yet know the symbol name
|
|
54
|
+
- exact string matching across the repo
|
|
55
|
+
- validating wording or finding repeated plan/document references
|
|
56
|
+
|
|
57
|
+
Practical rule:
|
|
58
|
+
|
|
59
|
+
- use \`ts_*\` first for TypeScript symbol definition, references, types, and dependency analysis
|
|
60
|
+
- use \`rg\`/\`grep\` for text search and non-TypeScript exploration
|
|
61
|
+
- combine both when a task spans TypeScript code and surrounding docs/config
|
|
47
62
|
`.trimStart();
|
|
48
63
|
|
|
49
64
|
const SNIPPET_MARKER = "## TypeScript Navigation (typegraph-mcp)";
|
|
@@ -808,39 +823,35 @@ async function setupAgentInstructions(projectRoot: string, selectedAgents: Agent
|
|
|
808
823
|
return; // No agents with instruction files selected (e.g. Cursor only)
|
|
809
824
|
}
|
|
810
825
|
|
|
811
|
-
//
|
|
826
|
+
// Ensure each selected agent file exists and has the snippet once. Resolve
|
|
827
|
+
// symlinks to avoid writing duplicate content through multiple aliases.
|
|
812
828
|
const seenRealPaths = new Map<string, string>(); // realPath -> first agentFile name
|
|
813
|
-
const existingFiles: { file: string; realPath: string; hasSnippet: boolean }[] = [];
|
|
814
829
|
for (const agentFile of agentFiles) {
|
|
815
830
|
const filePath = path.resolve(projectRoot, agentFile);
|
|
816
|
-
if (!fs.existsSync(filePath))
|
|
817
|
-
|
|
831
|
+
if (!fs.existsSync(filePath)) {
|
|
832
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
833
|
+
fs.writeFileSync(filePath, AGENT_SNIPPET + "\n");
|
|
834
|
+
p.log.success(`${agentFile}: created with typegraph-mcp instructions`);
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
818
837
|
|
|
838
|
+
const realPath = fs.realpathSync(filePath);
|
|
819
839
|
const previousFile = seenRealPaths.get(realPath);
|
|
820
840
|
if (previousFile) {
|
|
821
841
|
p.log.info(`${agentFile}: same file as ${previousFile} (skipped)`);
|
|
822
842
|
continue;
|
|
823
843
|
}
|
|
824
|
-
seenRealPaths.set(realPath, agentFile);
|
|
825
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
826
|
-
existingFiles.push({ file: agentFile, realPath, hasSnippet: content.includes(SNIPPET_MARKER) });
|
|
827
|
-
}
|
|
828
844
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
if (f.hasSnippet) {
|
|
835
|
-
p.log.info(`${f.file}: already has typegraph-mcp instructions`);
|
|
836
|
-
}
|
|
845
|
+
seenRealPaths.set(realPath, agentFile);
|
|
846
|
+
const content = fs.readFileSync(realPath, "utf-8");
|
|
847
|
+
if (content.includes(SNIPPET_MARKER)) {
|
|
848
|
+
p.log.info(`${agentFile}: already has typegraph-mcp instructions`);
|
|
849
|
+
continue;
|
|
837
850
|
}
|
|
838
|
-
|
|
839
|
-
const target = existingFiles[0]!;
|
|
840
|
-
const content = fs.readFileSync(target.realPath, "utf-8");
|
|
851
|
+
|
|
841
852
|
const appendContent = (content.endsWith("\n") ? "" : "\n") + "\n" + AGENT_SNIPPET;
|
|
842
|
-
fs.appendFileSync(
|
|
843
|
-
p.log.success(`${
|
|
853
|
+
fs.appendFileSync(realPath, appendContent);
|
|
854
|
+
p.log.success(`${agentFile}: appended typegraph-mcp instructions`);
|
|
844
855
|
}
|
|
845
856
|
|
|
846
857
|
// Update --plugin-dir line in CLAUDE.md if Claude Code is selected
|
package/dist/check.js
CHANGED
|
@@ -472,11 +472,44 @@ function hasTrustedCodexProject(projectRoot) {
|
|
|
472
472
|
}
|
|
473
473
|
return matchesTrustedProject();
|
|
474
474
|
}
|
|
475
|
+
function readProjectPackageJson(projectRoot) {
|
|
476
|
+
const packageJsonPath = path3.resolve(projectRoot, "package.json");
|
|
477
|
+
if (!fs2.existsSync(packageJsonPath)) return null;
|
|
478
|
+
try {
|
|
479
|
+
return JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
|
|
480
|
+
} catch {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function getProjectInstallCommand(projectRoot, packageJson) {
|
|
485
|
+
const packageManager = typeof packageJson?.["packageManager"] === "string" ? packageJson["packageManager"] : "";
|
|
486
|
+
if (packageManager.startsWith("pnpm@") || fs2.existsSync(path3.join(projectRoot, "pnpm-lock.yaml"))) {
|
|
487
|
+
return "pnpm install";
|
|
488
|
+
}
|
|
489
|
+
if (packageManager.startsWith("yarn@") || fs2.existsSync(path3.join(projectRoot, "yarn.lock"))) {
|
|
490
|
+
return "yarn install";
|
|
491
|
+
}
|
|
492
|
+
return "npm install";
|
|
493
|
+
}
|
|
494
|
+
function hasDeclaredDependency(packageJson, packageName) {
|
|
495
|
+
const depKeys = [
|
|
496
|
+
"dependencies",
|
|
497
|
+
"devDependencies",
|
|
498
|
+
"peerDependencies",
|
|
499
|
+
"optionalDependencies"
|
|
500
|
+
];
|
|
501
|
+
return depKeys.some((key) => {
|
|
502
|
+
const deps = packageJson?.[key];
|
|
503
|
+
return typeof deps === "object" && deps !== null && packageName in deps;
|
|
504
|
+
});
|
|
505
|
+
}
|
|
475
506
|
async function main(configOverride) {
|
|
476
507
|
const { projectRoot, tsconfigPath, toolDir, toolIsEmbedded, toolRelPath } = configOverride ?? resolveConfig(import.meta.dirname);
|
|
477
508
|
let passed = 0;
|
|
478
509
|
let failed = 0;
|
|
479
510
|
let warned = 0;
|
|
511
|
+
const projectPackageJson = readProjectPackageJson(projectRoot);
|
|
512
|
+
const installCommand = getProjectInstallCommand(projectRoot, projectPackageJson);
|
|
480
513
|
function pass(msg) {
|
|
481
514
|
console.log(` \u2713 ${msg}`);
|
|
482
515
|
passed++;
|
|
@@ -522,9 +555,10 @@ async function main(configOverride) {
|
|
|
522
555
|
tsVersion = tsPkg.version;
|
|
523
556
|
pass(`TypeScript found (v${tsVersion})`);
|
|
524
557
|
} catch {
|
|
558
|
+
const hasDeclaredTs = hasDeclaredDependency(projectPackageJson, "typescript");
|
|
525
559
|
fail(
|
|
526
|
-
"TypeScript not found in project",
|
|
527
|
-
|
|
560
|
+
hasDeclaredTs ? "TypeScript is declared but not installed in project" : "TypeScript not found in project",
|
|
561
|
+
hasDeclaredTs ? `Run \`${installCommand}\` to install project dependencies` : `Add \`typescript\` to devDependencies and run \`${installCommand}\``
|
|
528
562
|
);
|
|
529
563
|
}
|
|
530
564
|
const tsconfigAbs = path3.resolve(projectRoot, tsconfigPath);
|
package/dist/cli.js
CHANGED
|
@@ -479,11 +479,44 @@ function hasTrustedCodexProject(projectRoot3) {
|
|
|
479
479
|
}
|
|
480
480
|
return matchesTrustedProject();
|
|
481
481
|
}
|
|
482
|
+
function readProjectPackageJson(projectRoot3) {
|
|
483
|
+
const packageJsonPath = path3.resolve(projectRoot3, "package.json");
|
|
484
|
+
if (!fs2.existsSync(packageJsonPath)) return null;
|
|
485
|
+
try {
|
|
486
|
+
return JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
|
|
487
|
+
} catch {
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function getProjectInstallCommand(projectRoot3, packageJson) {
|
|
492
|
+
const packageManager = typeof packageJson?.["packageManager"] === "string" ? packageJson["packageManager"] : "";
|
|
493
|
+
if (packageManager.startsWith("pnpm@") || fs2.existsSync(path3.join(projectRoot3, "pnpm-lock.yaml"))) {
|
|
494
|
+
return "pnpm install";
|
|
495
|
+
}
|
|
496
|
+
if (packageManager.startsWith("yarn@") || fs2.existsSync(path3.join(projectRoot3, "yarn.lock"))) {
|
|
497
|
+
return "yarn install";
|
|
498
|
+
}
|
|
499
|
+
return "npm install";
|
|
500
|
+
}
|
|
501
|
+
function hasDeclaredDependency(packageJson, packageName) {
|
|
502
|
+
const depKeys = [
|
|
503
|
+
"dependencies",
|
|
504
|
+
"devDependencies",
|
|
505
|
+
"peerDependencies",
|
|
506
|
+
"optionalDependencies"
|
|
507
|
+
];
|
|
508
|
+
return depKeys.some((key) => {
|
|
509
|
+
const deps = packageJson?.[key];
|
|
510
|
+
return typeof deps === "object" && deps !== null && packageName in deps;
|
|
511
|
+
});
|
|
512
|
+
}
|
|
482
513
|
async function main(configOverride) {
|
|
483
514
|
const { projectRoot: projectRoot3, tsconfigPath: tsconfigPath3, toolDir, toolIsEmbedded, toolRelPath } = configOverride ?? resolveConfig(import.meta.dirname);
|
|
484
515
|
let passed = 0;
|
|
485
516
|
let failed = 0;
|
|
486
517
|
let warned = 0;
|
|
518
|
+
const projectPackageJson = readProjectPackageJson(projectRoot3);
|
|
519
|
+
const installCommand = getProjectInstallCommand(projectRoot3, projectPackageJson);
|
|
487
520
|
function pass(msg) {
|
|
488
521
|
console.log(` \u2713 ${msg}`);
|
|
489
522
|
passed++;
|
|
@@ -493,9 +526,9 @@ async function main(configOverride) {
|
|
|
493
526
|
console.log(` Fix: ${fix}`);
|
|
494
527
|
failed++;
|
|
495
528
|
}
|
|
496
|
-
function warn(msg,
|
|
529
|
+
function warn(msg, note) {
|
|
497
530
|
console.log(` ! ${msg}`);
|
|
498
|
-
console.log(` ${
|
|
531
|
+
console.log(` ${note}`);
|
|
499
532
|
warned++;
|
|
500
533
|
}
|
|
501
534
|
function skip(msg) {
|
|
@@ -529,9 +562,10 @@ async function main(configOverride) {
|
|
|
529
562
|
tsVersion = tsPkg.version;
|
|
530
563
|
pass(`TypeScript found (v${tsVersion})`);
|
|
531
564
|
} catch {
|
|
565
|
+
const hasDeclaredTs = hasDeclaredDependency(projectPackageJson, "typescript");
|
|
532
566
|
fail(
|
|
533
|
-
"TypeScript not found in project",
|
|
534
|
-
|
|
567
|
+
hasDeclaredTs ? "TypeScript is declared but not installed in project" : "TypeScript not found in project",
|
|
568
|
+
hasDeclaredTs ? `Run \`${installCommand}\` to install project dependencies` : `Add \`typescript\` to devDependencies and run \`${installCommand}\``
|
|
535
569
|
);
|
|
536
570
|
}
|
|
537
571
|
const tsconfigAbs = path3.resolve(projectRoot3, tsconfigPath3);
|
|
@@ -2881,10 +2915,25 @@ import * as p from "@clack/prompts";
|
|
|
2881
2915
|
var AGENT_SNIPPET = `
|
|
2882
2916
|
## TypeScript Navigation (typegraph-mcp)
|
|
2883
2917
|
|
|
2884
|
-
|
|
2918
|
+
Where suitable, use the \`ts_*\` MCP tools instead of grep/glob for navigating TypeScript code. They resolve through barrel files, re-exports, and project references and return semantic results instead of string matches.
|
|
2919
|
+
|
|
2920
|
+
- Point queries: \`ts_find_symbol\`, \`ts_definition\`, \`ts_references\`, \`ts_type_info\`, \`ts_navigate_to\`, \`ts_trace_chain\`, \`ts_blast_radius\`, \`ts_module_exports\`
|
|
2921
|
+
- Graph queries: \`ts_dependency_tree\`, \`ts_dependents\`, \`ts_import_cycles\`, \`ts_shortest_path\`, \`ts_subgraph\`, \`ts_module_boundary\`
|
|
2922
|
+
|
|
2923
|
+
Start with the navigation tools before reading entire files. Use direct file reads only after the MCP tools identify the exact symbols or lines that matter.
|
|
2885
2924
|
|
|
2886
|
-
|
|
2887
|
-
|
|
2925
|
+
Use \`rg\` or \`grep\` when semantic symbol navigation is not the right tool, especially for:
|
|
2926
|
+
|
|
2927
|
+
- docs, config, SQL, migrations, JSON, env vars, route strings, and other non-TypeScript assets
|
|
2928
|
+
- broad text discovery when you do not yet know the symbol name
|
|
2929
|
+
- exact string matching across the repo
|
|
2930
|
+
- validating wording or finding repeated plan/document references
|
|
2931
|
+
|
|
2932
|
+
Practical rule:
|
|
2933
|
+
|
|
2934
|
+
- use \`ts_*\` first for TypeScript symbol definition, references, types, and dependency analysis
|
|
2935
|
+
- use \`rg\`/\`grep\` for text search and non-TypeScript exploration
|
|
2936
|
+
- combine both when a task spans TypeScript code and surrounding docs/config
|
|
2888
2937
|
`.trimStart();
|
|
2889
2938
|
var SNIPPET_MARKER = "## TypeScript Navigation (typegraph-mcp)";
|
|
2890
2939
|
var PLUGIN_DIR_NAME = "plugins/typegraph-mcp";
|
|
@@ -3462,10 +3511,14 @@ async function setupAgentInstructions(projectRoot3, selectedAgents) {
|
|
|
3462
3511
|
return;
|
|
3463
3512
|
}
|
|
3464
3513
|
const seenRealPaths = /* @__PURE__ */ new Map();
|
|
3465
|
-
const existingFiles = [];
|
|
3466
3514
|
for (const agentFile of agentFiles) {
|
|
3467
3515
|
const filePath = path9.resolve(projectRoot3, agentFile);
|
|
3468
|
-
if (!fs8.existsSync(filePath))
|
|
3516
|
+
if (!fs8.existsSync(filePath)) {
|
|
3517
|
+
fs8.mkdirSync(path9.dirname(filePath), { recursive: true });
|
|
3518
|
+
fs8.writeFileSync(filePath, AGENT_SNIPPET + "\n");
|
|
3519
|
+
p.log.success(`${agentFile}: created with typegraph-mcp instructions`);
|
|
3520
|
+
continue;
|
|
3521
|
+
}
|
|
3469
3522
|
const realPath = fs8.realpathSync(filePath);
|
|
3470
3523
|
const previousFile = seenRealPaths.get(realPath);
|
|
3471
3524
|
if (previousFile) {
|
|
@@ -3473,24 +3526,14 @@ async function setupAgentInstructions(projectRoot3, selectedAgents) {
|
|
|
3473
3526
|
continue;
|
|
3474
3527
|
}
|
|
3475
3528
|
seenRealPaths.set(realPath, agentFile);
|
|
3476
|
-
const content = fs8.readFileSync(
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
p.log.warn(`No agent instruction files found (${agentFiles.join(", ")})`);
|
|
3481
|
-
p.note(AGENT_SNIPPET, "Add this snippet to your agent instructions file");
|
|
3482
|
-
} else if (existingFiles.some((f) => f.hasSnippet)) {
|
|
3483
|
-
for (const f of existingFiles) {
|
|
3484
|
-
if (f.hasSnippet) {
|
|
3485
|
-
p.log.info(`${f.file}: already has typegraph-mcp instructions`);
|
|
3486
|
-
}
|
|
3529
|
+
const content = fs8.readFileSync(realPath, "utf-8");
|
|
3530
|
+
if (content.includes(SNIPPET_MARKER)) {
|
|
3531
|
+
p.log.info(`${agentFile}: already has typegraph-mcp instructions`);
|
|
3532
|
+
continue;
|
|
3487
3533
|
}
|
|
3488
|
-
} else {
|
|
3489
|
-
const target = existingFiles[0];
|
|
3490
|
-
const content = fs8.readFileSync(target.realPath, "utf-8");
|
|
3491
3534
|
const appendContent = (content.endsWith("\n") ? "" : "\n") + "\n" + AGENT_SNIPPET;
|
|
3492
|
-
fs8.appendFileSync(
|
|
3493
|
-
p.log.success(`${
|
|
3535
|
+
fs8.appendFileSync(realPath, appendContent);
|
|
3536
|
+
p.log.success(`${agentFile}: appended typegraph-mcp instructions`);
|
|
3494
3537
|
}
|
|
3495
3538
|
if (selectedAgents.includes("claude-code")) {
|
|
3496
3539
|
const claudeMdPath = path9.resolve(projectRoot3, "CLAUDE.md");
|