@treedy/lsp-mcp 0.1.10 → 0.2.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/index.js CHANGED
@@ -19839,6 +19839,7 @@ class StdioServerTransport {
19839
19839
  import { createRequire as createRequire2 } from "module";
19840
19840
  import * as fs2 from "fs";
19841
19841
  import * as path2 from "path";
19842
+ import { execSync } from "child_process";
19842
19843
 
19843
19844
  // src/config.ts
19844
19845
  import * as path from "path";
@@ -19958,6 +19959,33 @@ function getEnvString(name, defaultValue) {
19958
19959
  return process.env[name] ?? defaultValue;
19959
19960
  }
19960
19961
  function inferLanguageFromPath(filePath, config2) {
19962
+ if (fs.existsSync(filePath)) {
19963
+ try {
19964
+ const stat = fs.statSync(filePath);
19965
+ if (stat.isDirectory()) {
19966
+ if (config2.languages.typescript?.enabled && (fs.existsSync(path.join(filePath, "tsconfig.json")) || fs.existsSync(path.join(filePath, "package.json")))) {
19967
+ return "typescript";
19968
+ }
19969
+ if (config2.languages.python?.enabled && (fs.existsSync(path.join(filePath, "pyproject.toml")) || fs.existsSync(path.join(filePath, "requirements.txt")) || fs.existsSync(path.join(filePath, "setup.py")) || fs.existsSync(path.join(filePath, "venv")) || fs.existsSync(path.join(filePath, ".venv")))) {
19970
+ return "python";
19971
+ }
19972
+ if (config2.languages.vue?.enabled && (fs.existsSync(path.join(filePath, "vite.config.ts")) || fs.existsSync(path.join(filePath, "vue.config.js")))) {
19973
+ return "vue";
19974
+ }
19975
+ try {
19976
+ const entries = fs.readdirSync(filePath);
19977
+ for (const entry of entries) {
19978
+ if (entry.endsWith(".ts") && config2.languages.typescript?.enabled)
19979
+ return "typescript";
19980
+ if (entry.endsWith(".py") && config2.languages.python?.enabled)
19981
+ return "python";
19982
+ if (entry.endsWith(".vue") && config2.languages.vue?.enabled)
19983
+ return "vue";
19984
+ }
19985
+ } catch {}
19986
+ }
19987
+ } catch (e) {}
19988
+ }
19961
19989
  const ext = filePath.substring(filePath.lastIndexOf("."));
19962
19990
  for (const [lang, langConfig] of Object.entries(config2.languages)) {
19963
19991
  if (langConfig?.enabled && langConfig.extensions.includes(ext)) {
@@ -21539,6 +21567,18 @@ Analyze Python and TypeScript code for structure, types, and errors.
21539
21567
 
21540
21568
  ## Tools
21541
21569
 
21570
+ ### project_structure
21571
+
21572
+ Get a visual tree structure of the project, highlighting key files.
21573
+
21574
+ \`\`\`
21575
+ project_structure(path=None)
21576
+ \`\`\`
21577
+
21578
+ **Use when:**
21579
+ - Starting a new task to understand project layout
21580
+ - Finding entry points (main.py, package.json)
21581
+
21542
21582
  ### symbols
21543
21583
 
21544
21584
  Extract all symbols (classes, functions, variables) from a file.
@@ -21565,6 +21605,18 @@ diagnostics(path)
21565
21605
  - Validating refactoring didn't break anything
21566
21606
  - Finding issues before running tests
21567
21607
 
21608
+ ### git_diagnostics
21609
+
21610
+ Check for errors ONLY in files changed in Git (working tree + staged).
21611
+
21612
+ \`\`\`
21613
+ git_diagnostics()
21614
+ \`\`\`
21615
+
21616
+ **Use when:**
21617
+ - Fast feedback loop after editing code
21618
+ - "Did I break anything I just touched?"
21619
+
21568
21620
  ### search
21569
21621
 
21570
21622
  Search for patterns across the codebase using regex. Returns positions in LSP format (file, line, column).
@@ -21782,7 +21834,7 @@ function registerPrompts(server) {
21782
21834
  text: `Please explore the project at '${path2 || "current workspace"}'.
21783
21835
 
21784
21836
  Recommended Workflow:
21785
- 1. List files to understand the directory structure (use 'ls' or 'glob').
21837
+ 1. Use 'project_structure' to visualize the directory hierarchy and identify key files.
21786
21838
  2. Identify key entry points (e.g., main.py, index.ts, App.vue, pyproject.toml, package.json).
21787
21839
  3. Use 'summarize_file' on these entry points to extract high-level symbols (classes/functions) without reading full content.
21788
21840
  4. Report back with a structural summary of the project.`
@@ -21802,7 +21854,7 @@ Recommended Workflow:
21802
21854
  text: `Please debug and analyze the file '${file}'.
21803
21855
 
21804
21856
  Recommended Workflow:
21805
- 1. Run 'diagnostics' on the file to identify syntax errors, type mismatches, or unused imports.
21857
+ 1. Run 'diagnostics' on the file (or 'git_diagnostics' to check recent changes) to identify syntax errors, type mismatches, or unused imports.
21806
21858
  2. Use 'read_file_with_hints' to read the content. This will reveal inferred types and parameter names, making it easier to spot logic errors.
21807
21859
  3. If errors are found, check specific locations with 'code_action' to see if auto-fixes (like 'Organize Imports') are available.
21808
21860
  4. Explain the findings and propose fixes.`
@@ -21824,6 +21876,8 @@ Recommended Workflow:
21824
21876
  ### 1. Smart Exploration
21825
21877
  Instead of reading raw code, use:
21826
21878
  \`\`\`
21879
+ project_structure() → See file hierarchy
21880
+ workspace_symbol("User") → Find where "User" class is
21827
21881
  summarize_file(file) → Get outline of classes/functions
21828
21882
  read_file_with_hints(file) → Read code with type/param annotations
21829
21883
  \`\`\`
@@ -21831,14 +21885,15 @@ read_file_with_hints(file) → Read code with type/param annotations
21831
21885
  ### 2. Search → LSP Tools
21832
21886
  \`\`\`
21833
21887
  search("ClassName") → get positions
21888
+ peek_definition(file, line, col) → See definition code immediately
21834
21889
  hover(file, line, column) → get type info
21835
- definition(...) → jump to definition
21836
21890
  references(...) → find usages
21837
21891
  \`\`\`
21838
21892
 
21839
21893
  ### 3. Debug & Fix
21840
21894
  \`\`\`
21841
- diagnostics(path) → Check for errors
21895
+ git_diagnostics() → Check errors in changed files
21896
+ diagnostics(path) → Check full path
21842
21897
  code_action(file, line, col) → Get quick fixes (e.g. Organize Imports)
21843
21898
  run_code_action(...) → Apply fix
21844
21899
  \`\`\`
@@ -21865,6 +21920,106 @@ var server = new McpServer({
21865
21920
  version: packageJson.version
21866
21921
  });
21867
21922
  registerPrompts(server);
21923
+ function getProjectStructure(dirPath, depth = 0, maxDepth = 3) {
21924
+ const IGNORED_DIRS = new Set([".git", "node_modules", "dist", "build", "coverage", "__pycache__", ".venv", ".idea", ".vscode", ".next", ".nuxt"]);
21925
+ const KEY_FILES = new Set(["package.json", "tsconfig.json", "pyproject.toml", "requirements.txt", "README.md", "Dockerfile", "docker-compose.yml", "cargo.toml", "go.mod", "gemfile"]);
21926
+ if (depth > maxDepth)
21927
+ return "";
21928
+ let output = "";
21929
+ let entries;
21930
+ try {
21931
+ entries = fs2.readdirSync(dirPath, { withFileTypes: true });
21932
+ } catch (e) {
21933
+ return "";
21934
+ }
21935
+ entries.sort((a, b) => {
21936
+ if (a.isDirectory() && !b.isDirectory())
21937
+ return -1;
21938
+ if (!a.isDirectory() && b.isDirectory())
21939
+ return 1;
21940
+ return a.name.localeCompare(b.name);
21941
+ });
21942
+ for (const entry of entries) {
21943
+ if (entry.name.startsWith("."))
21944
+ continue;
21945
+ if (IGNORED_DIRS.has(entry.name))
21946
+ continue;
21947
+ const isDir = entry.isDirectory();
21948
+ const indent = " ".repeat(depth);
21949
+ const marker = isDir ? "\uD83D\uDCC1 " : "\uD83D\uDCC4 ";
21950
+ const isKeyFile = KEY_FILES.has(entry.name.toLowerCase());
21951
+ const extra = isKeyFile ? " (config)" : "";
21952
+ output += `${indent}${marker}${entry.name}${extra}
21953
+ `;
21954
+ if (isDir) {
21955
+ output += getProjectStructure(path2.join(dirPath, entry.name), depth + 1, maxDepth);
21956
+ }
21957
+ }
21958
+ return output;
21959
+ }
21960
+ function getGitChangedFiles(cwd) {
21961
+ try {
21962
+ const gitRoot = execSync("git rev-parse --show-toplevel", { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
21963
+ const files = new Set;
21964
+ try {
21965
+ const stdout = execSync("git diff --name-only", { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
21966
+ stdout.split(`
21967
+ `).forEach((f) => {
21968
+ if (f.trim())
21969
+ files.add(path2.resolve(gitRoot, f.trim()));
21970
+ });
21971
+ } catch (e) {}
21972
+ try {
21973
+ const stdout = execSync("git diff --staged --name-only", { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
21974
+ stdout.split(`
21975
+ `).forEach((f) => {
21976
+ if (f.trim())
21977
+ files.add(path2.resolve(gitRoot, f.trim()));
21978
+ });
21979
+ } catch (e) {}
21980
+ return Array.from(files);
21981
+ } catch (error2) {
21982
+ return [];
21983
+ }
21984
+ }
21985
+ function validateAndFixPosition(filePath, line, column) {
21986
+ try {
21987
+ if (!fs2.existsSync(filePath))
21988
+ return { line, column };
21989
+ const stats = fs2.statSync(filePath);
21990
+ if (stats.size > 1024 * 1024)
21991
+ return { line, column };
21992
+ const content = fs2.readFileSync(filePath, "utf-8");
21993
+ const lines = content.split(`
21994
+ `);
21995
+ let newLine = line;
21996
+ let warning = "";
21997
+ if (newLine > lines.length) {
21998
+ newLine = lines.length;
21999
+ warning = `Line ${line} out of bounds (max ${lines.length}). Clamped to ${newLine}.`;
22000
+ }
22001
+ if (newLine < 1) {
22002
+ newLine = 1;
22003
+ warning = `Line ${line} must be positive. Clamped to 1.`;
22004
+ }
22005
+ const lineContent = lines[newLine - 1] || "";
22006
+ let newColumn = column;
22007
+ const maxCol = lineContent.length + 1;
22008
+ if (newColumn > maxCol) {
22009
+ newColumn = maxCol;
22010
+ const w = `Column ${column} out of bounds (max ${maxCol}). Clamped to ${newColumn}.`;
22011
+ warning = warning ? `${warning} ${w}` : w;
22012
+ }
22013
+ if (newColumn < 1) {
22014
+ newColumn = 1;
22015
+ const w = `Column ${column} must be positive. Clamped to 1.`;
22016
+ warning = warning ? `${warning} ${w}` : w;
22017
+ }
22018
+ return { line: newLine, column: newColumn, warning: warning || undefined };
22019
+ } catch (e) {
22020
+ return { line, column };
22021
+ }
22022
+ }
21868
22023
  async function startAndRegisterBackend(language) {
21869
22024
  if (startedBackends.has(language)) {
21870
22025
  const status2 = backendManager.getStatus()[language];
@@ -21926,7 +22081,11 @@ var UNIFIED_TOOLS = [
21926
22081
  { name: "summarize_file", description: "Get a high-level outline of a file (classes, functions, methods) to understand its structure without reading the full content.", schema: { file: exports_external.string() } },
21927
22082
  { name: "read_file_with_hints", description: "Read file content with inlay hints (type annotations, parameter names) inserted as comments. Useful for understanding complex code.", schema: { file: exports_external.string() } },
21928
22083
  { name: "code_action", description: "Get available code actions (refactors and quick fixes) at a specific position", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
21929
- { name: "run_code_action", description: "Apply a code action (refactor or quick fix)", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive(), kind: exports_external.enum(["refactor", "quickfix"]), name: exports_external.string(), actionName: exports_external.string().optional(), preview: exports_external.boolean().default(false).optional() } }
22084
+ { name: "run_code_action", description: "Apply a code action (refactor or quick fix)", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive(), kind: exports_external.enum(["refactor", "quickfix"]), name: exports_external.string(), actionName: exports_external.string().optional(), preview: exports_external.boolean().default(false).optional() } },
22085
+ { name: "workspace_symbol", description: "Search for a symbol (class, function, etc.) across the entire workspace. Returns locations that can be used with peek_definition.", schema: { query: exports_external.string() } },
22086
+ { name: "peek_definition", description: "Go to definition and return the surrounding code context immediately. Reduces round-trips compared to definition() + read_file().", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
22087
+ { name: "project_structure", description: "Get a visual tree structure of the project to understand hierarchy and identify key files. Ignores build artifacts.", schema: { path: exports_external.string().optional() } },
22088
+ { name: "git_diagnostics", description: "Check for errors/warnings ONLY in files changed in Git (working tree + staged). Useful for checking your changes.", schema: {} }
21930
22089
  ];
21931
22090
  function applyInlayHints(content, hints, language) {
21932
22091
  const lines = content.split(`
@@ -22044,30 +22203,131 @@ function preRegisterTools() {
22044
22203
  description: `${tool.description} (unified tool, routes automatically by file extension)`,
22045
22204
  inputSchema: tool.schema
22046
22205
  }, async (args) => {
22206
+ let paramWarning;
22207
+ if (typeof args.line === "number" && typeof args.column === "number") {
22208
+ const targetFile = args.file || args.path;
22209
+ if (targetFile) {
22210
+ let checkPath = targetFile;
22211
+ if (!path2.isAbsolute(checkPath) && activeWorkspacePath) {
22212
+ checkPath = path2.join(activeWorkspacePath, checkPath);
22213
+ } else if (!path2.isAbsolute(checkPath)) {
22214
+ checkPath = path2.resolve(checkPath);
22215
+ }
22216
+ const fixed = validateAndFixPosition(checkPath, args.line, args.column);
22217
+ if (fixed.warning) {
22218
+ console.error(`[lsp-mcp] Auto-corrected params for ${tool.name}: ${fixed.warning}`);
22219
+ args.line = fixed.line;
22220
+ args.column = fixed.column;
22221
+ paramWarning = `(Auto-corrected: ${fixed.warning})`;
22222
+ }
22223
+ }
22224
+ }
22225
+ if (tool.name === "project_structure") {
22226
+ const targetPath = args.path || activeWorkspacePath || process.cwd();
22227
+ const tree = getProjectStructure(targetPath);
22228
+ return {
22229
+ content: [{ type: "text", text: `Project Structure for ${targetPath}:
22230
+
22231
+ ${tree}` }]
22232
+ };
22233
+ }
22234
+ if (tool.name === "git_diagnostics") {
22235
+ const cwd = activeWorkspacePath || process.cwd();
22236
+ const changedFiles = getGitChangedFiles(cwd);
22237
+ if (changedFiles.length === 0) {
22238
+ return { content: [{ type: "text", text: "No changed files found in git." }] };
22239
+ }
22240
+ const results = [];
22241
+ for (const file of changedFiles) {
22242
+ const language2 = inferLanguageFromPath(file, config2);
22243
+ if (!language2)
22244
+ continue;
22245
+ if (!startedBackends.has(language2)) {
22246
+ try {
22247
+ await backendManager.getBackend(language2);
22248
+ startedBackends.add(language2);
22249
+ } catch (e) {
22250
+ results.push(`Could not check ${path2.basename(file)}: Backend failed to start`);
22251
+ continue;
22252
+ }
22253
+ }
22254
+ try {
22255
+ const relativePath = path2.relative(cwd, file);
22256
+ const res = await backendManager.callTool(language2, "diagnostics", { path: relativePath });
22257
+ const parsed = JSON.parse(res.content[0].text);
22258
+ if (parsed.error) {
22259
+ results.push(`⚠️ ${path2.basename(file)}: Backend error: ${parsed.error}`);
22260
+ continue;
22261
+ }
22262
+ let diagnostics = [];
22263
+ if (Array.isArray(parsed))
22264
+ diagnostics = parsed;
22265
+ else if (parsed.diagnostics && Array.isArray(parsed.diagnostics))
22266
+ diagnostics = parsed.diagnostics;
22267
+ else {
22268
+ console.error(`[lsp-mcp] Unexpected diagnostics format for ${file}:`, parsed);
22269
+ results.push(`⚠️ ${path2.basename(file)}: Unexpected response format`);
22270
+ continue;
22271
+ }
22272
+ if (diagnostics.length === 0) {
22273
+ results.push(`✅ ${path2.basename(file)}: No errors`);
22274
+ } else {
22275
+ const errors4 = diagnostics.map((d) => ` - [Line ${d.range?.start?.line ?? d.line ?? "?"}] ${d.message}`).join(`
22276
+ `);
22277
+ results.push(`❌ ${path2.basename(file)}:
22278
+ ${errors4}`);
22279
+ }
22280
+ } catch (e) {
22281
+ results.push(`⚠️ ${path2.basename(file)}: Check failed (${e})`);
22282
+ }
22283
+ }
22284
+ return { content: [{ type: "text", text: `Git Diagnostics Report:
22285
+
22286
+ ${results.join(`
22287
+
22288
+ `)}` }] };
22289
+ }
22047
22290
  const filePath = args.file || args.path;
22048
- if (tool.name === "search" && !filePath) {
22291
+ if ((tool.name === "search" || tool.name === "workspace_symbol") && !filePath) {
22049
22292
  const languages = Object.keys(config2.languages).filter((lang) => config2.languages[lang].enabled);
22050
22293
  const results = [];
22051
22294
  for (const lang of languages) {
22052
22295
  if (startedBackends.has(lang)) {
22053
22296
  try {
22054
- const res = await backendManager.callTool(lang, "search", args);
22055
- results.push(JSON.parse(res.content[0].text));
22297
+ const res = await backendManager.callTool(lang, tool.name, args);
22298
+ const parsed = JSON.parse(res.content[0].text);
22299
+ let items = [];
22300
+ if (Array.isArray(parsed))
22301
+ items = parsed;
22302
+ else if (parsed.matches)
22303
+ items = parsed.matches;
22304
+ else if (parsed.symbols)
22305
+ items = parsed.symbols;
22306
+ if (items.length > 0) {
22307
+ results.push(...items.map((i) => ({ ...i, language: lang })));
22308
+ }
22056
22309
  } catch (e) {}
22057
22310
  }
22058
22311
  }
22059
22312
  if (results.length === 0) {
22060
- return { content: [{ type: "text", text: JSON.stringify({ matches: [], count: 0, message: "No active backends to search in. Please specify a file path to auto-start a backend." }) }] };
22313
+ return { content: [{ type: "text", text: JSON.stringify({ matches: [], count: 0, message: "No matches found or no active backends." }) }] };
22061
22314
  }
22062
- const allMatches = results.flatMap((r) => r.matches || []);
22063
- return { content: [{ type: "text", text: JSON.stringify({ matches: allMatches, count: allMatches.length }) }] };
22315
+ return { content: [{ type: "text", text: JSON.stringify({ matches: results, count: results.length }) }] };
22064
22316
  }
22065
22317
  if (!filePath) {
22066
22318
  return {
22067
22319
  content: [{ type: "text", text: JSON.stringify({ error: "Missing 'file' or 'path' argument required for unified routing" }) }]
22068
22320
  };
22069
22321
  }
22070
- const language = inferLanguageFromPath(filePath, config2);
22322
+ let absPath = filePath;
22323
+ if (!path2.isAbsolute(filePath)) {
22324
+ if (activeWorkspacePath) {
22325
+ absPath = path2.join(activeWorkspacePath, filePath);
22326
+ } else {
22327
+ absPath = path2.resolve(filePath);
22328
+ }
22329
+ }
22330
+ const language = inferLanguageFromPath(absPath, config2);
22071
22331
  if (!language) {
22072
22332
  return {
22073
22333
  content: [
@@ -22114,7 +22374,7 @@ function preRegisterTools() {
22114
22374
  };
22115
22375
  }
22116
22376
  }
22117
- if (tool.name !== "summarize_file" && tool.name !== "read_file_with_hints") {
22377
+ if (tool.name !== "summarize_file" && tool.name !== "read_file_with_hints" && tool.name !== "peek_definition") {
22118
22378
  const availableTools = await backendManager.getTools(language);
22119
22379
  const supportsTool = availableTools.some((t) => t.name === tool.name);
22120
22380
  if (!supportsTool) {
@@ -22155,16 +22415,69 @@ ${summary || "(No symbols found)"}`
22155
22415
  };
22156
22416
  }
22157
22417
  }
22418
+ if (tool.name === "peek_definition") {
22419
+ try {
22420
+ const result = await backendManager.callTool(language, "definition", args);
22421
+ const parsed = JSON.parse(result.content[0].text);
22422
+ if (parsed.error) {
22423
+ return { content: [{ type: "text", text: JSON.stringify(parsed) }] };
22424
+ }
22425
+ let locs = Array.isArray(parsed) ? parsed : [parsed];
22426
+ if (parsed.matches)
22427
+ locs = parsed.matches;
22428
+ if (!locs || locs.length === 0) {
22429
+ return { content: [{ type: "text", text: JSON.stringify({ message: "No definition found" }) }] };
22430
+ }
22431
+ const def = locs[0];
22432
+ const defPath = def.file || def.uri;
22433
+ if (!defPath) {
22434
+ return { content: [{ type: "text", text: JSON.stringify({ error: "Invalid definition result", raw: parsed }) }] };
22435
+ }
22436
+ let defAbsPath = defPath;
22437
+ if (!path2.isAbsolute(defPath) && activeWorkspacePath) {
22438
+ defAbsPath = path2.join(activeWorkspacePath, defPath);
22439
+ }
22440
+ if (!fs2.existsSync(defAbsPath)) {
22441
+ return { content: [{ type: "text", text: JSON.stringify({ error: `Definition file not found: ${defAbsPath}`, location: def }) }] };
22442
+ }
22443
+ const fileContent = fs2.readFileSync(defAbsPath, "utf-8");
22444
+ const lines = fileContent.split(`
22445
+ `);
22446
+ const targetLine = def.line;
22447
+ const lineIdx = targetLine - 1;
22448
+ const CONTEXT_LINES = 10;
22449
+ const startIdx = Math.max(0, lineIdx - CONTEXT_LINES);
22450
+ const endIdx = Math.min(lines.length, lineIdx + CONTEXT_LINES + 1);
22451
+ const contextSnippet = lines.slice(startIdx, endIdx).map((line, i) => {
22452
+ const currentLineNum = startIdx + i + 1;
22453
+ const marker = currentLineNum === targetLine ? " >" : " ";
22454
+ return `${marker} ${currentLineNum.toString().padEnd(4)} | ${line}`;
22455
+ }).join(`
22456
+ `);
22457
+ const responseText = `Definition found in ${defPath} at line ${targetLine}:
22458
+
22459
+ ` + "```" + (language === "python" ? "python" : "typescript") + `
22460
+ ` + contextSnippet + `
22461
+ ` + "```";
22462
+ return {
22463
+ content: [{ type: "text", text: responseText }]
22464
+ };
22465
+ } catch (error2) {
22466
+ return {
22467
+ content: [{ type: "text", text: JSON.stringify({ error: `Failed to peek definition: ${error2}` }) }]
22468
+ };
22469
+ }
22470
+ }
22158
22471
  if (tool.name === "read_file_with_hints") {
22159
22472
  try {
22160
- let absPath = filePath;
22473
+ let absPath2 = filePath;
22161
22474
  if (!path2.isAbsolute(filePath) && activeWorkspacePath) {
22162
- absPath = path2.join(activeWorkspacePath, filePath);
22475
+ absPath2 = path2.join(activeWorkspacePath, filePath);
22163
22476
  }
22164
- if (!fs2.existsSync(absPath)) {
22165
- return { content: [{ type: "text", text: JSON.stringify({ error: `File not found: ${absPath}` }) }] };
22477
+ if (!fs2.existsSync(absPath2)) {
22478
+ return { content: [{ type: "text", text: JSON.stringify({ error: `File not found: ${absPath2}` }) }] };
22166
22479
  }
22167
- const content = fs2.readFileSync(absPath, "utf-8");
22480
+ const content = fs2.readFileSync(absPath2, "utf-8");
22168
22481
  const result = await backendManager.callTool(language, "inlay_hints", args);
22169
22482
  const parsed = JSON.parse(result.content[0].text);
22170
22483
  if (parsed.error) {
@@ -22275,4 +22588,4 @@ main().catch((error2) => {
22275
22588
  process.exit(1);
22276
22589
  });
22277
22590
 
22278
- //# debugId=4446D59062B5AFD964756E2164756E21
22591
+ //# debugId=CC41A27AB80DC0BB64756E2164756E21