@treedy/lsp-mcp 0.1.6 → 0.1.8

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.
Files changed (76) hide show
  1. package/dist/bundled/pyright/dist/index.d.ts +2 -0
  2. package/dist/bundled/pyright/dist/index.js +1620 -0
  3. package/dist/bundled/pyright/dist/index.js.map +26 -0
  4. package/dist/bundled/pyright/dist/lsp/connection.d.ts +71 -0
  5. package/dist/bundled/pyright/dist/lsp/document-manager.d.ts +67 -0
  6. package/dist/bundled/pyright/dist/lsp/index.d.ts +3 -0
  7. package/dist/bundled/pyright/dist/lsp/types.d.ts +55 -0
  8. package/dist/bundled/pyright/dist/lsp-client.d.ts +55 -0
  9. package/dist/bundled/pyright/dist/tools/completions.d.ts +18 -0
  10. package/dist/bundled/pyright/dist/tools/definition.d.ts +16 -0
  11. package/dist/bundled/pyright/dist/tools/diagnostics.d.ts +12 -0
  12. package/dist/bundled/pyright/dist/tools/hover.d.ts +16 -0
  13. package/dist/bundled/pyright/dist/tools/references.d.ts +16 -0
  14. package/dist/bundled/pyright/dist/tools/rename.d.ts +18 -0
  15. package/dist/bundled/pyright/dist/tools/search.d.ts +20 -0
  16. package/dist/bundled/pyright/dist/tools/signature-help.d.ts +16 -0
  17. package/dist/bundled/pyright/dist/tools/status.d.ts +14 -0
  18. package/dist/bundled/pyright/dist/tools/symbols.d.ts +17 -0
  19. package/dist/bundled/pyright/dist/tools/update-document.d.ts +14 -0
  20. package/dist/bundled/pyright/dist/utils/position.d.ts +33 -0
  21. package/dist/bundled/pyright/package.json +54 -0
  22. package/dist/bundled/python/README.md +230 -0
  23. package/dist/bundled/python/pyproject.toml +61 -0
  24. package/dist/bundled/python/src/rope_mcp/__init__.py +3 -0
  25. package/dist/bundled/python/src/rope_mcp/__pycache__/__init__.cpython-312.pyc +0 -0
  26. package/dist/bundled/python/src/rope_mcp/__pycache__/__init__.cpython-313.pyc +0 -0
  27. package/dist/bundled/python/src/rope_mcp/__pycache__/config.cpython-312.pyc +0 -0
  28. package/dist/bundled/python/src/rope_mcp/__pycache__/config.cpython-313.pyc +0 -0
  29. package/dist/bundled/python/src/rope_mcp/__pycache__/pyright_client.cpython-313.pyc +0 -0
  30. package/dist/bundled/python/src/rope_mcp/__pycache__/rope_client.cpython-313.pyc +0 -0
  31. package/dist/bundled/python/src/rope_mcp/__pycache__/server.cpython-312.pyc +0 -0
  32. package/dist/bundled/python/src/rope_mcp/__pycache__/server.cpython-313.pyc +0 -0
  33. package/dist/bundled/python/src/rope_mcp/config.py +408 -0
  34. package/dist/bundled/python/src/rope_mcp/lsp/__init__.py +15 -0
  35. package/dist/bundled/python/src/rope_mcp/lsp/__pycache__/__init__.cpython-313.pyc +0 -0
  36. package/dist/bundled/python/src/rope_mcp/lsp/__pycache__/client.cpython-313.pyc +0 -0
  37. package/dist/bundled/python/src/rope_mcp/lsp/__pycache__/types.cpython-313.pyc +0 -0
  38. package/dist/bundled/python/src/rope_mcp/lsp/client.py +624 -0
  39. package/dist/bundled/python/src/rope_mcp/lsp/types.py +82 -0
  40. package/dist/bundled/python/src/rope_mcp/pyright_client.py +147 -0
  41. package/dist/bundled/python/src/rope_mcp/rope_client.py +198 -0
  42. package/dist/bundled/python/src/rope_mcp/server.py +963 -0
  43. package/dist/bundled/python/src/rope_mcp/tools/__init__.py +26 -0
  44. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/__init__.cpython-313.pyc +0 -0
  45. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/change_signature.cpython-313.pyc +0 -0
  46. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/completions.cpython-313.pyc +0 -0
  47. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/definition.cpython-313.pyc +0 -0
  48. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/diagnostics.cpython-313.pyc +0 -0
  49. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/hover.cpython-313.pyc +0 -0
  50. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/move.cpython-313.pyc +0 -0
  51. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/references.cpython-313.pyc +0 -0
  52. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/rename.cpython-313.pyc +0 -0
  53. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/search.cpython-313.pyc +0 -0
  54. package/dist/bundled/python/src/rope_mcp/tools/__pycache__/symbols.cpython-313.pyc +0 -0
  55. package/dist/bundled/python/src/rope_mcp/tools/change_signature.py +184 -0
  56. package/dist/bundled/python/src/rope_mcp/tools/completions.py +84 -0
  57. package/dist/bundled/python/src/rope_mcp/tools/definition.py +51 -0
  58. package/dist/bundled/python/src/rope_mcp/tools/diagnostics.py +18 -0
  59. package/dist/bundled/python/src/rope_mcp/tools/hover.py +49 -0
  60. package/dist/bundled/python/src/rope_mcp/tools/move.py +81 -0
  61. package/dist/bundled/python/src/rope_mcp/tools/references.py +60 -0
  62. package/dist/bundled/python/src/rope_mcp/tools/rename.py +61 -0
  63. package/dist/bundled/python/src/rope_mcp/tools/search.py +128 -0
  64. package/dist/bundled/python/src/rope_mcp/tools/symbols.py +118 -0
  65. package/dist/bundled/python/uv.lock +979 -0
  66. package/dist/bundled/typescript/dist/index.js +29534 -0
  67. package/dist/bundled/typescript/dist/index.js.map +211 -0
  68. package/dist/bundled/typescript/package.json +46 -0
  69. package/dist/bundled/vue/dist/index.d.ts +8 -0
  70. package/dist/bundled/vue/dist/index.js +21111 -0
  71. package/dist/bundled/vue/dist/ts-vue-service.d.ts +67 -0
  72. package/dist/bundled/vue/dist/vue-service.d.ts +144 -0
  73. package/dist/bundled/vue/package.json +45 -0
  74. package/dist/index.js +268 -112
  75. package/dist/index.js.map +5 -5
  76. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6495,8 +6495,8 @@ var require_dist = __commonJS((exports, module) => {
6495
6495
  var require_windows = __commonJS((exports, module) => {
6496
6496
  module.exports = isexe;
6497
6497
  isexe.sync = sync;
6498
- var fs = __require("fs");
6499
- function checkPathExt(path, options) {
6498
+ var fs2 = __require("fs");
6499
+ function checkPathExt(path2, options) {
6500
6500
  var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
6501
6501
  if (!pathext) {
6502
6502
  return true;
@@ -6507,25 +6507,25 @@ var require_windows = __commonJS((exports, module) => {
6507
6507
  }
6508
6508
  for (var i = 0;i < pathext.length; i++) {
6509
6509
  var p = pathext[i].toLowerCase();
6510
- if (p && path.substr(-p.length).toLowerCase() === p) {
6510
+ if (p && path2.substr(-p.length).toLowerCase() === p) {
6511
6511
  return true;
6512
6512
  }
6513
6513
  }
6514
6514
  return false;
6515
6515
  }
6516
- function checkStat(stat, path, options) {
6516
+ function checkStat(stat, path2, options) {
6517
6517
  if (!stat.isSymbolicLink() && !stat.isFile()) {
6518
6518
  return false;
6519
6519
  }
6520
- return checkPathExt(path, options);
6520
+ return checkPathExt(path2, options);
6521
6521
  }
6522
- function isexe(path, options, cb) {
6523
- fs.stat(path, function(er, stat) {
6524
- cb(er, er ? false : checkStat(stat, path, options));
6522
+ function isexe(path2, options, cb) {
6523
+ fs2.stat(path2, function(er, stat) {
6524
+ cb(er, er ? false : checkStat(stat, path2, options));
6525
6525
  });
6526
6526
  }
6527
- function sync(path, options) {
6528
- return checkStat(fs.statSync(path), path, options);
6527
+ function sync(path2, options) {
6528
+ return checkStat(fs2.statSync(path2), path2, options);
6529
6529
  }
6530
6530
  });
6531
6531
 
@@ -6533,14 +6533,14 @@ var require_windows = __commonJS((exports, module) => {
6533
6533
  var require_mode = __commonJS((exports, module) => {
6534
6534
  module.exports = isexe;
6535
6535
  isexe.sync = sync;
6536
- var fs = __require("fs");
6537
- function isexe(path, options, cb) {
6538
- fs.stat(path, function(er, stat) {
6536
+ var fs2 = __require("fs");
6537
+ function isexe(path2, options, cb) {
6538
+ fs2.stat(path2, function(er, stat) {
6539
6539
  cb(er, er ? false : checkStat(stat, options));
6540
6540
  });
6541
6541
  }
6542
- function sync(path, options) {
6543
- return checkStat(fs.statSync(path), options);
6542
+ function sync(path2, options) {
6543
+ return checkStat(fs2.statSync(path2), options);
6544
6544
  }
6545
6545
  function checkStat(stat, options) {
6546
6546
  return stat.isFile() && checkMode(stat, options);
@@ -6562,7 +6562,7 @@ var require_mode = __commonJS((exports, module) => {
6562
6562
 
6563
6563
  // node_modules/isexe/index.js
6564
6564
  var require_isexe = __commonJS((exports, module) => {
6565
- var fs = __require("fs");
6565
+ var fs2 = __require("fs");
6566
6566
  var core2;
6567
6567
  if (process.platform === "win32" || global.TESTING_WINDOWS) {
6568
6568
  core2 = require_windows();
@@ -6571,7 +6571,7 @@ var require_isexe = __commonJS((exports, module) => {
6571
6571
  }
6572
6572
  module.exports = isexe;
6573
6573
  isexe.sync = sync;
6574
- function isexe(path, options, cb) {
6574
+ function isexe(path2, options, cb) {
6575
6575
  if (typeof options === "function") {
6576
6576
  cb = options;
6577
6577
  options = {};
@@ -6580,17 +6580,17 @@ var require_isexe = __commonJS((exports, module) => {
6580
6580
  if (typeof Promise !== "function") {
6581
6581
  throw new TypeError("callback not provided");
6582
6582
  }
6583
- return new Promise(function(resolve, reject) {
6584
- isexe(path, options || {}, function(er, is) {
6583
+ return new Promise(function(resolve2, reject) {
6584
+ isexe(path2, options || {}, function(er, is) {
6585
6585
  if (er) {
6586
6586
  reject(er);
6587
6587
  } else {
6588
- resolve(is);
6588
+ resolve2(is);
6589
6589
  }
6590
6590
  });
6591
6591
  });
6592
6592
  }
6593
- core2(path, options || {}, function(er, is) {
6593
+ core2(path2, options || {}, function(er, is) {
6594
6594
  if (er) {
6595
6595
  if (er.code === "EACCES" || options && options.ignoreErrors) {
6596
6596
  er = null;
@@ -6600,9 +6600,9 @@ var require_isexe = __commonJS((exports, module) => {
6600
6600
  cb(er, is);
6601
6601
  });
6602
6602
  }
6603
- function sync(path, options) {
6603
+ function sync(path2, options) {
6604
6604
  try {
6605
- return core2.sync(path, options || {});
6605
+ return core2.sync(path2, options || {});
6606
6606
  } catch (er) {
6607
6607
  if (options && options.ignoreErrors || er.code === "EACCES") {
6608
6608
  return false;
@@ -6616,7 +6616,7 @@ var require_isexe = __commonJS((exports, module) => {
6616
6616
  // node_modules/which/which.js
6617
6617
  var require_which = __commonJS((exports, module) => {
6618
6618
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
6619
- var path = __require("path");
6619
+ var path2 = __require("path");
6620
6620
  var COLON = isWindows ? ";" : ":";
6621
6621
  var isexe = require_isexe();
6622
6622
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -6647,27 +6647,27 @@ var require_which = __commonJS((exports, module) => {
6647
6647
  opt = {};
6648
6648
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
6649
6649
  const found = [];
6650
- const step = (i) => new Promise((resolve, reject) => {
6650
+ const step = (i) => new Promise((resolve2, reject) => {
6651
6651
  if (i === pathEnv.length)
6652
- return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
6652
+ return opt.all && found.length ? resolve2(found) : reject(getNotFoundError(cmd));
6653
6653
  const ppRaw = pathEnv[i];
6654
6654
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
6655
- const pCmd = path.join(pathPart, cmd);
6655
+ const pCmd = path2.join(pathPart, cmd);
6656
6656
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
6657
- resolve(subStep(p, i, 0));
6657
+ resolve2(subStep(p, i, 0));
6658
6658
  });
6659
- const subStep = (p, i, ii) => new Promise((resolve, reject) => {
6659
+ const subStep = (p, i, ii) => new Promise((resolve2, reject) => {
6660
6660
  if (ii === pathExt.length)
6661
- return resolve(step(i + 1));
6661
+ return resolve2(step(i + 1));
6662
6662
  const ext = pathExt[ii];
6663
6663
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
6664
6664
  if (!er && is) {
6665
6665
  if (opt.all)
6666
6666
  found.push(p + ext);
6667
6667
  else
6668
- return resolve(p + ext);
6668
+ return resolve2(p + ext);
6669
6669
  }
6670
- return resolve(subStep(p, i, ii + 1));
6670
+ return resolve2(subStep(p, i, ii + 1));
6671
6671
  });
6672
6672
  });
6673
6673
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -6679,7 +6679,7 @@ var require_which = __commonJS((exports, module) => {
6679
6679
  for (let i = 0;i < pathEnv.length; i++) {
6680
6680
  const ppRaw = pathEnv[i];
6681
6681
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
6682
- const pCmd = path.join(pathPart, cmd);
6682
+ const pCmd = path2.join(pathPart, cmd);
6683
6683
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
6684
6684
  for (let j = 0;j < pathExt.length; j++) {
6685
6685
  const cur = p + pathExt[j];
@@ -6720,7 +6720,7 @@ var require_path_key = __commonJS((exports, module) => {
6720
6720
 
6721
6721
  // node_modules/cross-spawn/lib/util/resolveCommand.js
6722
6722
  var require_resolveCommand = __commonJS((exports, module) => {
6723
- var path = __require("path");
6723
+ var path2 = __require("path");
6724
6724
  var which = require_which();
6725
6725
  var getPathKey = require_path_key();
6726
6726
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -6737,7 +6737,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
6737
6737
  try {
6738
6738
  resolved = which.sync(parsed.command, {
6739
6739
  path: env[getPathKey({ env })],
6740
- pathExt: withoutPathExt ? path.delimiter : undefined
6740
+ pathExt: withoutPathExt ? path2.delimiter : undefined
6741
6741
  });
6742
6742
  } catch (e) {} finally {
6743
6743
  if (shouldSwitchCwd) {
@@ -6745,7 +6745,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
6745
6745
  }
6746
6746
  }
6747
6747
  if (resolved) {
6748
- resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
6748
+ resolved = path2.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
6749
6749
  }
6750
6750
  return resolved;
6751
6751
  }
@@ -6790,8 +6790,8 @@ var require_shebang_command = __commonJS((exports, module) => {
6790
6790
  if (!match) {
6791
6791
  return null;
6792
6792
  }
6793
- const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
6794
- const binary = path.split("/").pop();
6793
+ const [path2, argument] = match[0].replace(/#! ?/, "").split(" ");
6794
+ const binary = path2.split("/").pop();
6795
6795
  if (binary === "env") {
6796
6796
  return argument;
6797
6797
  }
@@ -6801,16 +6801,16 @@ var require_shebang_command = __commonJS((exports, module) => {
6801
6801
 
6802
6802
  // node_modules/cross-spawn/lib/util/readShebang.js
6803
6803
  var require_readShebang = __commonJS((exports, module) => {
6804
- var fs = __require("fs");
6804
+ var fs2 = __require("fs");
6805
6805
  var shebangCommand = require_shebang_command();
6806
6806
  function readShebang(command) {
6807
6807
  const size = 150;
6808
6808
  const buffer = Buffer.alloc(size);
6809
6809
  let fd;
6810
6810
  try {
6811
- fd = fs.openSync(command, "r");
6812
- fs.readSync(fd, buffer, 0, size, 0);
6813
- fs.closeSync(fd);
6811
+ fd = fs2.openSync(command, "r");
6812
+ fs2.readSync(fd, buffer, 0, size, 0);
6813
+ fs2.closeSync(fd);
6814
6814
  } catch (e) {}
6815
6815
  return shebangCommand(buffer.toString());
6816
6816
  }
@@ -6819,7 +6819,7 @@ var require_readShebang = __commonJS((exports, module) => {
6819
6819
 
6820
6820
  // node_modules/cross-spawn/lib/parse.js
6821
6821
  var require_parse = __commonJS((exports, module) => {
6822
- var path = __require("path");
6822
+ var path2 = __require("path");
6823
6823
  var resolveCommand = require_resolveCommand();
6824
6824
  var escape2 = require_escape();
6825
6825
  var readShebang = require_readShebang();
@@ -6844,7 +6844,7 @@ var require_parse = __commonJS((exports, module) => {
6844
6844
  const needsShell = !isExecutableRegExp.test(commandFile);
6845
6845
  if (parsed.options.forceShell || needsShell) {
6846
6846
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
6847
- parsed.command = path.normalize(parsed.command);
6847
+ parsed.command = path2.normalize(parsed.command);
6848
6848
  parsed.command = escape2.command(parsed.command);
6849
6849
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
6850
6850
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -19839,6 +19839,9 @@ class StdioServerTransport {
19839
19839
  import { createRequire as createRequire2 } from "module";
19840
19840
 
19841
19841
  // src/config.ts
19842
+ import * as path from "path";
19843
+ import * as fs from "fs";
19844
+ import { fileURLToPath } from "url";
19842
19845
  function loadConfig() {
19843
19846
  const pythonEnabled = getEnvBool("LSP_MCP_PYTHON_ENABLED", true);
19844
19847
  const pythonProvider = getEnvString("LSP_MCP_PYTHON_PROVIDER", "python-lsp-mcp");
@@ -19870,18 +19873,47 @@ function getEnvBool(name, defaultValue) {
19870
19873
  function getEnvString(name, defaultValue) {
19871
19874
  return process.env[name] ?? defaultValue;
19872
19875
  }
19876
+ function resolveBundledBackend(name) {
19877
+ try {
19878
+ const currentDir = path.dirname(fileURLToPath(import.meta.url));
19879
+ const isInDist = currentDir.endsWith("dist") || currentDir.endsWith("dist/");
19880
+ const bundledDir = isInDist ? path.resolve(currentDir, "bundled", name) : path.resolve(currentDir, "..", "dist", "bundled", name);
19881
+ if (fs.existsSync(bundledDir)) {
19882
+ return bundledDir;
19883
+ }
19884
+ } catch (error2) {}
19885
+ return null;
19886
+ }
19873
19887
  function getBackendCommand(language, config2) {
19874
19888
  const { autoUpdate } = config2;
19875
19889
  if (language === "python") {
19876
19890
  if (!config2.python.enabled)
19877
19891
  return null;
19878
19892
  if (config2.python.provider === "pyright-mcp") {
19893
+ const bundledPath = resolveBundledBackend("pyright");
19894
+ if (bundledPath) {
19895
+ console.error(`[Config] Using bundled pyright backend from ${bundledPath}`);
19896
+ return {
19897
+ enabled: true,
19898
+ command: "node",
19899
+ args: [path.join(bundledPath, "dist", "index.js")]
19900
+ };
19901
+ }
19879
19902
  return {
19880
19903
  enabled: true,
19881
19904
  command: "npx",
19882
19905
  args: autoUpdate ? ["--yes", "@treedy/pyright-mcp@latest"] : ["@treedy/pyright-mcp@latest"]
19883
19906
  };
19884
19907
  } else {
19908
+ const bundledPath = resolveBundledBackend("python");
19909
+ if (bundledPath) {
19910
+ console.error(`[Config] Using bundled python backend from ${bundledPath}`);
19911
+ return {
19912
+ enabled: true,
19913
+ command: "uv",
19914
+ args: ["run", "--directory", bundledPath, "python-lsp-mcp"]
19915
+ };
19916
+ }
19885
19917
  return {
19886
19918
  enabled: true,
19887
19919
  command: "uvx",
@@ -19891,6 +19923,15 @@ function getBackendCommand(language, config2) {
19891
19923
  } else if (language === "typescript") {
19892
19924
  if (!config2.typescript.enabled)
19893
19925
  return null;
19926
+ const bundledPath = resolveBundledBackend("typescript");
19927
+ if (bundledPath) {
19928
+ console.error(`[Config] Using bundled typescript backend from ${bundledPath}`);
19929
+ return {
19930
+ enabled: true,
19931
+ command: "node",
19932
+ args: [path.join(bundledPath, "dist", "index.js")]
19933
+ };
19934
+ }
19894
19935
  return {
19895
19936
  enabled: true,
19896
19937
  command: "npx",
@@ -19899,6 +19940,15 @@ function getBackendCommand(language, config2) {
19899
19940
  } else if (language === "vue") {
19900
19941
  if (!config2.vue.enabled)
19901
19942
  return null;
19943
+ const bundledPath = resolveBundledBackend("vue");
19944
+ if (bundledPath) {
19945
+ console.error(`[Config] Using bundled vue backend from ${bundledPath}`);
19946
+ return {
19947
+ enabled: true,
19948
+ command: "node",
19949
+ args: [path.join(bundledPath, "dist", "index.js")]
19950
+ };
19951
+ }
19902
19952
  return {
19903
19953
  enabled: true,
19904
19954
  command: "npx",
@@ -20487,7 +20537,7 @@ class StdioClientTransport {
20487
20537
  if (this._process) {
20488
20538
  throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");
20489
20539
  }
20490
- return new Promise((resolve, reject) => {
20540
+ return new Promise((resolve2, reject) => {
20491
20541
  this._process = import_cross_spawn.default(this._serverParams.command, this._serverParams.args ?? [], {
20492
20542
  env: {
20493
20543
  ...getDefaultEnvironment(),
@@ -20503,7 +20553,7 @@ class StdioClientTransport {
20503
20553
  this.onerror?.(error2);
20504
20554
  });
20505
20555
  this._process.on("spawn", () => {
20506
- resolve();
20556
+ resolve2();
20507
20557
  });
20508
20558
  this._process.on("close", (_code) => {
20509
20559
  this._process = undefined;
@@ -20550,20 +20600,20 @@ class StdioClientTransport {
20550
20600
  if (this._process) {
20551
20601
  const processToClose = this._process;
20552
20602
  this._process = undefined;
20553
- const closePromise = new Promise((resolve) => {
20603
+ const closePromise = new Promise((resolve2) => {
20554
20604
  processToClose.once("close", () => {
20555
- resolve();
20605
+ resolve2();
20556
20606
  });
20557
20607
  });
20558
20608
  try {
20559
20609
  processToClose.stdin?.end();
20560
20610
  } catch {}
20561
- await Promise.race([closePromise, new Promise((resolve) => setTimeout(resolve, 2000).unref())]);
20611
+ await Promise.race([closePromise, new Promise((resolve2) => setTimeout(resolve2, 2000).unref())]);
20562
20612
  if (processToClose.exitCode === null) {
20563
20613
  try {
20564
20614
  processToClose.kill("SIGTERM");
20565
20615
  } catch {}
20566
- await Promise.race([closePromise, new Promise((resolve) => setTimeout(resolve, 2000).unref())]);
20616
+ await Promise.race([closePromise, new Promise((resolve2) => setTimeout(resolve2, 2000).unref())]);
20567
20617
  }
20568
20618
  if (processToClose.exitCode === null) {
20569
20619
  try {
@@ -20574,15 +20624,15 @@ class StdioClientTransport {
20574
20624
  this._readBuffer.clear();
20575
20625
  }
20576
20626
  send(message) {
20577
- return new Promise((resolve) => {
20627
+ return new Promise((resolve2) => {
20578
20628
  if (!this._process?.stdin) {
20579
20629
  throw new Error("Not connected");
20580
20630
  }
20581
20631
  const json = serializeMessage(message);
20582
20632
  if (this._process.stdin.write(json)) {
20583
- resolve();
20633
+ resolve2();
20584
20634
  } else {
20585
- this._process.stdin.once("drain", resolve);
20635
+ this._process.stdin.once("drain", resolve2);
20586
20636
  }
20587
20637
  });
20588
20638
  }
@@ -20670,11 +20720,31 @@ class BackendManager {
20670
20720
  if (state.status !== "ready") {
20671
20721
  throw new Error(`${language} backend is not ready: ${state.lastError}`);
20672
20722
  }
20673
- const result = await state.client.callTool({
20674
- name: toolName,
20675
- arguments: args
20676
- });
20677
- return result;
20723
+ try {
20724
+ const result = await state.client.callTool({
20725
+ name: toolName,
20726
+ arguments: args
20727
+ });
20728
+ return result;
20729
+ } catch (error2) {
20730
+ state.status = "error";
20731
+ state.lastError = String(error2);
20732
+ console.error(`[BackendManager] ${language} tool call failed, attempting restart:`, error2);
20733
+ try {
20734
+ await this.restartBackend(language);
20735
+ const restarted = this.backends.get(language);
20736
+ if (!restarted || restarted.status !== "ready") {
20737
+ throw new Error(`${language} backend failed to restart`);
20738
+ }
20739
+ const result = await restarted.client.callTool({
20740
+ name: toolName,
20741
+ arguments: args
20742
+ });
20743
+ return result;
20744
+ } catch (restartError) {
20745
+ throw new Error(`${language} backend error after restart: ${restartError}`);
20746
+ }
20747
+ }
20678
20748
  }
20679
20749
  async getTools(language) {
20680
20750
  const state = await this.getBackend(language);
@@ -20748,6 +20818,7 @@ class BackendManager {
20748
20818
  async restartBackend(language) {
20749
20819
  const existing = this.backends.get(language);
20750
20820
  const oldVersion = existing?.serverInfo?.version ?? null;
20821
+ const restartCount = (existing?.restartCount ?? 0) + 1;
20751
20822
  if (existing) {
20752
20823
  console.error(`[BackendManager] Stopping ${language} for update...`);
20753
20824
  try {
@@ -20760,6 +20831,7 @@ class BackendManager {
20760
20831
  }
20761
20832
  console.error(`[BackendManager] Starting fresh ${language} backend...`);
20762
20833
  const state = await this.startBackend(language);
20834
+ state.restartCount = restartCount;
20763
20835
  const newVersion = state.serverInfo?.version ?? null;
20764
20836
  return { oldVersion, newVersion };
20765
20837
  }
@@ -20783,12 +20855,12 @@ class BackendManager {
20783
20855
 
20784
20856
  // src/tools/meta.ts
20785
20857
  import { readFileSync } from "fs";
20786
- import { dirname, join } from "path";
20787
- import { fileURLToPath } from "url";
20788
- var __dirname2 = dirname(fileURLToPath(import.meta.url));
20858
+ import { dirname as dirname2, join as join2 } from "path";
20859
+ import { fileURLToPath as fileURLToPath2 } from "url";
20860
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
20789
20861
  var serverVersion = "0.1.0";
20790
20862
  try {
20791
- const packageJson = JSON.parse(readFileSync(join(__dirname2, "../../package.json"), "utf-8"));
20863
+ const packageJson = JSON.parse(readFileSync(join2(__dirname2, "../../package.json"), "utf-8"));
20792
20864
  serverVersion = packageJson.version;
20793
20865
  } catch {}
20794
20866
  async function status(backendManager, config2) {
@@ -21586,6 +21658,7 @@ var packageJson = require2("../package.json");
21586
21658
  var config2 = loadConfig();
21587
21659
  var backendManager = new BackendManager(config2);
21588
21660
  var startedBackends = new Set;
21661
+ var registeredTools = new Set;
21589
21662
  var server = new McpServer({
21590
21663
  name: "lsp-mcp",
21591
21664
  version: packageJson.version
@@ -21598,46 +21671,7 @@ function jsonSchemaToZod(schema) {
21598
21671
  }
21599
21672
  const required2 = new Set(schema.required || []);
21600
21673
  for (const [key, prop] of Object.entries(schema.properties)) {
21601
- let zodType;
21602
- switch (prop.type) {
21603
- case "string":
21604
- zodType = exports_external.string();
21605
- if (prop.enum) {
21606
- zodType = exports_external.enum(prop.enum);
21607
- }
21608
- break;
21609
- case "number":
21610
- case "integer":
21611
- zodType = exports_external.number();
21612
- if (prop.type === "integer") {
21613
- zodType = zodType.int();
21614
- }
21615
- if (prop.exclusiveMinimum !== undefined) {
21616
- zodType = zodType.gt(prop.exclusiveMinimum);
21617
- }
21618
- if (prop.minimum !== undefined) {
21619
- zodType = zodType.gte(prop.minimum);
21620
- }
21621
- if (prop.maximum !== undefined) {
21622
- zodType = zodType.lte(prop.maximum);
21623
- }
21624
- break;
21625
- case "boolean":
21626
- zodType = exports_external.boolean();
21627
- break;
21628
- case "array":
21629
- if (prop.items?.type === "string") {
21630
- zodType = exports_external.array(exports_external.string());
21631
- } else {
21632
- zodType = exports_external.array(exports_external.any());
21633
- }
21634
- break;
21635
- case "object":
21636
- zodType = exports_external.record(exports_external.any());
21637
- break;
21638
- default:
21639
- zodType = exports_external.any();
21640
- }
21674
+ let zodType = schemaToZod(prop);
21641
21675
  if (prop.description) {
21642
21676
  zodType = zodType.describe(prop.description);
21643
21677
  }
@@ -21651,16 +21685,101 @@ function jsonSchemaToZod(schema) {
21651
21685
  }
21652
21686
  return result;
21653
21687
  }
21688
+ function schemaToZod(schema) {
21689
+ if (!schema)
21690
+ return exports_external.any();
21691
+ if (schema.oneOf || schema.anyOf) {
21692
+ const variants = schema.oneOf ?? schema.anyOf;
21693
+ const mapped = variants.map((variant) => schemaToZod(variant));
21694
+ if (mapped.length === 1)
21695
+ return mapped[0];
21696
+ if (mapped.length > 1)
21697
+ return exports_external.union(mapped);
21698
+ return exports_external.any();
21699
+ }
21700
+ if (schema.allOf) {
21701
+ const variants = schema.allOf;
21702
+ if (variants.length === 0)
21703
+ return exports_external.any();
21704
+ return variants.map((variant) => schemaToZod(variant)).reduce((acc, next) => exports_external.intersection(acc, next));
21705
+ }
21706
+ if (schema.enum && schema.type === "string") {
21707
+ return exports_external.enum(schema.enum);
21708
+ }
21709
+ switch (schema.type) {
21710
+ case "string": {
21711
+ let zodType = exports_external.string();
21712
+ if (schema.minLength !== undefined)
21713
+ zodType = zodType.min(schema.minLength);
21714
+ if (schema.maxLength !== undefined)
21715
+ zodType = zodType.max(schema.maxLength);
21716
+ if (schema.pattern) {
21717
+ try {
21718
+ zodType = zodType.regex(new RegExp(schema.pattern));
21719
+ } catch {}
21720
+ }
21721
+ return zodType;
21722
+ }
21723
+ case "number":
21724
+ case "integer": {
21725
+ let zodType = exports_external.number();
21726
+ if (schema.type === "integer") {
21727
+ zodType = zodType.int();
21728
+ }
21729
+ if (schema.exclusiveMinimum !== undefined) {
21730
+ zodType = zodType.gt(schema.exclusiveMinimum);
21731
+ }
21732
+ if (schema.minimum !== undefined) {
21733
+ zodType = zodType.gte(schema.minimum);
21734
+ }
21735
+ if (schema.maximum !== undefined) {
21736
+ zodType = zodType.lte(schema.maximum);
21737
+ }
21738
+ return zodType;
21739
+ }
21740
+ case "boolean":
21741
+ return exports_external.boolean();
21742
+ case "array":
21743
+ return exports_external.array(schemaToZod(schema.items ?? {}));
21744
+ case "object": {
21745
+ if (schema.properties) {
21746
+ const shape = {};
21747
+ const required2 = new Set(schema.required || []);
21748
+ for (const [key, prop] of Object.entries(schema.properties)) {
21749
+ let propSchema = schemaToZod(prop);
21750
+ if (prop.description) {
21751
+ propSchema = propSchema.describe(prop.description);
21752
+ }
21753
+ if (prop.default !== undefined) {
21754
+ propSchema = propSchema.default(prop.default);
21755
+ }
21756
+ if (!required2.has(key)) {
21757
+ propSchema = propSchema.optional();
21758
+ }
21759
+ shape[key] = propSchema;
21760
+ }
21761
+ return exports_external.object(shape).passthrough();
21762
+ }
21763
+ return exports_external.record(exports_external.any());
21764
+ }
21765
+ default:
21766
+ return exports_external.any();
21767
+ }
21768
+ }
21654
21769
  function registerBackendTools(language, tools) {
21655
21770
  let count = 0;
21656
21771
  for (const tool of tools) {
21657
21772
  const namespacedName = `${language}_${tool.name}`;
21773
+ if (registeredTools.has(namespacedName)) {
21774
+ continue;
21775
+ }
21658
21776
  const zodSchema = jsonSchemaToZod(tool.inputSchema);
21659
21777
  server.registerTool(namespacedName, {
21660
21778
  description: tool.description || `${language} ${tool.name} tool`,
21661
21779
  inputSchema: zodSchema
21662
21780
  }, async (args) => backendManager.callTool(language, tool.name, args));
21663
21781
  console.error(`[lsp-mcp] Registered ${namespacedName}`);
21782
+ registeredTools.add(namespacedName);
21664
21783
  count++;
21665
21784
  }
21666
21785
  server.sendToolListChanged();
@@ -21677,7 +21796,7 @@ async function startAndRegisterBackend(language) {
21677
21796
  const tools = await backendManager.getTools(language);
21678
21797
  const count = registerBackendTools(language, tools);
21679
21798
  startedBackends.add(language);
21680
- console.error(`[lsp-mcp] ${language}: ${count} tools registered`);
21799
+ console.error(`[lsp-mcp] ${language}: ${count} new tools registered`);
21681
21800
  return count;
21682
21801
  } catch (error2) {
21683
21802
  console.error(`[lsp-mcp] Failed to start ${language} backend:`, error2);
@@ -21687,14 +21806,10 @@ async function startAndRegisterBackend(language) {
21687
21806
  async function updateAndRestartBackend(language) {
21688
21807
  console.error(`[lsp-mcp] Updating ${language} backend...`);
21689
21808
  const result = await backendManager.restartBackend(language);
21690
- if (startedBackends.has(language)) {
21691
- console.error(`[lsp-mcp] ${language} backend updated, tools still available`);
21692
- } else {
21693
- const tools = await backendManager.getTools(language);
21694
- registerBackendTools(language, tools);
21695
- startedBackends.add(language);
21696
- console.error(`[lsp-mcp] ${language} backend updated and ${tools.length} tools registered`);
21697
- }
21809
+ const tools = await backendManager.getTools(language);
21810
+ const newlyRegistered = registerBackendTools(language, tools);
21811
+ startedBackends.add(language);
21812
+ console.error(`[lsp-mcp] ${language} backend updated (${newlyRegistered} new tools registered)`);
21698
21813
  return result;
21699
21814
  }
21700
21815
  server.registerTool("status", { description: "Get status of all LSP backends and server configuration" }, async () => status(backendManager, config2));
@@ -21716,6 +21831,7 @@ server.registerTool("update_backend", {
21716
21831
  }, async ({ language }) => updateBackend(language, backendManager, config2, updateAndRestartBackend));
21717
21832
  var KNOWN_TOOLS = {
21718
21833
  python: [
21834
+ { name: "switch_workspace", description: "Switch the active workspace to a new project directory", schema: { path: exports_external.string() } },
21719
21835
  { name: "hover", description: "Get documentation for the symbol at the given position", schema: { file: exports_external.string(), line: exports_external.number().int(), column: exports_external.number().int() } },
21720
21836
  { name: "definition", description: "Get the definition location for the symbol at the given position", schema: { file: exports_external.string(), line: exports_external.number().int(), column: exports_external.number().int() } },
21721
21837
  { name: "references", description: "Find all references to the symbol at the given position", schema: { file: exports_external.string(), line: exports_external.number().int(), column: exports_external.number().int() } },
@@ -21729,6 +21845,7 @@ var KNOWN_TOOLS = {
21729
21845
  { name: "status", description: "Get the status of the Python MCP server", schema: {} }
21730
21846
  ],
21731
21847
  typescript: [
21848
+ { name: "switch_workspace", description: "Switch the active workspace to a new project directory", schema: { path: exports_external.string() } },
21732
21849
  { name: "hover", description: "Get type information and documentation at a specific position", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
21733
21850
  { name: "definition", description: "Go to definition of a symbol at a specific position", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
21734
21851
  { name: "references", description: "Find all references to a symbol at a specific position", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
@@ -21746,6 +21863,7 @@ var KNOWN_TOOLS = {
21746
21863
  { name: "apply_refactor", description: "Apply a specific refactoring action at a position", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive(), refactorName: exports_external.string(), actionName: exports_external.string(), preview: exports_external.boolean().default(false).optional() } }
21747
21864
  ],
21748
21865
  vue: [
21866
+ { name: "switch_workspace", description: "Switch the active workspace to a new project directory", schema: { path: exports_external.string() } },
21749
21867
  { name: "hover", description: "Get type information and documentation at a specific position in a Vue SFC file", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
21750
21868
  { name: "definition", description: "Go to definition of a symbol at a specific position in a Vue SFC file", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
21751
21869
  { name: "references", description: "Find all references to a symbol at a specific position in a Vue SFC file", schema: { file: exports_external.string(), line: exports_external.number().int().positive(), column: exports_external.number().int().positive() } },
@@ -21759,6 +21877,43 @@ var KNOWN_TOOLS = {
21759
21877
  { name: "status", description: "Check Vue Language Server status for a project", schema: { file: exports_external.string() } }
21760
21878
  ]
21761
21879
  };
21880
+ server.registerTool("switch_workspace", {
21881
+ description: "Switch the active workspace for ALL backends simultaneously. This clears caches and refocuses code intelligence on the new project root.",
21882
+ inputSchema: {
21883
+ path: exports_external.string().describe("Absolute path to the new project root directory")
21884
+ }
21885
+ }, async ({ path: workspacePath }) => {
21886
+ const results = {};
21887
+ const languages = [];
21888
+ if (config2.python.enabled)
21889
+ languages.push("python");
21890
+ if (config2.typescript.enabled)
21891
+ languages.push("typescript");
21892
+ if (config2.vue.enabled)
21893
+ languages.push("vue");
21894
+ await Promise.all(languages.map(async (lang) => {
21895
+ try {
21896
+ if (startedBackends.has(lang)) {
21897
+ const result = await backendManager.callTool(lang, "switch_workspace", { path: workspacePath });
21898
+ results[lang] = JSON.parse(result.content[0].text);
21899
+ } else {
21900
+ results[lang] = { status: "not_started", message: "Workspace will be set when backend starts" };
21901
+ }
21902
+ } catch (error2) {
21903
+ results[lang] = { error: String(error2) };
21904
+ }
21905
+ }));
21906
+ return {
21907
+ content: [{
21908
+ type: "text",
21909
+ text: JSON.stringify({
21910
+ success: true,
21911
+ workspace: workspacePath,
21912
+ results
21913
+ }, null, 2)
21914
+ }]
21915
+ };
21916
+ });
21762
21917
  function preRegisterKnownTools() {
21763
21918
  const languages = [];
21764
21919
  if (config2.python.enabled)
@@ -21792,6 +21947,7 @@ function preRegisterKnownTools() {
21792
21947
  }
21793
21948
  return backendManager.callTool(language, tool.name, args);
21794
21949
  });
21950
+ registeredTools.add(namespacedName);
21795
21951
  totalCount++;
21796
21952
  }
21797
21953
  console.error(`[lsp-mcp] Pre-registered ${tools.length} ${language} tools`);
@@ -21852,4 +22008,4 @@ main().catch((error2) => {
21852
22008
  process.exit(1);
21853
22009
  });
21854
22010
 
21855
- //# debugId=45E34912A1845F5D64756E2164756E21
22011
+ //# debugId=B173E4D0EEF312F264756E2164756E21