typegraph-mcp 0.9.21 → 0.9.23

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 CHANGED
@@ -143,6 +143,7 @@ npx typegraph-mcp check
143
143
  | "TypeScript not found" | Add `typescript` to devDependencies |
144
144
  | Tools return empty results | Check `TYPEGRAPH_TSCONFIG` points to the right tsconfig |
145
145
  | Build errors from plugins/ | Add `"plugins/**"` to tsconfig.json `exclude` array |
146
+ | "npm warn Unknown project config" | Safe to ignore — caused by pnpm settings in your `.npmrc` that npm doesn't recognize |
146
147
 
147
148
  ## Manual MCP configuration
148
149
 
package/check.ts CHANGED
@@ -371,8 +371,10 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
371
371
 
372
372
  // 11. ESLint ignores (only when typegraph-mcp is embedded inside the project)
373
373
  if (toolIsEmbedded) {
374
- const eslintConfigPath = path.resolve(projectRoot, "eslint.config.mjs");
375
- if (fs.existsSync(eslintConfigPath)) {
374
+ const eslintConfigNames = ["eslint.config.mjs", "eslint.config.js", "eslint.config.ts", "eslint.config.cjs"];
375
+ const eslintConfigFile = eslintConfigNames.find((name) => fs.existsSync(path.resolve(projectRoot, name)));
376
+ if (eslintConfigFile) {
377
+ const eslintConfigPath = path.resolve(projectRoot, eslintConfigFile);
376
378
  const eslintContent = fs.readFileSync(eslintConfigPath, "utf-8");
377
379
  // Determine the parent directory (e.g. "plugins") for the ignore pattern
378
380
  const parentDir = path.basename(path.dirname(toolDir));
@@ -384,11 +386,11 @@ export async function main(configOverride?: TypegraphConfig): Promise<CheckResul
384
386
  } else {
385
387
  fail(
386
388
  `ESLint missing ignore: "${parentDir}/**"`,
387
- `Add to the ignores array in eslint.config.mjs:\n "${parentDir}/**",`
389
+ `Add to the ignores array in ${eslintConfigFile}:\n "${parentDir}/**",`
388
390
  );
389
391
  }
390
392
  } else {
391
- skip("ESLint config check (no eslint.config.mjs)");
393
+ skip("ESLint config check (no eslint flat config found)");
392
394
  }
393
395
  } else {
394
396
  skip("ESLint config check (typegraph-mcp is external to project)");
package/cli.ts CHANGED
@@ -362,6 +362,51 @@ function ensureTsconfigExclude(projectRoot: string): void {
362
362
  }
363
363
  }
364
364
 
365
+ // ─── ESLint Ignore ───────────────────────────────────────────────────────────
366
+
367
+ function ensureEslintIgnore(projectRoot: string): void {
368
+ const eslintConfigNames = ["eslint.config.mjs", "eslint.config.js", "eslint.config.ts", "eslint.config.cjs"];
369
+ const eslintConfigFile = eslintConfigNames.find((name) => fs.existsSync(path.resolve(projectRoot, name)));
370
+ if (!eslintConfigFile) return;
371
+ const eslintConfigPath = path.resolve(projectRoot, eslintConfigFile);
372
+
373
+ try {
374
+ const raw = fs.readFileSync(eslintConfigPath, "utf-8");
375
+ const pattern = /["']plugins\/\*\*["']/;
376
+ if (pattern.test(raw)) return; // Already ignored
377
+
378
+ // Strategy 1: Append to an existing ignores array
379
+ const ignoresArrayRe = /(ignores\s*:\s*\[)([\s\S]*?)(\])/;
380
+ const match = raw.match(ignoresArrayRe);
381
+ if (match) {
382
+ const updated = raw.replace(ignoresArrayRe, (_m, open, items, close) => {
383
+ const trimmed = items.trimEnd();
384
+ const needsComma = trimmed.length > 0 && !trimmed.endsWith(",");
385
+ return `${open}${items.trimEnd()}${needsComma ? "," : ""} "plugins/**"${close}`;
386
+ });
387
+ fs.writeFileSync(eslintConfigPath, updated);
388
+ p.log.success(`Added "plugins/**" to ${eslintConfigFile} ignores`);
389
+ return;
390
+ }
391
+
392
+ // Strategy 2: Insert a new ignores object at the start of the exported array
393
+ // Matches: export default [ or export default tseslint.config(
394
+ const exportArrayRe = /(export\s+default\s+(?:\w+\.config\(|\[))\s*\n?/;
395
+ if (exportArrayRe.test(raw)) {
396
+ const updated = raw.replace(exportArrayRe, (m) => {
397
+ return `${m} { ignores: ["plugins/**"] },\n`;
398
+ });
399
+ fs.writeFileSync(eslintConfigPath, updated);
400
+ p.log.success(`Added "plugins/**" to ${eslintConfigFile} ignores`);
401
+ return;
402
+ }
403
+
404
+ p.log.warn(`Could not patch ${eslintConfigFile} — manually add "plugins/**" to the ignores array`);
405
+ } catch {
406
+ p.log.warn(`Could not update ${eslintConfigFile} — manually add "plugins/**" to the ignores array`);
407
+ }
408
+ }
409
+
365
410
  // ─── Agent Selection ─────────────────────────────────────────────────────────
366
411
 
367
412
  function detectAgents(projectRoot: string): AgentId[] {
@@ -564,7 +609,10 @@ async function setup(yes: boolean): Promise<void> {
564
609
  // 8. Ensure plugins/ is excluded from tsconfig
565
610
  ensureTsconfigExclude(projectRoot);
566
611
 
567
- // 9. Verification
612
+ // 9. Ensure plugins/ is ignored by ESLint
613
+ ensureEslintIgnore(projectRoot);
614
+
615
+ // 10. Verification
568
616
  await runVerification(targetDir, selectedAgents);
569
617
  }
570
618
 
@@ -808,6 +856,9 @@ const command = args.find((a) => !a.startsWith("-"));
808
856
  const yes = args.includes("--yes") || args.includes("-y");
809
857
  const help = args.includes("--help") || args.includes("-h");
810
858
 
859
+ // Clear npx download noise (warnings, "Ok to proceed?" prompt)
860
+ process.stdout.write("\x1Bc");
861
+
811
862
  if (help || !command) {
812
863
  console.log(HELP);
813
864
  process.exit(0);
package/dist/check.js CHANGED
@@ -663,8 +663,10 @@ async function main(configOverride) {
663
663
  );
664
664
  }
665
665
  if (toolIsEmbedded) {
666
- const eslintConfigPath = path3.resolve(projectRoot, "eslint.config.mjs");
667
- if (fs2.existsSync(eslintConfigPath)) {
666
+ const eslintConfigNames = ["eslint.config.mjs", "eslint.config.js", "eslint.config.ts", "eslint.config.cjs"];
667
+ const eslintConfigFile = eslintConfigNames.find((name) => fs2.existsSync(path3.resolve(projectRoot, name)));
668
+ if (eslintConfigFile) {
669
+ const eslintConfigPath = path3.resolve(projectRoot, eslintConfigFile);
668
670
  const eslintContent = fs2.readFileSync(eslintConfigPath, "utf-8");
669
671
  const parentDir = path3.basename(path3.dirname(toolDir));
670
672
  const parentIgnorePattern = new RegExp(`["']${parentDir}\\/\\*\\*["']`);
@@ -674,12 +676,12 @@ async function main(configOverride) {
674
676
  } else {
675
677
  fail(
676
678
  `ESLint missing ignore: "${parentDir}/**"`,
677
- `Add to the ignores array in eslint.config.mjs:
679
+ `Add to the ignores array in ${eslintConfigFile}:
678
680
  "${parentDir}/**",`
679
681
  );
680
682
  }
681
683
  } else {
682
- skip("ESLint config check (no eslint.config.mjs)");
684
+ skip("ESLint config check (no eslint flat config found)");
683
685
  }
684
686
  } else {
685
687
  skip("ESLint config check (typegraph-mcp is external to project)");
package/dist/cli.js CHANGED
@@ -670,8 +670,10 @@ async function main(configOverride) {
670
670
  );
671
671
  }
672
672
  if (toolIsEmbedded) {
673
- const eslintConfigPath = path3.resolve(projectRoot3, "eslint.config.mjs");
674
- if (fs2.existsSync(eslintConfigPath)) {
673
+ const eslintConfigNames = ["eslint.config.mjs", "eslint.config.js", "eslint.config.ts", "eslint.config.cjs"];
674
+ const eslintConfigFile = eslintConfigNames.find((name) => fs2.existsSync(path3.resolve(projectRoot3, name)));
675
+ if (eslintConfigFile) {
676
+ const eslintConfigPath = path3.resolve(projectRoot3, eslintConfigFile);
675
677
  const eslintContent = fs2.readFileSync(eslintConfigPath, "utf-8");
676
678
  const parentDir = path3.basename(path3.dirname(toolDir));
677
679
  const parentIgnorePattern = new RegExp(`["']${parentDir}\\/\\*\\*["']`);
@@ -681,12 +683,12 @@ async function main(configOverride) {
681
683
  } else {
682
684
  fail(
683
685
  `ESLint missing ignore: "${parentDir}/**"`,
684
- `Add to the ignores array in eslint.config.mjs:
686
+ `Add to the ignores array in ${eslintConfigFile}:
685
687
  "${parentDir}/**",`
686
688
  );
687
689
  }
688
690
  } else {
689
- skip("ESLint config check (no eslint.config.mjs)");
691
+ skip("ESLint config check (no eslint flat config found)");
690
692
  }
691
693
  } else {
692
694
  skip("ESLint config check (typegraph-mcp is external to project)");
@@ -3055,6 +3057,42 @@ function ensureTsconfigExclude(projectRoot3) {
3055
3057
  p.log.warn('Could not update tsconfig.json \u2014 manually add "plugins/**" to the exclude array to prevent build errors');
3056
3058
  }
3057
3059
  }
3060
+ function ensureEslintIgnore(projectRoot3) {
3061
+ const eslintConfigNames = ["eslint.config.mjs", "eslint.config.js", "eslint.config.ts", "eslint.config.cjs"];
3062
+ const eslintConfigFile = eslintConfigNames.find((name) => fs8.existsSync(path9.resolve(projectRoot3, name)));
3063
+ if (!eslintConfigFile) return;
3064
+ const eslintConfigPath = path9.resolve(projectRoot3, eslintConfigFile);
3065
+ try {
3066
+ const raw = fs8.readFileSync(eslintConfigPath, "utf-8");
3067
+ const pattern = /["']plugins\/\*\*["']/;
3068
+ if (pattern.test(raw)) return;
3069
+ const ignoresArrayRe = /(ignores\s*:\s*\[)([\s\S]*?)(\])/;
3070
+ const match = raw.match(ignoresArrayRe);
3071
+ if (match) {
3072
+ const updated = raw.replace(ignoresArrayRe, (_m, open, items, close) => {
3073
+ const trimmed = items.trimEnd();
3074
+ const needsComma = trimmed.length > 0 && !trimmed.endsWith(",");
3075
+ return `${open}${items.trimEnd()}${needsComma ? "," : ""} "plugins/**"${close}`;
3076
+ });
3077
+ fs8.writeFileSync(eslintConfigPath, updated);
3078
+ p.log.success(`Added "plugins/**" to ${eslintConfigFile} ignores`);
3079
+ return;
3080
+ }
3081
+ const exportArrayRe = /(export\s+default\s+(?:\w+\.config\(|\[))\s*\n?/;
3082
+ if (exportArrayRe.test(raw)) {
3083
+ const updated = raw.replace(exportArrayRe, (m) => {
3084
+ return `${m} { ignores: ["plugins/**"] },
3085
+ `;
3086
+ });
3087
+ fs8.writeFileSync(eslintConfigPath, updated);
3088
+ p.log.success(`Added "plugins/**" to ${eslintConfigFile} ignores`);
3089
+ return;
3090
+ }
3091
+ p.log.warn(`Could not patch ${eslintConfigFile} \u2014 manually add "plugins/**" to the ignores array`);
3092
+ } catch {
3093
+ p.log.warn(`Could not update ${eslintConfigFile} \u2014 manually add "plugins/**" to the ignores array`);
3094
+ }
3095
+ }
3058
3096
  function detectAgents(projectRoot3) {
3059
3097
  return AGENT_IDS.filter((id) => AGENTS[id].detect(projectRoot3));
3060
3098
  }
@@ -3199,6 +3237,7 @@ async function setup(yes2) {
3199
3237
  await setupAgentInstructions(projectRoot3, selectedAgents);
3200
3238
  registerMcpServers(projectRoot3, selectedAgents);
3201
3239
  ensureTsconfigExclude(projectRoot3);
3240
+ ensureEslintIgnore(projectRoot3);
3202
3241
  await runVerification(targetDir, selectedAgents);
3203
3242
  }
3204
3243
  async function removePlugin(projectRoot3, pluginDir) {
@@ -3373,6 +3412,7 @@ var args = process.argv.slice(2);
3373
3412
  var command = args.find((a) => !a.startsWith("-"));
3374
3413
  var yes = args.includes("--yes") || args.includes("-y");
3375
3414
  var help = args.includes("--help") || args.includes("-h");
3415
+ process.stdout.write("\x1Bc");
3376
3416
  if (help || !command) {
3377
3417
  console.log(HELP);
3378
3418
  process.exit(0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typegraph-mcp",
3
- "version": "0.9.21",
3
+ "version": "0.9.23",
4
4
  "description": "Type-aware codebase navigation for AI coding agents — 14 MCP tools powered by tsserver + oxc",
5
5
  "license": "MIT",
6
6
  "type": "module",