pybao-cli 1.3.21 → 1.3.22

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 (133) hide show
  1. package/dist/REPL-U233WVGQ.js +42 -0
  2. package/dist/{acp-5COUMMLN.js → acp-MGSGKN7I.js} +26 -26
  3. package/dist/{agentsValidate-DKGJ5OX4.js → agentsValidate-E24UODFJ.js} +7 -7
  4. package/dist/{ask-QW644CAZ.js → ask-WVNNLMSZ.js} +25 -25
  5. package/dist/{autoUpdater-WUTZGWEM.js → autoUpdater-R5VI5NS5.js} +3 -3
  6. package/dist/{chunk-KANFF7SM.js → chunk-3BDBJ76H.js} +1 -1
  7. package/dist/{chunk-LCN6UMC2.js → chunk-3GSGGTNG.js} +1 -1
  8. package/dist/{chunk-YEDGG2CM.js → chunk-3NJ6JQ2M.js} +6 -12
  9. package/dist/chunk-3NJ6JQ2M.js.map +7 -0
  10. package/dist/{chunk-VXPAJIEJ.js → chunk-7OOX64M4.js} +3 -3
  11. package/dist/{chunk-4FSJIGYW.js → chunk-B4Z3JBM6.js} +2 -2
  12. package/dist/{chunk-Q27MKRQ5.js → chunk-BDRQU7KP.js} +4 -4
  13. package/dist/{chunk-YVLQDPDN.js → chunk-BHRZG737.js} +2 -2
  14. package/dist/{chunk-KAAPCK6R.js → chunk-BLZG4P4W.js} +4 -4
  15. package/dist/{chunk-Z7P6CYVJ.js → chunk-C27RUGNT.js} +2 -2
  16. package/dist/{chunk-PF3A6LJD.js → chunk-D5XZE6VD.js} +1 -1
  17. package/dist/{chunk-RSCGHYX4.js → chunk-HIN7NLKB.js} +3 -3
  18. package/dist/{chunk-3NZTTP2W.js → chunk-JPR5LF4I.js} +33 -33
  19. package/dist/{chunk-3NZTTP2W.js.map → chunk-JPR5LF4I.js.map} +2 -2
  20. package/dist/{chunk-PJ2UYD4Q.js → chunk-JZTNGHID.js} +2 -2
  21. package/dist/{chunk-6IQ6RNSC.js → chunk-O6LTYDEM.js} +2 -2
  22. package/dist/{chunk-WU4SXVFN.js → chunk-OFNZCXTL.js} +1130 -345
  23. package/dist/chunk-OFNZCXTL.js.map +7 -0
  24. package/dist/{chunk-HJPCQROC.js → chunk-OK6YLALO.js} +1 -1
  25. package/dist/{chunk-DTOUFBLG.js → chunk-Q6NZXTU7.js} +3 -3
  26. package/dist/{chunk-ZQLAZEQ6.js → chunk-QKK7OEVT.js} +1 -1
  27. package/dist/{chunk-X2LHX4TN.js → chunk-QPYMEJ7J.js} +1 -1
  28. package/dist/{chunk-IA565ACR.js → chunk-RGMQE5W7.js} +3 -3
  29. package/dist/{chunk-UDXJD3B5.js → chunk-RQHQ3V5R.js} +1 -1
  30. package/dist/{chunk-UDXJD3B5.js.map → chunk-RQHQ3V5R.js.map} +1 -1
  31. package/dist/{chunk-Q74XWGWS.js → chunk-SPSZIFD3.js} +1 -1
  32. package/dist/{chunk-TBU6CIW7.js → chunk-TB6NRY5H.js} +1 -1
  33. package/dist/{chunk-LTUBDTY7.js → chunk-UDHQY254.js} +1 -1
  34. package/dist/{chunk-ILKTL4HO.js → chunk-VHPGBFI2.js} +2 -2
  35. package/dist/{chunk-LFT6GMDJ.js → chunk-VNX4XL5W.js} +3 -3
  36. package/dist/{chunk-PWZPQLA5.js → chunk-Z3QCGGDI.js} +3 -3
  37. package/dist/{cli-5AQQAMDZ.js → cli-VHCSI3MC.js} +77 -77
  38. package/dist/commands-OAY7CB4V.js +46 -0
  39. package/dist/{config-XUTCS32D.js → config-L3IXWETT.js} +4 -4
  40. package/dist/{context-BJBOG5ML.js → context-F2IIOXEP.js} +5 -5
  41. package/dist/{customCommands-FCGJVPMM.js → customCommands-POVQCNWI.js} +4 -4
  42. package/dist/{env-PCEHNXQ7.js → env-5OAJSWRZ.js} +2 -2
  43. package/dist/index.js +3 -3
  44. package/dist/{llm-YXYHYLLL.js → llm-TQRNSHD2.js} +26 -26
  45. package/dist/{llmLazy-BWNMELGK.js → llmLazy-LP3VLWST.js} +1 -1
  46. package/dist/{loader-UXDARCPS.js → loader-LERT53VD.js} +4 -4
  47. package/dist/{mcp-OD4RSPAA.js → mcp-7WABABD5.js} +7 -7
  48. package/dist/{mentionProcessor-MRLHJCG7.js → mentionProcessor-3EES7EOM.js} +5 -5
  49. package/dist/{messages-WDA7YIIR.js → messages-KDYSBWPF.js} +1 -1
  50. package/dist/{model-E7A4ZTH3.js → model-H5SZYB3G.js} +5 -5
  51. package/dist/{openai-6VE4E33T.js → openai-OJDXHXW7.js} +5 -5
  52. package/dist/{outputStyles-ALNI7DMM.js → outputStyles-KPZL4IL6.js} +4 -4
  53. package/dist/{pluginRuntime-ZJM5CYBI.js → pluginRuntime-FMYJ2OLJ.js} +6 -6
  54. package/dist/{pluginValidation-P7F37TRM.js → pluginValidation-3XL3376C.js} +6 -6
  55. package/dist/prompts-5ZSQVFA4.js +48 -0
  56. package/dist/{pybAgentSessionLoad-DXA2GXAD.js → pybAgentSessionLoad-CWFVVJJP.js} +4 -4
  57. package/dist/{pybAgentSessionResume-GSTPB6PZ.js → pybAgentSessionResume-NOZGRPWX.js} +4 -4
  58. package/dist/{pybAgentStreamJsonSession-NJYZ5ZC5.js → pybAgentStreamJsonSession-XJBNIDCX.js} +1 -1
  59. package/dist/{pybHooks-G4QW3QWC.js → pybHooks-X4Z6SUM3.js} +4 -4
  60. package/dist/query-I6RAXHNW.js +50 -0
  61. package/dist/{ripgrep-RLDVZ7XG.js → ripgrep-2FLGSL5E.js} +3 -3
  62. package/dist/{skillMarketplace-N45WWBB3.js → skillMarketplace-EZFJG2VQ.js} +3 -3
  63. package/dist/{state-PVTHPFRK.js → state-TJYRRWRD.js} +2 -2
  64. package/dist/{theme-7YQL4AQ4.js → theme-XFYRVMO2.js} +5 -5
  65. package/dist/{toolPermissionSettings-EGYQOIYG.js → toolPermissionSettings-DFXSQ5HV.js} +6 -6
  66. package/dist/tools-CNY53VUO.js +47 -0
  67. package/dist/{userInput-6Z5PYOLR.js → userInput-EU5BLE3W.js} +27 -27
  68. package/package.json +1 -1
  69. package/dist/REPL-4QRH44HC.js +0 -42
  70. package/dist/chunk-WU4SXVFN.js.map +0 -7
  71. package/dist/chunk-YEDGG2CM.js.map +0 -7
  72. package/dist/commands-UAI6QEAI.js +0 -46
  73. package/dist/prompts-VPJ5WN33.js +0 -48
  74. package/dist/query-LGA6DMR3.js +0 -50
  75. package/dist/tools-CMR3PLSX.js +0 -47
  76. /package/dist/{REPL-4QRH44HC.js.map → REPL-U233WVGQ.js.map} +0 -0
  77. /package/dist/{acp-5COUMMLN.js.map → acp-MGSGKN7I.js.map} +0 -0
  78. /package/dist/{agentsValidate-DKGJ5OX4.js.map → agentsValidate-E24UODFJ.js.map} +0 -0
  79. /package/dist/{ask-QW644CAZ.js.map → ask-WVNNLMSZ.js.map} +0 -0
  80. /package/dist/{autoUpdater-WUTZGWEM.js.map → autoUpdater-R5VI5NS5.js.map} +0 -0
  81. /package/dist/{chunk-KANFF7SM.js.map → chunk-3BDBJ76H.js.map} +0 -0
  82. /package/dist/{chunk-LCN6UMC2.js.map → chunk-3GSGGTNG.js.map} +0 -0
  83. /package/dist/{chunk-VXPAJIEJ.js.map → chunk-7OOX64M4.js.map} +0 -0
  84. /package/dist/{chunk-4FSJIGYW.js.map → chunk-B4Z3JBM6.js.map} +0 -0
  85. /package/dist/{chunk-Q27MKRQ5.js.map → chunk-BDRQU7KP.js.map} +0 -0
  86. /package/dist/{chunk-YVLQDPDN.js.map → chunk-BHRZG737.js.map} +0 -0
  87. /package/dist/{chunk-KAAPCK6R.js.map → chunk-BLZG4P4W.js.map} +0 -0
  88. /package/dist/{chunk-Z7P6CYVJ.js.map → chunk-C27RUGNT.js.map} +0 -0
  89. /package/dist/{chunk-PF3A6LJD.js.map → chunk-D5XZE6VD.js.map} +0 -0
  90. /package/dist/{chunk-RSCGHYX4.js.map → chunk-HIN7NLKB.js.map} +0 -0
  91. /package/dist/{chunk-PJ2UYD4Q.js.map → chunk-JZTNGHID.js.map} +0 -0
  92. /package/dist/{chunk-6IQ6RNSC.js.map → chunk-O6LTYDEM.js.map} +0 -0
  93. /package/dist/{chunk-HJPCQROC.js.map → chunk-OK6YLALO.js.map} +0 -0
  94. /package/dist/{chunk-DTOUFBLG.js.map → chunk-Q6NZXTU7.js.map} +0 -0
  95. /package/dist/{chunk-ZQLAZEQ6.js.map → chunk-QKK7OEVT.js.map} +0 -0
  96. /package/dist/{chunk-X2LHX4TN.js.map → chunk-QPYMEJ7J.js.map} +0 -0
  97. /package/dist/{chunk-IA565ACR.js.map → chunk-RGMQE5W7.js.map} +0 -0
  98. /package/dist/{chunk-Q74XWGWS.js.map → chunk-SPSZIFD3.js.map} +0 -0
  99. /package/dist/{chunk-TBU6CIW7.js.map → chunk-TB6NRY5H.js.map} +0 -0
  100. /package/dist/{chunk-LTUBDTY7.js.map → chunk-UDHQY254.js.map} +0 -0
  101. /package/dist/{chunk-ILKTL4HO.js.map → chunk-VHPGBFI2.js.map} +0 -0
  102. /package/dist/{chunk-LFT6GMDJ.js.map → chunk-VNX4XL5W.js.map} +0 -0
  103. /package/dist/{chunk-PWZPQLA5.js.map → chunk-Z3QCGGDI.js.map} +0 -0
  104. /package/dist/{cli-5AQQAMDZ.js.map → cli-VHCSI3MC.js.map} +0 -0
  105. /package/dist/{commands-UAI6QEAI.js.map → commands-OAY7CB4V.js.map} +0 -0
  106. /package/dist/{config-XUTCS32D.js.map → config-L3IXWETT.js.map} +0 -0
  107. /package/dist/{context-BJBOG5ML.js.map → context-F2IIOXEP.js.map} +0 -0
  108. /package/dist/{customCommands-FCGJVPMM.js.map → customCommands-POVQCNWI.js.map} +0 -0
  109. /package/dist/{env-PCEHNXQ7.js.map → env-5OAJSWRZ.js.map} +0 -0
  110. /package/dist/{llm-YXYHYLLL.js.map → llm-TQRNSHD2.js.map} +0 -0
  111. /package/dist/{llmLazy-BWNMELGK.js.map → llmLazy-LP3VLWST.js.map} +0 -0
  112. /package/dist/{loader-UXDARCPS.js.map → loader-LERT53VD.js.map} +0 -0
  113. /package/dist/{mcp-OD4RSPAA.js.map → mcp-7WABABD5.js.map} +0 -0
  114. /package/dist/{mentionProcessor-MRLHJCG7.js.map → mentionProcessor-3EES7EOM.js.map} +0 -0
  115. /package/dist/{messages-WDA7YIIR.js.map → messages-KDYSBWPF.js.map} +0 -0
  116. /package/dist/{model-E7A4ZTH3.js.map → model-H5SZYB3G.js.map} +0 -0
  117. /package/dist/{openai-6VE4E33T.js.map → openai-OJDXHXW7.js.map} +0 -0
  118. /package/dist/{outputStyles-ALNI7DMM.js.map → outputStyles-KPZL4IL6.js.map} +0 -0
  119. /package/dist/{pluginRuntime-ZJM5CYBI.js.map → pluginRuntime-FMYJ2OLJ.js.map} +0 -0
  120. /package/dist/{pluginValidation-P7F37TRM.js.map → pluginValidation-3XL3376C.js.map} +0 -0
  121. /package/dist/{prompts-VPJ5WN33.js.map → prompts-5ZSQVFA4.js.map} +0 -0
  122. /package/dist/{pybAgentSessionLoad-DXA2GXAD.js.map → pybAgentSessionLoad-CWFVVJJP.js.map} +0 -0
  123. /package/dist/{pybAgentSessionResume-GSTPB6PZ.js.map → pybAgentSessionResume-NOZGRPWX.js.map} +0 -0
  124. /package/dist/{pybAgentStreamJsonSession-NJYZ5ZC5.js.map → pybAgentStreamJsonSession-XJBNIDCX.js.map} +0 -0
  125. /package/dist/{pybHooks-G4QW3QWC.js.map → pybHooks-X4Z6SUM3.js.map} +0 -0
  126. /package/dist/{query-LGA6DMR3.js.map → query-I6RAXHNW.js.map} +0 -0
  127. /package/dist/{ripgrep-RLDVZ7XG.js.map → ripgrep-2FLGSL5E.js.map} +0 -0
  128. /package/dist/{skillMarketplace-N45WWBB3.js.map → skillMarketplace-EZFJG2VQ.js.map} +0 -0
  129. /package/dist/{state-PVTHPFRK.js.map → state-TJYRRWRD.js.map} +0 -0
  130. /package/dist/{theme-7YQL4AQ4.js.map → theme-XFYRVMO2.js.map} +0 -0
  131. /package/dist/{toolPermissionSettings-EGYQOIYG.js.map → toolPermissionSettings-DFXSQ5HV.js.map} +0 -0
  132. /package/dist/{tools-CMR3PLSX.js.map → tools-CNY53VUO.js.map} +0 -0
  133. /package/dist/{userInput-6Z5PYOLR.js.map → userInput-EU5BLE3W.js.map} +0 -0
@@ -26,51 +26,52 @@ import {
26
26
  hasPermissionsToUseTool,
27
27
  hasReadPermission,
28
28
  query
29
- } from "./chunk-3NZTTP2W.js";
29
+ } from "./chunk-JPR5LF4I.js";
30
30
  import {
31
31
  FallbackToolUseRejectedMessage,
32
32
  MCPTool,
33
33
  getClients,
34
34
  getMCPTools
35
- } from "./chunk-Q27MKRQ5.js";
35
+ } from "./chunk-BDRQU7KP.js";
36
36
  import {
37
37
  queryLLM
38
- } from "./chunk-KAAPCK6R.js";
38
+ } from "./chunk-BLZG4P4W.js";
39
39
  import {
40
40
  generateAgentId
41
- } from "./chunk-PJ2UYD4Q.js";
41
+ } from "./chunk-JZTNGHID.js";
42
42
  import {
43
43
  getActiveAgents,
44
44
  getAgentByType,
45
45
  getAvailableAgentTypes
46
- } from "./chunk-6IQ6RNSC.js";
46
+ } from "./chunk-O6LTYDEM.js";
47
47
  import {
48
48
  INTERRUPT_MESSAGE,
49
49
  createAssistantMessage,
50
50
  createUserMessage,
51
51
  getLastAssistantMessageId
52
- } from "./chunk-LCN6UMC2.js";
52
+ } from "./chunk-3GSGGTNG.js";
53
53
  import {
54
54
  getModelManager
55
- } from "./chunk-IA565ACR.js";
55
+ } from "./chunk-RGMQE5W7.js";
56
56
  import {
57
57
  getContext
58
- } from "./chunk-PWZPQLA5.js";
58
+ } from "./chunk-Z3QCGGDI.js";
59
59
  import {
60
60
  getTheme
61
- } from "./chunk-X2LHX4TN.js";
61
+ } from "./chunk-QPYMEJ7J.js";
62
62
  import {
63
63
  debug
64
- } from "./chunk-LTUBDTY7.js";
64
+ } from "./chunk-UDHQY254.js";
65
65
  import {
66
66
  BunShell,
67
67
  getCwd,
68
68
  getMessagesPath,
69
69
  getNextAvailableLogSidechainNumber,
70
+ getPybBaseDir,
70
71
  logError,
71
72
  overwriteLog,
72
73
  readTaskOutput
73
- } from "./chunk-TBU6CIW7.js";
74
+ } from "./chunk-TB6NRY5H.js";
74
75
  import {
75
76
  formatDuration,
76
77
  formatNumber
@@ -1021,17 +1022,16 @@ var ListMcpResourcesTool = {
1021
1022
  };
1022
1023
 
1023
1024
  // src/tools/search/LspTool/LspTool.tsx
1024
- import { existsSync as existsSync2, readFileSync as readFileSync2, statSync } from "fs";
1025
+ import { existsSync as existsSync4, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
1025
1026
  import { Box as Box4, Text as Text4 } from "ink";
1026
- import { createRequire } from "node:module";
1027
- import { extname, join as join2, relative } from "path";
1027
+ import { extname as extname3 } from "path";
1028
1028
  import React4 from "react";
1029
- import { pathToFileURL } from "url";
1030
1029
  import { z as z4 } from "zod";
1031
1030
 
1032
1031
  // src/tools/search/LspTool/prompt.ts
1033
1032
  var TOOL_NAME_FOR_PROMPT2 = "LSP";
1034
1033
  var PROMPT3 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
1034
+ Supports 29+ languages including Python, Go, Rust, TypeScript, JavaScript, Bash, Java, C++, PHP, and more.
1035
1035
 
1036
1036
  Supported operations:
1037
1037
  - goToDefinition: Find where a symbol is defined
@@ -1049,54 +1049,14 @@ All operations require:
1049
1049
  - line: The line number (1-based, as shown in editors)
1050
1050
  - character: The character offset (1-based, as shown in editors)
1051
1051
 
1052
- Note: LSP servers must be configured for the file type. If no server is available, an error will be returned.`;
1052
+ Note: LSP servers are automatically managed and installed for most languages. For system-level languages (like C++, Java), ensure the corresponding tools (clangd, jdtls) are in your PATH.`;
1053
1053
  var DESCRIPTION3 = PROMPT3;
1054
1054
 
1055
- // src/tools/search/LspTool/LspTool.tsx
1056
- var inputSchema4 = z4.strictObject({
1057
- operation: z4.enum([
1058
- "goToDefinition",
1059
- "findReferences",
1060
- "hover",
1061
- "documentSymbol",
1062
- "workspaceSymbol",
1063
- "goToImplementation",
1064
- "prepareCallHierarchy",
1065
- "incomingCalls",
1066
- "outgoingCalls"
1067
- ]).describe("The LSP operation to perform"),
1068
- filePath: z4.string().describe("The absolute or relative path to the file"),
1069
- line: z4.number().int().positive().describe("The line number (1-based, as shown in editors)"),
1070
- character: z4.number().int().positive().describe("The character offset (1-based, as shown in editors)")
1071
- });
1072
- var outputSchema = z4.object({
1073
- operation: z4.enum([
1074
- "goToDefinition",
1075
- "findReferences",
1076
- "hover",
1077
- "documentSymbol",
1078
- "workspaceSymbol",
1079
- "goToImplementation",
1080
- "prepareCallHierarchy",
1081
- "incomingCalls",
1082
- "outgoingCalls"
1083
- ]).describe("The LSP operation that was performed"),
1084
- result: z4.string().describe("The formatted result of the LSP operation"),
1085
- filePath: z4.string().describe("The file path the operation was performed on"),
1086
- resultCount: z4.number().int().nonnegative().optional().describe("Number of results (definitions, references, symbols)"),
1087
- fileCount: z4.number().int().nonnegative().optional().describe("Number of files containing results")
1088
- });
1089
- var OPERATION_LABELS = {
1090
- goToDefinition: { singular: "definition", plural: "definitions" },
1091
- findReferences: { singular: "reference", plural: "references" },
1092
- documentSymbol: { singular: "symbol", plural: "symbols" },
1093
- workspaceSymbol: { singular: "symbol", plural: "symbols" },
1094
- hover: { singular: "hover info", plural: "hover info", special: "available" },
1095
- goToImplementation: { singular: "implementation", plural: "implementations" },
1096
- prepareCallHierarchy: { singular: "call item", plural: "call items" },
1097
- incomingCalls: { singular: "caller", plural: "callers" },
1098
- outgoingCalls: { singular: "callee", plural: "callees" }
1099
- };
1055
+ // src/tools/search/LspTool/TypeScriptBackend.ts
1056
+ import { statSync } from "fs";
1057
+ import { createRequire } from "node:module";
1058
+ import { extname, join as join2, relative } from "path";
1059
+ import { pathToFileURL } from "url";
1100
1060
  function extractSymbolAtPosition(lines, zeroBasedLine, zeroBasedCharacter) {
1101
1061
  try {
1102
1062
  if (zeroBasedLine < 0 || zeroBasedLine >= lines.length) return null;
@@ -1334,10 +1294,1021 @@ function getOrCreateTsProject(projectCwd) {
1334
1294
  projectCache.set(projectCwd, state);
1335
1295
  return state;
1336
1296
  }
1337
- function isFileTypeSupportedByTypescriptBackend(filePath) {
1338
- const ext = extname(filePath).toLowerCase();
1339
- return ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".jsx" || ext === ".mts" || ext === ".cts" || ext === ".mjs" || ext === ".cjs";
1297
+ var TypeScriptBackend = {
1298
+ tryLoadTypeScriptModule,
1299
+ isFileTypeSupported(filePath) {
1300
+ const ext = extname(filePath).toLowerCase();
1301
+ return ext === ".ts" || ext === ".tsx" || ext === ".js" || ext === ".jsx" || ext === ".mts" || ext === ".cts" || ext === ".mjs" || ext === ".cjs";
1302
+ },
1303
+ extractSymbolAtPosition,
1304
+ toProjectRelativeIfPossible,
1305
+ runOperation(operation, absPath, line, character) {
1306
+ const project = getOrCreateTsProject(getCwd());
1307
+ if (!project) {
1308
+ return {
1309
+ formatted: "LSP server manager not initialized. This may indicate a startup issue.",
1310
+ resultCount: 0,
1311
+ fileCount: 0
1312
+ };
1313
+ }
1314
+ project.rootFiles.add(absPath);
1315
+ const ts = project.ts;
1316
+ const service = project.languageService;
1317
+ const program = service.getProgram?.();
1318
+ if (!program) {
1319
+ throw new Error("TypeScript program not available");
1320
+ }
1321
+ const sourceFile = program.getSourceFile(absPath);
1322
+ if (!sourceFile) {
1323
+ throw new Error("File is not part of the TypeScript program");
1324
+ }
1325
+ const pos = ts.getPositionOfLineAndCharacter(
1326
+ sourceFile,
1327
+ line - 1,
1328
+ character - 1
1329
+ );
1330
+ switch (operation) {
1331
+ case "goToDefinition": {
1332
+ const defs = service.getDefinitionAtPosition?.(absPath, pos) ?? [];
1333
+ const locations = defs.map((d) => {
1334
+ const defSourceFile = program.getSourceFile(d.fileName);
1335
+ if (!defSourceFile) return null;
1336
+ const lc = ts.getLineAndCharacterOfPosition(
1337
+ defSourceFile,
1338
+ d.textSpan.start
1339
+ );
1340
+ return {
1341
+ fileName: d.fileName,
1342
+ line0: lc.line,
1343
+ character0: lc.character
1344
+ };
1345
+ }).filter(Boolean);
1346
+ return formatGoToDefinitionResult(locations);
1347
+ }
1348
+ case "goToImplementation": {
1349
+ const impls = service.getImplementationAtPosition?.(absPath, pos) ?? [];
1350
+ const locations = impls.map((d) => {
1351
+ const defSourceFile = program.getSourceFile(d.fileName);
1352
+ if (!defSourceFile) return null;
1353
+ const lc = ts.getLineAndCharacterOfPosition(
1354
+ defSourceFile,
1355
+ d.textSpan.start
1356
+ );
1357
+ return {
1358
+ fileName: d.fileName,
1359
+ line0: lc.line,
1360
+ character0: lc.character
1361
+ };
1362
+ }).filter(Boolean);
1363
+ return formatGoToDefinitionResult(locations);
1364
+ }
1365
+ case "findReferences": {
1366
+ const referencedSymbols = service.findReferences?.(absPath, pos) ?? [];
1367
+ const refs = [];
1368
+ for (const sym of referencedSymbols) {
1369
+ for (const ref of sym.references ?? []) {
1370
+ const refSource = program.getSourceFile(ref.fileName);
1371
+ if (!refSource) continue;
1372
+ const lc = ts.getLineAndCharacterOfPosition(
1373
+ refSource,
1374
+ ref.textSpan.start
1375
+ );
1376
+ refs.push({
1377
+ fileName: ref.fileName,
1378
+ line0: lc.line,
1379
+ character0: lc.character
1380
+ });
1381
+ }
1382
+ }
1383
+ return formatFindReferencesResult(refs);
1384
+ }
1385
+ case "hover": {
1386
+ const info = service.getQuickInfoAtPosition?.(absPath, pos);
1387
+ let text = null;
1388
+ let hoverLine0 = line - 1;
1389
+ let hoverCharacter0 = character - 1;
1390
+ if (info) {
1391
+ const parts = [];
1392
+ const signature = ts.displayPartsToString(info.displayParts ?? []);
1393
+ if (signature) parts.push(signature);
1394
+ const doc = ts.displayPartsToString(info.documentation ?? []);
1395
+ if (doc) parts.push(doc);
1396
+ if (info.tags && info.tags.length > 0) {
1397
+ for (const tag of info.tags) {
1398
+ const tagText = ts.displayPartsToString(tag.text ?? []);
1399
+ parts.push(`@${tag.name}${tagText ? ` ${tagText}` : ""}`);
1400
+ }
1401
+ }
1402
+ text = parts.filter(Boolean).join("\n\n");
1403
+ const lc = ts.getLineAndCharacterOfPosition(
1404
+ sourceFile,
1405
+ info.textSpan.start
1406
+ );
1407
+ hoverLine0 = lc.line;
1408
+ hoverCharacter0 = lc.character;
1409
+ }
1410
+ return formatHoverResult(text, hoverLine0, hoverCharacter0);
1411
+ }
1412
+ case "documentSymbol": {
1413
+ const tree = service.getNavigationTree?.(absPath);
1414
+ const lines = [];
1415
+ let count = 0;
1416
+ const kindLabel = (kind) => {
1417
+ const m = {
1418
+ class: "Class",
1419
+ interface: "Interface",
1420
+ enum: "Enum",
1421
+ function: "Function",
1422
+ method: "Method",
1423
+ property: "Property",
1424
+ var: "Variable",
1425
+ let: "Variable",
1426
+ const: "Constant",
1427
+ module: "Module",
1428
+ alias: "Alias",
1429
+ type: "Type"
1430
+ };
1431
+ return m[kind] ?? (kind ? kind[0].toUpperCase() + kind.slice(1) : "Unknown");
1432
+ };
1433
+ const walk = (node, depth) => {
1434
+ const children = node?.childItems ?? [];
1435
+ for (const child of children) {
1436
+ const span = child.spans?.[0];
1437
+ if (!span) continue;
1438
+ const lc = ts.getLineAndCharacterOfPosition(
1439
+ sourceFile,
1440
+ span.start
1441
+ );
1442
+ const indent = " ".repeat(depth);
1443
+ const label = kindLabel(child.kind);
1444
+ const detail = child.kindModifiers ? ` ${child.kindModifiers}` : "";
1445
+ lines.push(
1446
+ `${indent}${child.text} (${label})${detail} - Line ${lc.line + 1}`
1447
+ );
1448
+ count += 1;
1449
+ if (child.childItems && child.childItems.length > 0) {
1450
+ walk(child, depth + 1);
1451
+ }
1452
+ }
1453
+ };
1454
+ walk(tree, 0);
1455
+ return formatDocumentSymbolsResult(lines, count);
1456
+ }
1457
+ case "workspaceSymbol": {
1458
+ const items = service.getNavigateToItems?.("", 100, void 0, true, true) ?? [];
1459
+ if (!items || items.length === 0) {
1460
+ return {
1461
+ formatted: "No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.",
1462
+ resultCount: 0,
1463
+ fileCount: 0
1464
+ };
1465
+ }
1466
+ const lines = [
1467
+ `Found ${items.length} symbol${items.length === 1 ? "" : "s"} in workspace:`
1468
+ ];
1469
+ const grouped = groupLocationsByFile(
1470
+ items.map((it) => ({
1471
+ fileName: it.fileName,
1472
+ item: it
1473
+ }))
1474
+ );
1475
+ for (const [file, itemsInFile] of grouped) {
1476
+ lines.push(`
1477
+ ${file}:`);
1478
+ for (const wrapper of itemsInFile) {
1479
+ const it = wrapper.item;
1480
+ const sf = program.getSourceFile(it.fileName);
1481
+ if (!sf) continue;
1482
+ const span = it.textSpan;
1483
+ const lc = span ? ts.getLineAndCharacterOfPosition(sf, span.start) : { line: 0, character: 0 };
1484
+ const label = it.kind ? String(it.kind)[0].toUpperCase() + String(it.kind).slice(1) : "Symbol";
1485
+ let lineStr = ` ${it.name} (${label}) - Line ${lc.line + 1}`;
1486
+ if (it.containerName) lineStr += ` in ${it.containerName}`;
1487
+ lines.push(lineStr);
1488
+ }
1489
+ }
1490
+ return {
1491
+ formatted: lines.join("\n"),
1492
+ resultCount: items.length,
1493
+ fileCount: grouped.size
1494
+ };
1495
+ }
1496
+ case "prepareCallHierarchy":
1497
+ case "incomingCalls":
1498
+ case "outgoingCalls": {
1499
+ return {
1500
+ formatted: `Error performing ${operation}: Call hierarchy is not supported by the TypeScript backend`,
1501
+ resultCount: 0,
1502
+ fileCount: 0
1503
+ };
1504
+ }
1505
+ default: {
1506
+ return {
1507
+ formatted: `Error performing ${operation}: Unsupported operation`,
1508
+ resultCount: 0,
1509
+ fileCount: 0
1510
+ };
1511
+ }
1512
+ }
1513
+ }
1514
+ };
1515
+
1516
+ // src/tools/search/LspTool/client/generic.ts
1517
+ import { createMessageConnection, StreamMessageReader, StreamMessageWriter } from "vscode-jsonrpc/node";
1518
+ import { spawn } from "child_process";
1519
+ import { pathToFileURL as pathToFileURL2 } from "url";
1520
+ var GenericLspClient = class {
1521
+ constructor(serverCommand, serverArgs, cwd, rootPath) {
1522
+ this.rootPath = rootPath;
1523
+ this.process = spawn(serverCommand, serverArgs, {
1524
+ cwd,
1525
+ stdio: "pipe",
1526
+ env: process.env
1527
+ });
1528
+ this.connection = createMessageConnection(
1529
+ new StreamMessageReader(this.process.stdout),
1530
+ new StreamMessageWriter(this.process.stdin)
1531
+ );
1532
+ this.connection.listen();
1533
+ }
1534
+ connection;
1535
+ process;
1536
+ async initialize() {
1537
+ const params = {
1538
+ processId: process.pid,
1539
+ rootUri: pathToFileURL2(this.rootPath).href,
1540
+ capabilities: {
1541
+ textDocument: {
1542
+ synchronization: {
1543
+ didOpen: true,
1544
+ didChange: true,
1545
+ willSave: false,
1546
+ willSaveWaitUntil: false,
1547
+ didSave: true
1548
+ },
1549
+ hover: {
1550
+ contentFormat: ["markdown", "plaintext"]
1551
+ },
1552
+ definition: {},
1553
+ references: {}
1554
+ },
1555
+ workspace: {
1556
+ workspaceFolders: true
1557
+ }
1558
+ },
1559
+ workspaceFolders: [
1560
+ {
1561
+ name: "workspace",
1562
+ uri: pathToFileURL2(this.rootPath).href
1563
+ }
1564
+ ]
1565
+ };
1566
+ const result = await this.connection.sendRequest("initialize", params);
1567
+ await this.connection.sendNotification("initialized", {});
1568
+ return result;
1569
+ }
1570
+ async shutdown() {
1571
+ try {
1572
+ await this.connection.sendRequest("shutdown");
1573
+ await this.connection.sendNotification("exit");
1574
+ } catch (error) {
1575
+ }
1576
+ this.connection.dispose();
1577
+ this.process.kill();
1578
+ }
1579
+ async goToDefinition(filePath, line, character) {
1580
+ const params = {
1581
+ textDocument: { uri: pathToFileURL2(filePath).href },
1582
+ position: { line: line - 1, character: character - 1 }
1583
+ };
1584
+ return this.connection.sendRequest("textDocument/definition", params);
1585
+ }
1586
+ async findReferences(filePath, line, character) {
1587
+ const params = {
1588
+ textDocument: { uri: pathToFileURL2(filePath).href },
1589
+ position: { line: line - 1, character: character - 1 },
1590
+ context: { includeDeclaration: true }
1591
+ };
1592
+ return this.connection.sendRequest("textDocument/references", params);
1593
+ }
1594
+ async hover(filePath, line, character) {
1595
+ const params = {
1596
+ textDocument: { uri: pathToFileURL2(filePath).href },
1597
+ position: { line: line - 1, character: character - 1 }
1598
+ };
1599
+ return this.connection.sendRequest("textDocument/hover", params);
1600
+ }
1601
+ async documentSymbol(filePath) {
1602
+ const params = {
1603
+ textDocument: { uri: pathToFileURL2(filePath).href }
1604
+ };
1605
+ return this.connection.sendRequest("textDocument/documentSymbol", params);
1606
+ }
1607
+ async workspaceSymbol(query2) {
1608
+ const params = {
1609
+ query: query2
1610
+ };
1611
+ return this.connection.sendRequest("workspace/symbol", params);
1612
+ }
1613
+ async goToImplementation(filePath, line, character) {
1614
+ const params = {
1615
+ textDocument: { uri: pathToFileURL2(filePath).href },
1616
+ position: { line: line - 1, character: character - 1 }
1617
+ };
1618
+ return this.connection.sendRequest("textDocument/implementation", params);
1619
+ }
1620
+ };
1621
+
1622
+ // src/tools/search/LspTool/client/manager.ts
1623
+ import { extname as extname2 } from "path";
1624
+
1625
+ // src/tools/search/LspTool/registry.ts
1626
+ import { join as join4 } from "path";
1627
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1628
+ import { spawnSync } from "child_process";
1629
+
1630
+ // src/tools/search/LspTool/utils.ts
1631
+ import { join as join3 } from "path";
1632
+ function getToolsDir() {
1633
+ return join3(getPybBaseDir(), "tools");
1634
+ }
1635
+ function getLspBinDir() {
1636
+ return join3(getToolsDir(), "bin");
1340
1637
  }
1638
+
1639
+ // src/tools/search/LspTool/registry.ts
1640
+ var BaseLspServer = class {
1641
+ isInPath(cmd) {
1642
+ try {
1643
+ const where = process.platform === "win32" ? "where" : "which";
1644
+ const result = spawnSync(where, [cmd], { encoding: "utf8" });
1645
+ return result.status === 0;
1646
+ } catch {
1647
+ return false;
1648
+ }
1649
+ }
1650
+ getLocalBinPath(binName) {
1651
+ const binDir = getLspBinDir();
1652
+ const ext = process.platform === "win32" ? ".cmd" : "";
1653
+ return join4(binDir, `${binName}${ext}`);
1654
+ }
1655
+ async installNpm(pkgName) {
1656
+ try {
1657
+ const binDir = getLspBinDir();
1658
+ if (!existsSync3(binDir)) {
1659
+ mkdirSync2(binDir, { recursive: true });
1660
+ }
1661
+ debug.info("LSP_INSTALL", { server: this.id, action: "start" });
1662
+ const toolsDir = join4(binDir, "..");
1663
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
1664
+ const result = spawnSync(npmCmd, ["install", pkgName, "--prefix", toolsDir], {
1665
+ encoding: "utf8",
1666
+ cwd: toolsDir
1667
+ });
1668
+ if (result.status !== 0) {
1669
+ debug.error("LSP_INSTALL_FAILED", { server: this.id, error: result.stderr });
1670
+ return false;
1671
+ }
1672
+ debug.info("LSP_INSTALL", { server: this.id, action: "success" });
1673
+ return true;
1674
+ } catch (e) {
1675
+ debug.error("LSP_INSTALL_ERROR", { server: this.id, error: String(e) });
1676
+ return false;
1677
+ }
1678
+ }
1679
+ };
1680
+ var GenericNpmServer = class extends BaseLspServer {
1681
+ id;
1682
+ extensions;
1683
+ rootMarkers;
1684
+ npmPackage;
1685
+ binName;
1686
+ args;
1687
+ constructor(id, extensions, rootMarkers, npmPackage, binName, args) {
1688
+ super();
1689
+ this.id = id;
1690
+ this.extensions = extensions;
1691
+ this.rootMarkers = rootMarkers;
1692
+ this.npmPackage = npmPackage;
1693
+ this.binName = binName;
1694
+ this.args = args;
1695
+ }
1696
+ async prepare() {
1697
+ if (this.isInPath(this.binName)) {
1698
+ return true;
1699
+ }
1700
+ const localBin = this.getLocalBinPath(this.binName);
1701
+ if (existsSync3(localBin)) {
1702
+ return true;
1703
+ }
1704
+ return this.installNpm(this.npmPackage);
1705
+ }
1706
+ async getCommand(rootPath) {
1707
+ if (this.isInPath(this.binName)) {
1708
+ return { command: this.binName, args: this.args };
1709
+ }
1710
+ const localBin = this.getLocalBinPath(this.binName);
1711
+ if (existsSync3(localBin)) {
1712
+ return { command: localBin, args: this.args };
1713
+ }
1714
+ return null;
1715
+ }
1716
+ };
1717
+ var GenericBinaryServer = class extends BaseLspServer {
1718
+ id;
1719
+ extensions;
1720
+ rootMarkers;
1721
+ binNames;
1722
+ args;
1723
+ constructor(id, extensions, rootMarkers, binNames, args) {
1724
+ super();
1725
+ this.id = id;
1726
+ this.extensions = extensions;
1727
+ this.rootMarkers = rootMarkers;
1728
+ this.binNames = Array.isArray(binNames) ? binNames : [binNames];
1729
+ this.args = args;
1730
+ }
1731
+ async prepare() {
1732
+ return this.binNames.some((bin) => this.isInPath(bin));
1733
+ }
1734
+ async getCommand(rootPath) {
1735
+ for (const bin of this.binNames) {
1736
+ if (this.isInPath(bin)) {
1737
+ return { command: bin, args: this.args };
1738
+ }
1739
+ }
1740
+ return null;
1741
+ }
1742
+ };
1743
+ var PyrightServer = class extends BaseLspServer {
1744
+ id = "pyright";
1745
+ extensions = [".py", ".pyi"];
1746
+ rootMarkers = ["pyrightconfig.json", "pyproject.toml", "setup.py", "requirements.txt", "Pipfile"];
1747
+ async prepare() {
1748
+ if (this.isInPath("pyright-langserver")) {
1749
+ return true;
1750
+ }
1751
+ const localBin = this.getLocalBinPath("pyright-langserver");
1752
+ if (existsSync3(localBin)) {
1753
+ return true;
1754
+ }
1755
+ return this.installNpm("pyright");
1756
+ }
1757
+ async getCommand(rootPath) {
1758
+ if (this.isInPath("pyright-langserver")) {
1759
+ return { command: "pyright-langserver", args: ["--stdio"] };
1760
+ }
1761
+ const localBin = this.getLocalBinPath("pyright-langserver");
1762
+ if (existsSync3(localBin)) {
1763
+ return { command: localBin, args: ["--stdio"] };
1764
+ }
1765
+ return null;
1766
+ }
1767
+ };
1768
+ var GoplsServer = class extends BaseLspServer {
1769
+ id = "gopls";
1770
+ extensions = [".go", ".mod"];
1771
+ rootMarkers = ["go.mod", "go.work", ".git"];
1772
+ async prepare() {
1773
+ if (this.isInPath("gopls")) {
1774
+ return true;
1775
+ }
1776
+ if (!this.isInPath("go")) {
1777
+ debug.error("LSP_MISSING_DEP", { server: this.id, error: "go command not found" });
1778
+ return false;
1779
+ }
1780
+ return this.installGo();
1781
+ }
1782
+ async getCommand(rootPath) {
1783
+ if (this.isInPath("gopls")) {
1784
+ return { command: "gopls", args: ["serve"] };
1785
+ }
1786
+ return null;
1787
+ }
1788
+ async installGo() {
1789
+ try {
1790
+ debug.info("LSP_INSTALL", { server: this.id, action: "start" });
1791
+ const result = spawnSync("go", ["install", "golang.org/x/tools/gopls@latest"], {
1792
+ encoding: "utf8"
1793
+ });
1794
+ if (result.status !== 0) {
1795
+ debug.error("LSP_INSTALL_FAILED", { server: this.id, error: result.stderr });
1796
+ return false;
1797
+ }
1798
+ if (!this.isInPath("gopls")) {
1799
+ debug.warn("LSP_INSTALL_WARNING", { server: this.id, message: "gopls installed but not found in PATH. Make sure $(go env GOPATH)/bin is in your PATH." });
1800
+ }
1801
+ debug.info("LSP_INSTALL", { server: this.id, action: "success" });
1802
+ return true;
1803
+ } catch (e) {
1804
+ debug.error("LSP_INSTALL_ERROR", { server: this.id, error: String(e) });
1805
+ return false;
1806
+ }
1807
+ }
1808
+ };
1809
+ var RustAnalyzerServer = class extends BaseLspServer {
1810
+ id = "rust-analyzer";
1811
+ extensions = [".rs"];
1812
+ rootMarkers = ["Cargo.toml", "rust-project.json", ".git"];
1813
+ async prepare() {
1814
+ if (this.isInPath("rust-analyzer")) {
1815
+ return true;
1816
+ }
1817
+ if (this.isInPath("rustup")) {
1818
+ return this.installRustup();
1819
+ }
1820
+ debug.warn("LSP_MISSING_DEP", { server: this.id, message: "rust-analyzer not found and rustup not available. Please install rust-analyzer manually." });
1821
+ return false;
1822
+ }
1823
+ async getCommand(rootPath) {
1824
+ if (this.isInPath("rust-analyzer")) {
1825
+ return { command: "rust-analyzer", args: [] };
1826
+ }
1827
+ return null;
1828
+ }
1829
+ async installRustup() {
1830
+ try {
1831
+ debug.info("LSP_INSTALL", { server: this.id, action: "start" });
1832
+ const result = spawnSync("rustup", ["component", "add", "rust-analyzer"], {
1833
+ encoding: "utf8"
1834
+ });
1835
+ if (result.status !== 0) {
1836
+ debug.error("LSP_INSTALL_FAILED", { server: this.id, error: result.stderr });
1837
+ return false;
1838
+ }
1839
+ debug.info("LSP_INSTALL", { server: this.id, action: "success" });
1840
+ return true;
1841
+ } catch (e) {
1842
+ debug.error("LSP_INSTALL_ERROR", { server: this.id, error: String(e) });
1843
+ return false;
1844
+ }
1845
+ }
1846
+ };
1847
+ var BashLanguageServer = class extends BaseLspServer {
1848
+ id = "bash-language-server";
1849
+ extensions = [".sh", ".bash", ".zsh"];
1850
+ rootMarkers = [".git"];
1851
+ async prepare() {
1852
+ if (this.isInPath("bash-language-server")) {
1853
+ return true;
1854
+ }
1855
+ const localBin = this.getLocalBinPath("bash-language-server");
1856
+ if (existsSync3(localBin)) {
1857
+ return true;
1858
+ }
1859
+ return this.installNpm("bash-language-server");
1860
+ }
1861
+ async getCommand(rootPath) {
1862
+ if (this.isInPath("bash-language-server")) {
1863
+ return { command: "bash-language-server", args: ["start"] };
1864
+ }
1865
+ const localBin = this.getLocalBinPath("bash-language-server");
1866
+ if (existsSync3(localBin)) {
1867
+ return { command: localBin, args: ["start"] };
1868
+ }
1869
+ return null;
1870
+ }
1871
+ };
1872
+ var LspServerRegistry = class _LspServerRegistry {
1873
+ static instance;
1874
+ servers = [];
1875
+ constructor() {
1876
+ this.register(new PyrightServer());
1877
+ this.register(new GoplsServer());
1878
+ this.register(new RustAnalyzerServer());
1879
+ this.register(new BashLanguageServer());
1880
+ this.register(new GenericNpmServer(
1881
+ "yaml-language-server",
1882
+ [".yaml", ".yml"],
1883
+ [],
1884
+ "yaml-language-server",
1885
+ "yaml-language-server",
1886
+ ["--stdio"]
1887
+ ));
1888
+ this.register(new GenericNpmServer(
1889
+ "dockerfile-language-server",
1890
+ ["Dockerfile", ".dockerfile"],
1891
+ [],
1892
+ "dockerfile-language-server-nodejs",
1893
+ "docker-langserver",
1894
+ ["--stdio"]
1895
+ ));
1896
+ this.register(new GenericNpmServer(
1897
+ "vue-language-server",
1898
+ [".vue"],
1899
+ ["package.json"],
1900
+ "@vue/language-server",
1901
+ "vue-language-server",
1902
+ ["--stdio"]
1903
+ ));
1904
+ this.register(new GenericNpmServer(
1905
+ "html-language-server",
1906
+ [".html", ".htm"],
1907
+ [],
1908
+ "vscode-langservers-extracted",
1909
+ "vscode-html-language-server",
1910
+ ["--stdio"]
1911
+ ));
1912
+ this.register(new GenericNpmServer(
1913
+ "css-language-server",
1914
+ [".css", ".scss", ".less"],
1915
+ [],
1916
+ "vscode-langservers-extracted",
1917
+ "vscode-css-language-server",
1918
+ ["--stdio"]
1919
+ ));
1920
+ this.register(new GenericNpmServer(
1921
+ "json-language-server",
1922
+ [".json", ".jsonc"],
1923
+ [],
1924
+ "vscode-langservers-extracted",
1925
+ "vscode-json-language-server",
1926
+ ["--stdio"]
1927
+ ));
1928
+ this.register(new GenericNpmServer(
1929
+ "intelephense",
1930
+ [".php"],
1931
+ ["composer.json"],
1932
+ "intelephense",
1933
+ "intelephense",
1934
+ ["--stdio"]
1935
+ ));
1936
+ this.register(new GenericNpmServer(
1937
+ "svelte-language-server",
1938
+ [".svelte"],
1939
+ ["package.json"],
1940
+ "svelte-language-server",
1941
+ "svelte-language-server",
1942
+ ["--stdio"]
1943
+ ));
1944
+ this.register(new GenericNpmServer(
1945
+ "astro-ls",
1946
+ [".astro"],
1947
+ ["package.json"],
1948
+ "@astrojs/language-server",
1949
+ "astro-ls",
1950
+ ["--stdio"]
1951
+ ));
1952
+ this.register(new GenericNpmServer(
1953
+ "prisma-language-server",
1954
+ [".prisma"],
1955
+ ["schema.prisma"],
1956
+ "@prisma/language-server",
1957
+ "prisma-language-server",
1958
+ ["--stdio"]
1959
+ ));
1960
+ this.register(new GenericNpmServer(
1961
+ "graphql-lsp",
1962
+ [".graphql", ".gql"],
1963
+ [".graphqlrc", "graphql.config.js"],
1964
+ "graphql-language-service-cli",
1965
+ "graphql-lsp",
1966
+ ["server", "-m", "stream"]
1967
+ ));
1968
+ this.register(new GenericBinaryServer(
1969
+ "jdtls",
1970
+ [".java"],
1971
+ ["pom.xml", "build.gradle"],
1972
+ "jdtls",
1973
+ []
1974
+ ));
1975
+ this.register(new GenericBinaryServer(
1976
+ "clangd",
1977
+ [".c", ".cpp", ".h", ".hpp", ".cc"],
1978
+ ["compile_commands.json", ".clang-format"],
1979
+ "clangd",
1980
+ ["--stdio"]
1981
+ ));
1982
+ this.register(new GenericBinaryServer(
1983
+ "ruby-lsp",
1984
+ [".rb", ".rake"],
1985
+ ["Gemfile", ".ruby-version"],
1986
+ "ruby-lsp",
1987
+ ["--stdio"]
1988
+ ));
1989
+ this.register(new GenericBinaryServer(
1990
+ "lua-language-server",
1991
+ [".lua"],
1992
+ [".luarc.json"],
1993
+ ["lua-ls", "lua-language-server"],
1994
+ []
1995
+ ));
1996
+ this.register(new GenericBinaryServer(
1997
+ "terraform-ls",
1998
+ [".tf", ".tfvars"],
1999
+ [],
2000
+ "terraform-ls",
2001
+ ["serve"]
2002
+ ));
2003
+ this.register(new GenericBinaryServer(
2004
+ "kotlin-language-server",
2005
+ [".kt", ".kts"],
2006
+ ["build.gradle.kts"],
2007
+ ["kotlin-ls", "kotlin-language-server"],
2008
+ []
2009
+ ));
2010
+ this.register(new GenericBinaryServer(
2011
+ "elixir-ls",
2012
+ [".ex", ".exs"],
2013
+ ["mix.exs"],
2014
+ ["elixir-ls", "language_server.sh"],
2015
+ []
2016
+ ));
2017
+ this.register(new GenericBinaryServer(
2018
+ "zls",
2019
+ [".zig"],
2020
+ ["build.zig"],
2021
+ "zls",
2022
+ []
2023
+ ));
2024
+ this.register(new GenericBinaryServer(
2025
+ "csharp-ls",
2026
+ [".cs"],
2027
+ [".csproj", ".sln"],
2028
+ "csharp-ls",
2029
+ []
2030
+ ));
2031
+ this.register(new GenericBinaryServer(
2032
+ "fsautocomplete",
2033
+ [".fs", ".fsi", ".fsx"],
2034
+ [".fsproj", ".sln"],
2035
+ "fsautocomplete",
2036
+ ["--background-service-enabled"]
2037
+ ));
2038
+ this.register(new GenericBinaryServer(
2039
+ "sourcekit-lsp",
2040
+ [".swift"],
2041
+ ["Package.swift"],
2042
+ "sourcekit-lsp",
2043
+ []
2044
+ ));
2045
+ this.register(new GenericBinaryServer(
2046
+ "dart",
2047
+ [".dart"],
2048
+ ["pubspec.yaml"],
2049
+ "dart",
2050
+ ["language-server"]
2051
+ ));
2052
+ this.register(new GenericBinaryServer(
2053
+ "ocamllsp",
2054
+ [".ml", ".mli"],
2055
+ ["dune-project"],
2056
+ ["ocaml-lsp", "ocamllsp"],
2057
+ []
2058
+ ));
2059
+ this.register(new GenericBinaryServer(
2060
+ "gleam",
2061
+ [".gleam"],
2062
+ ["gleam.toml"],
2063
+ "gleam",
2064
+ ["lsp"]
2065
+ ));
2066
+ this.register(new GenericBinaryServer(
2067
+ "clojure-lsp",
2068
+ [".clj", ".cljs", ".cljc", ".edn"],
2069
+ ["deps.edn", "project.clj"],
2070
+ "clojure-lsp",
2071
+ []
2072
+ ));
2073
+ this.register(new GenericBinaryServer(
2074
+ "nixd",
2075
+ [".nix"],
2076
+ ["flake.nix"],
2077
+ "nixd",
2078
+ []
2079
+ ));
2080
+ this.register(new GenericBinaryServer(
2081
+ "tinymist",
2082
+ [".typ"],
2083
+ [],
2084
+ "tinymist",
2085
+ []
2086
+ ));
2087
+ this.register(new GenericBinaryServer(
2088
+ "haskell-language-server",
2089
+ [".hs", ".lhs"],
2090
+ ["stack.yaml", "cabal.project", "*.cabal"],
2091
+ "haskell-language-server-wrapper",
2092
+ ["--lsp"]
2093
+ ));
2094
+ this.register(new GenericBinaryServer(
2095
+ "texlab",
2096
+ [".tex", ".bib"],
2097
+ [],
2098
+ "texlab",
2099
+ []
2100
+ ));
2101
+ }
2102
+ static getInstance() {
2103
+ if (!_LspServerRegistry.instance) {
2104
+ _LspServerRegistry.instance = new _LspServerRegistry();
2105
+ }
2106
+ return _LspServerRegistry.instance;
2107
+ }
2108
+ register(server) {
2109
+ this.servers.push(server);
2110
+ }
2111
+ getServerForExtension(ext) {
2112
+ return this.servers.find((s) => s.extensions.includes(ext)) || null;
2113
+ }
2114
+ };
2115
+
2116
+ // src/tools/search/LspTool/client/manager.ts
2117
+ var LspClientManager = class _LspClientManager {
2118
+ static instance;
2119
+ clients = /* @__PURE__ */ new Map();
2120
+ constructor() {
2121
+ }
2122
+ static getInstance() {
2123
+ if (!_LspClientManager.instance) {
2124
+ _LspClientManager.instance = new _LspClientManager();
2125
+ }
2126
+ return _LspClientManager.instance;
2127
+ }
2128
+ async getClient(filePath, rootPath) {
2129
+ const ext = extname2(filePath);
2130
+ const serverInfo = LspServerRegistry.getInstance().getServerForExtension(ext);
2131
+ if (!serverInfo) {
2132
+ return null;
2133
+ }
2134
+ try {
2135
+ const ready = await serverInfo.prepare();
2136
+ if (!ready) {
2137
+ return null;
2138
+ }
2139
+ } catch (e) {
2140
+ return null;
2141
+ }
2142
+ const cmd = await serverInfo.getCommand(rootPath);
2143
+ if (!cmd) {
2144
+ return null;
2145
+ }
2146
+ const key = `${rootPath}:${serverInfo.id}`;
2147
+ let client = this.clients.get(key);
2148
+ if (!client) {
2149
+ client = new GenericLspClient(cmd.command, cmd.args, rootPath, rootPath);
2150
+ try {
2151
+ await client.initialize();
2152
+ this.clients.set(key, client);
2153
+ } catch (error) {
2154
+ return null;
2155
+ }
2156
+ }
2157
+ return client;
2158
+ }
2159
+ async shutdownAll() {
2160
+ for (const client of this.clients.values()) {
2161
+ await client.shutdown();
2162
+ }
2163
+ this.clients.clear();
2164
+ }
2165
+ };
2166
+
2167
+ // src/tools/search/LspTool/client/formatters.ts
2168
+ import { fileURLToPath } from "url";
2169
+ import { relative as relative2 } from "path";
2170
+ function toProjectRelative(filePath) {
2171
+ const cwd = getCwd();
2172
+ try {
2173
+ const rel = relative2(cwd, filePath);
2174
+ if (!rel || rel === "") return filePath;
2175
+ if (rel.startsWith("..")) return filePath;
2176
+ return rel;
2177
+ } catch {
2178
+ return filePath;
2179
+ }
2180
+ }
2181
+ function formatLocation2(uri, range) {
2182
+ const filePath = fileURLToPath(uri);
2183
+ return `${toProjectRelative(filePath)}:${range.start.line + 1}:${range.start.character + 1}`;
2184
+ }
2185
+ function formatGenericDefinitionResult(result) {
2186
+ if (!result) {
2187
+ return { formatted: "No definition found.", resultCount: 0, fileCount: 0 };
2188
+ }
2189
+ const locations = Array.isArray(result) ? result : [result];
2190
+ if (locations.length === 0) {
2191
+ return { formatted: "No definition found.", resultCount: 0, fileCount: 0 };
2192
+ }
2193
+ const fileCount = new Set(locations.map((l) => l.uri)).size;
2194
+ if (locations.length === 1) {
2195
+ return {
2196
+ formatted: `Defined in ${formatLocation2(locations[0].uri, locations[0].range)}`,
2197
+ resultCount: 1,
2198
+ fileCount
2199
+ };
2200
+ }
2201
+ return {
2202
+ formatted: `Found ${locations.length} definitions:
2203
+ ${locations.map((l) => ` ${formatLocation2(l.uri, l.range)}`).join("\n")}`,
2204
+ resultCount: locations.length,
2205
+ fileCount
2206
+ };
2207
+ }
2208
+ function formatGenericReferencesResult(result) {
2209
+ if (!result || !Array.isArray(result) || result.length === 0) {
2210
+ return { formatted: "No references found.", resultCount: 0, fileCount: 0 };
2211
+ }
2212
+ const grouped = /* @__PURE__ */ new Map();
2213
+ for (const ref of result) {
2214
+ const file = toProjectRelative(fileURLToPath(ref.uri));
2215
+ if (!grouped.has(file)) grouped.set(file, []);
2216
+ grouped.get(file).push(ref);
2217
+ }
2218
+ const lines = [`Found ${result.length} references across ${grouped.size} files:`];
2219
+ for (const [file, refs] of grouped) {
2220
+ lines.push(`
2221
+ ${file}:`);
2222
+ for (const ref of refs) {
2223
+ lines.push(` Line ${ref.range.start.line + 1}:${ref.range.start.character + 1}`);
2224
+ }
2225
+ }
2226
+ return {
2227
+ formatted: lines.join("\n"),
2228
+ resultCount: result.length,
2229
+ fileCount: grouped.size
2230
+ };
2231
+ }
2232
+ function formatGenericHoverResult(result, line, character) {
2233
+ if (!result || !result.contents) {
2234
+ return { formatted: "No hover info.", resultCount: 0, fileCount: 0 };
2235
+ }
2236
+ let contents = "";
2237
+ if (typeof result.contents === "string") {
2238
+ contents = result.contents;
2239
+ } else if (Array.isArray(result.contents)) {
2240
+ contents = result.contents.map((c) => typeof c === "string" ? c : c.value).join("\n");
2241
+ } else {
2242
+ contents = result.contents.value;
2243
+ }
2244
+ return {
2245
+ formatted: `Hover info at ${line}:${character}:
2246
+
2247
+ ${contents}`,
2248
+ resultCount: 1,
2249
+ fileCount: 1
2250
+ };
2251
+ }
2252
+ function formatGenericDocumentSymbolResult(result) {
2253
+ if (!result || !Array.isArray(result) || result.length === 0) {
2254
+ return { formatted: "No symbols found.", resultCount: 0, fileCount: 0 };
2255
+ }
2256
+ const lines = result.map((s) => {
2257
+ const kind = s.kind;
2258
+ return `${s.name} (${kind}) at ${s.range.start.line + 1}:${s.range.start.character + 1}`;
2259
+ });
2260
+ return {
2261
+ formatted: ["Document symbols:", ...lines].join("\n"),
2262
+ resultCount: result.length,
2263
+ fileCount: 1
2264
+ };
2265
+ }
2266
+
2267
+ // src/tools/search/LspTool/LspTool.tsx
2268
+ var inputSchema4 = z4.strictObject({
2269
+ operation: z4.enum([
2270
+ "goToDefinition",
2271
+ "findReferences",
2272
+ "hover",
2273
+ "documentSymbol",
2274
+ "workspaceSymbol",
2275
+ "goToImplementation",
2276
+ "prepareCallHierarchy",
2277
+ "incomingCalls",
2278
+ "outgoingCalls"
2279
+ ]).describe("The LSP operation to perform"),
2280
+ filePath: z4.string().describe("The absolute or relative path to the file"),
2281
+ line: z4.number().int().positive().describe("The line number (1-based, as shown in editors)"),
2282
+ character: z4.number().int().positive().describe("The character offset (1-based, as shown in editors)")
2283
+ });
2284
+ var outputSchema = z4.object({
2285
+ operation: z4.enum([
2286
+ "goToDefinition",
2287
+ "findReferences",
2288
+ "hover",
2289
+ "documentSymbol",
2290
+ "workspaceSymbol",
2291
+ "goToImplementation",
2292
+ "prepareCallHierarchy",
2293
+ "incomingCalls",
2294
+ "outgoingCalls"
2295
+ ]).describe("The LSP operation that was performed"),
2296
+ result: z4.string().describe("The formatted result of the LSP operation"),
2297
+ filePath: z4.string().describe("The file path the operation was performed on"),
2298
+ resultCount: z4.number().int().nonnegative().optional().describe("Number of results (definitions, references, symbols)"),
2299
+ fileCount: z4.number().int().nonnegative().optional().describe("Number of files containing results")
2300
+ });
2301
+ var OPERATION_LABELS = {
2302
+ goToDefinition: { singular: "definition", plural: "definitions" },
2303
+ findReferences: { singular: "reference", plural: "references" },
2304
+ documentSymbol: { singular: "symbol", plural: "symbols" },
2305
+ workspaceSymbol: { singular: "symbol", plural: "symbols" },
2306
+ hover: { singular: "hover info", plural: "hover info", special: "available" },
2307
+ goToImplementation: { singular: "implementation", plural: "implementations" },
2308
+ prepareCallHierarchy: { singular: "call item", plural: "call items" },
2309
+ incomingCalls: { singular: "caller", plural: "callers" },
2310
+ outgoingCalls: { singular: "callee", plural: "callees" }
2311
+ };
1341
2312
  function summarizeToolResult(operation, resultCount, fileCount) {
1342
2313
  const label = OPERATION_LABELS[operation] ?? {
1343
2314
  singular: "result",
@@ -1362,7 +2333,7 @@ var LspTool = {
1362
2333
  return "LSP";
1363
2334
  },
1364
2335
  async isEnabled() {
1365
- return tryLoadTypeScriptModule(getCwd()) !== null;
2336
+ return true;
1366
2337
  },
1367
2338
  isReadOnly() {
1368
2339
  return true;
@@ -1384,7 +2355,7 @@ var LspTool = {
1384
2355
  };
1385
2356
  }
1386
2357
  const absPath = getAbsolutePath(input.filePath) ?? input.filePath;
1387
- if (!existsSync2(absPath)) {
2358
+ if (!existsSync4(absPath)) {
1388
2359
  return {
1389
2360
  result: false,
1390
2361
  message: `File does not exist: ${input.filePath}`,
@@ -1392,7 +2363,7 @@ var LspTool = {
1392
2363
  };
1393
2364
  }
1394
2365
  try {
1395
- if (!statSync(absPath).isFile()) {
2366
+ if (!statSync2(absPath).isFile()) {
1396
2367
  return {
1397
2368
  result: false,
1398
2369
  message: `Path is not a file: ${input.filePath}`,
@@ -1411,12 +2382,12 @@ var LspTool = {
1411
2382
  },
1412
2383
  renderToolUseMessage(input, { verbose }) {
1413
2384
  const abs = getAbsolutePath(input.filePath) ?? input.filePath;
1414
- const filePathForDisplay = verbose ? abs : toProjectRelativeIfPossible(abs);
2385
+ const filePathForDisplay = verbose ? abs : TypeScriptBackend.toProjectRelativeIfPossible(abs);
1415
2386
  const parts = [];
1416
2387
  if ((input.operation === "goToDefinition" || input.operation === "findReferences" || input.operation === "hover" || input.operation === "goToImplementation") && input.filePath && input.line !== void 0 && input.character !== void 0) {
1417
2388
  try {
1418
- const content = readFileSync2(abs, "utf8");
1419
- const symbol = extractSymbolAtPosition(
2389
+ const content = readFileSync3(abs, "utf8");
2390
+ const symbol = TypeScriptBackend.extractSymbolAtPosition(
1420
2391
  content.split("\n"),
1421
2392
  input.line - 1,
1422
2393
  input.character - 1
@@ -1460,282 +2431,96 @@ var LspTool = {
1460
2431
  },
1461
2432
  async *call(input, _context) {
1462
2433
  const absPath = getAbsolutePath(input.filePath) ?? input.filePath;
1463
- if (!isFileTypeSupportedByTypescriptBackend(absPath)) {
1464
- const ext = extname(absPath);
1465
- const out = {
1466
- operation: input.operation,
1467
- result: `No LSP server available for file type: ${ext}`,
1468
- filePath: input.filePath,
1469
- resultCount: 0,
1470
- fileCount: 0
1471
- };
1472
- yield { type: "result", data: out, resultForAssistant: out.result };
1473
- return;
1474
- }
1475
- const project = getOrCreateTsProject(getCwd());
1476
- if (!project) {
1477
- const out = {
1478
- operation: input.operation,
1479
- result: "LSP server manager not initialized. This may indicate a startup issue.",
1480
- filePath: input.filePath,
1481
- resultCount: 0,
1482
- fileCount: 0
1483
- };
1484
- yield { type: "result", data: out, resultForAssistant: out.result };
1485
- return;
1486
- }
1487
- project.rootFiles.add(absPath);
1488
- const ts = project.ts;
1489
- const service = project.languageService;
1490
- const program = service.getProgram?.();
1491
- if (!program) {
1492
- const out = {
1493
- operation: input.operation,
1494
- result: `Error performing ${input.operation}: TypeScript program not available`,
1495
- filePath: input.filePath,
1496
- resultCount: 0,
1497
- fileCount: 0
1498
- };
1499
- yield { type: "result", data: out, resultForAssistant: out.result };
1500
- return;
1501
- }
1502
- const sourceFile = program.getSourceFile(absPath);
1503
- if (!sourceFile) {
1504
- const out = {
1505
- operation: input.operation,
1506
- result: `Error performing ${input.operation}: File is not part of the TypeScript program`,
1507
- filePath: input.filePath,
1508
- resultCount: 0,
1509
- fileCount: 0
1510
- };
1511
- yield { type: "result", data: out, resultForAssistant: out.result };
1512
- return;
1513
- }
1514
- const pos = ts.getPositionOfLineAndCharacter(
1515
- sourceFile,
1516
- input.line - 1,
1517
- input.character - 1
1518
- );
1519
- try {
1520
- let formatted;
1521
- let resultCount = 0;
1522
- let fileCount = 0;
1523
- switch (input.operation) {
1524
- case "goToDefinition": {
1525
- const defs = service.getDefinitionAtPosition?.(absPath, pos) ?? [];
1526
- const locations = defs.map((d) => {
1527
- const defSourceFile = program.getSourceFile(d.fileName);
1528
- if (!defSourceFile) return null;
1529
- const lc = ts.getLineAndCharacterOfPosition(
1530
- defSourceFile,
1531
- d.textSpan.start
1532
- );
1533
- return {
1534
- fileName: d.fileName,
1535
- line0: lc.line,
1536
- character0: lc.character
1537
- };
1538
- }).filter(Boolean);
1539
- const res = formatGoToDefinitionResult(locations);
1540
- formatted = res.formatted;
1541
- resultCount = res.resultCount;
1542
- fileCount = res.fileCount;
1543
- break;
1544
- }
1545
- case "goToImplementation": {
1546
- const impls = service.getImplementationAtPosition?.(absPath, pos) ?? [];
1547
- const locations = impls.map((d) => {
1548
- const defSourceFile = program.getSourceFile(d.fileName);
1549
- if (!defSourceFile) return null;
1550
- const lc = ts.getLineAndCharacterOfPosition(
1551
- defSourceFile,
1552
- d.textSpan.start
1553
- );
1554
- return {
1555
- fileName: d.fileName,
1556
- line0: lc.line,
1557
- character0: lc.character
1558
- };
1559
- }).filter(Boolean);
1560
- const res = formatGoToDefinitionResult(locations);
1561
- formatted = res.formatted;
1562
- resultCount = res.resultCount;
1563
- fileCount = res.fileCount;
1564
- break;
1565
- }
1566
- case "findReferences": {
1567
- const referencedSymbols = service.findReferences?.(absPath, pos) ?? [];
1568
- const refs = [];
1569
- for (const sym of referencedSymbols) {
1570
- for (const ref of sym.references ?? []) {
1571
- const refSource = program.getSourceFile(ref.fileName);
1572
- if (!refSource) continue;
1573
- const lc = ts.getLineAndCharacterOfPosition(
1574
- refSource,
1575
- ref.textSpan.start
1576
- );
1577
- refs.push({
1578
- fileName: ref.fileName,
1579
- line0: lc.line,
1580
- character0: lc.character
1581
- });
1582
- }
1583
- }
1584
- const res = formatFindReferencesResult(refs);
1585
- formatted = res.formatted;
1586
- resultCount = res.resultCount;
1587
- fileCount = res.fileCount;
1588
- break;
1589
- }
1590
- case "hover": {
1591
- const info = service.getQuickInfoAtPosition?.(absPath, pos);
1592
- let text = null;
1593
- let hoverLine0 = input.line - 1;
1594
- let hoverCharacter0 = input.character - 1;
1595
- if (info) {
1596
- const parts = [];
1597
- const signature = ts.displayPartsToString(info.displayParts ?? []);
1598
- if (signature) parts.push(signature);
1599
- const doc = ts.displayPartsToString(info.documentation ?? []);
1600
- if (doc) parts.push(doc);
1601
- if (info.tags && info.tags.length > 0) {
1602
- for (const tag of info.tags) {
1603
- const tagText = ts.displayPartsToString(tag.text ?? []);
1604
- parts.push(`@${tag.name}${tagText ? ` ${tagText}` : ""}`);
1605
- }
1606
- }
1607
- text = parts.filter(Boolean).join("\n\n");
1608
- const lc = ts.getLineAndCharacterOfPosition(
1609
- sourceFile,
1610
- info.textSpan.start
1611
- );
1612
- hoverLine0 = lc.line;
1613
- hoverCharacter0 = lc.character;
1614
- }
1615
- const res = formatHoverResult(text, hoverLine0, hoverCharacter0);
1616
- formatted = res.formatted;
1617
- resultCount = res.resultCount;
1618
- fileCount = res.fileCount;
1619
- break;
1620
- }
1621
- case "documentSymbol": {
1622
- const tree = service.getNavigationTree?.(absPath);
1623
- const lines = [];
1624
- let count = 0;
1625
- const kindLabel = (kind) => {
1626
- const m = {
1627
- class: "Class",
1628
- interface: "Interface",
1629
- enum: "Enum",
1630
- function: "Function",
1631
- method: "Method",
1632
- property: "Property",
1633
- var: "Variable",
1634
- let: "Variable",
1635
- const: "Constant",
1636
- module: "Module",
1637
- alias: "Alias",
1638
- type: "Type"
1639
- };
1640
- return m[kind] ?? (kind ? kind[0].toUpperCase() + kind.slice(1) : "Unknown");
1641
- };
1642
- const walk = (node, depth) => {
1643
- const children = node?.childItems ?? [];
1644
- for (const child of children) {
1645
- const span = child.spans?.[0];
1646
- if (!span) continue;
1647
- const lc = ts.getLineAndCharacterOfPosition(
1648
- sourceFile,
1649
- span.start
1650
- );
1651
- const indent = " ".repeat(depth);
1652
- const label = kindLabel(child.kind);
1653
- const detail = child.kindModifiers ? ` ${child.kindModifiers}` : "";
1654
- lines.push(
1655
- `${indent}${child.text} (${label})${detail} - Line ${lc.line + 1}`
1656
- );
1657
- count += 1;
1658
- if (child.childItems && child.childItems.length > 0) {
1659
- walk(child, depth + 1);
1660
- }
1661
- }
1662
- };
1663
- walk(tree, 0);
1664
- const res = formatDocumentSymbolsResult(lines, count);
1665
- formatted = res.formatted;
1666
- resultCount = res.resultCount;
1667
- fileCount = res.fileCount;
1668
- break;
1669
- }
1670
- case "workspaceSymbol": {
1671
- const items = service.getNavigateToItems?.("", 100, void 0, true, true) ?? [];
1672
- if (!items || items.length === 0) {
1673
- formatted = "No symbols found in workspace. This may occur if the workspace is empty, or if the LSP server has not finished indexing the project.";
1674
- resultCount = 0;
1675
- fileCount = 0;
2434
+ const client = await LspClientManager.getInstance().getClient(absPath, getCwd());
2435
+ if (client) {
2436
+ try {
2437
+ let result;
2438
+ let formattedResult;
2439
+ switch (input.operation) {
2440
+ case "goToDefinition":
2441
+ result = await client.goToDefinition(absPath, input.line, input.character);
2442
+ formattedResult = formatGenericDefinitionResult(result);
1676
2443
  break;
1677
- }
1678
- const lines = [
1679
- `Found ${items.length} symbol${items.length === 1 ? "" : "s"} in workspace:`
1680
- ];
1681
- const grouped = groupLocationsByFile(
1682
- items.map((it) => ({
1683
- fileName: it.fileName,
1684
- item: it
1685
- }))
1686
- );
1687
- for (const [file, itemsInFile] of grouped) {
1688
- lines.push(`
1689
- ${file}:`);
1690
- for (const wrapper of itemsInFile) {
1691
- const it = wrapper.item;
1692
- const sf = program.getSourceFile(it.fileName);
1693
- if (!sf) continue;
1694
- const span = it.textSpan;
1695
- const lc = span ? ts.getLineAndCharacterOfPosition(sf, span.start) : { line: 0, character: 0 };
1696
- const label = it.kind ? String(it.kind)[0].toUpperCase() + String(it.kind).slice(1) : "Symbol";
1697
- let line = ` ${it.name} (${label}) - Line ${lc.line + 1}`;
1698
- if (it.containerName) line += ` in ${it.containerName}`;
1699
- lines.push(line);
1700
- }
1701
- }
1702
- formatted = lines.join("\n");
1703
- resultCount = items.length;
1704
- fileCount = grouped.size;
1705
- break;
1706
- }
1707
- case "prepareCallHierarchy":
1708
- case "incomingCalls":
1709
- case "outgoingCalls": {
1710
- const opLabel = input.operation;
1711
- formatted = `Error performing ${opLabel}: Call hierarchy is not supported by the TypeScript backend`;
1712
- resultCount = 0;
1713
- fileCount = 0;
1714
- break;
1715
- }
1716
- default: {
1717
- formatted = `Error performing ${input.operation}: Unsupported operation`;
1718
- resultCount = 0;
1719
- fileCount = 0;
2444
+ case "findReferences":
2445
+ result = await client.findReferences(absPath, input.line, input.character);
2446
+ formattedResult = formatGenericReferencesResult(result);
2447
+ break;
2448
+ case "hover":
2449
+ result = await client.hover(absPath, input.line, input.character);
2450
+ formattedResult = formatGenericHoverResult(result, input.line, input.character);
2451
+ break;
2452
+ case "documentSymbol":
2453
+ result = await client.documentSymbol(absPath);
2454
+ formattedResult = formatGenericDocumentSymbolResult(result);
2455
+ break;
2456
+ case "goToImplementation":
2457
+ result = await client.goToImplementation(absPath, input.line, input.character);
2458
+ formattedResult = formatGenericDefinitionResult(result);
2459
+ break;
2460
+ default:
2461
+ formattedResult = { formatted: `Operation ${input.operation} not supported by generic client yet.`, resultCount: 0, fileCount: 0 };
1720
2462
  }
2463
+ const out2 = {
2464
+ operation: input.operation,
2465
+ result: formattedResult.formatted,
2466
+ filePath: input.filePath,
2467
+ resultCount: formattedResult.resultCount,
2468
+ fileCount: formattedResult.fileCount
2469
+ };
2470
+ yield { type: "result", data: out2, resultForAssistant: out2.result };
2471
+ return;
2472
+ } catch (err) {
2473
+ const message = err instanceof Error ? err.message : String(err);
2474
+ const out2 = {
2475
+ operation: input.operation,
2476
+ result: `Error performing ${input.operation} with generic client: ${message}`,
2477
+ filePath: input.filePath,
2478
+ resultCount: 0,
2479
+ fileCount: 0
2480
+ };
2481
+ yield { type: "result", data: out2, resultForAssistant: out2.result };
2482
+ return;
1721
2483
  }
1722
- const out = {
1723
- operation: input.operation,
1724
- result: formatted,
1725
- filePath: input.filePath,
1726
- resultCount,
1727
- fileCount
1728
- };
1729
- yield { type: "result", data: out, resultForAssistant: out.result };
1730
- } catch (err) {
1731
- const message = err instanceof Error ? err.message : String(err);
1732
- const out = {
1733
- operation: input.operation,
1734
- result: `Error performing ${input.operation}: ${message}`,
1735
- filePath: input.filePath
1736
- };
1737
- yield { type: "result", data: out, resultForAssistant: out.result };
1738
2484
  }
2485
+ if (TypeScriptBackend.isFileTypeSupported(absPath)) {
2486
+ try {
2487
+ const result = TypeScriptBackend.runOperation(
2488
+ input.operation,
2489
+ absPath,
2490
+ input.line,
2491
+ input.character
2492
+ );
2493
+ const out2 = {
2494
+ operation: input.operation,
2495
+ result: result.formatted,
2496
+ filePath: input.filePath,
2497
+ resultCount: result.resultCount,
2498
+ fileCount: result.fileCount
2499
+ };
2500
+ yield { type: "result", data: out2, resultForAssistant: out2.result };
2501
+ return;
2502
+ } catch (err) {
2503
+ const message = err instanceof Error ? err.message : String(err);
2504
+ const out2 = {
2505
+ operation: input.operation,
2506
+ result: `Error performing ${input.operation}: ${message}`,
2507
+ filePath: input.filePath,
2508
+ resultCount: 0,
2509
+ fileCount: 0
2510
+ };
2511
+ yield { type: "result", data: out2, resultForAssistant: out2.result };
2512
+ return;
2513
+ }
2514
+ }
2515
+ const ext = extname3(absPath);
2516
+ const out = {
2517
+ operation: input.operation,
2518
+ result: `No LSP server available for file type: ${ext}`,
2519
+ filePath: input.filePath,
2520
+ resultCount: 0,
2521
+ fileCount: 0
2522
+ };
2523
+ yield { type: "result", data: out, resultForAssistant: out.result };
1739
2524
  }
1740
2525
  };
1741
2526
 
@@ -1876,7 +2661,7 @@ import React6 from "react";
1876
2661
  import { Box as Box6, Text as Text6 } from "ink";
1877
2662
  import { z as z6 } from "zod";
1878
2663
  import { randomUUID as randomUUID2 } from "crypto";
1879
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
2664
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
1880
2665
 
1881
2666
  // src/utils/agent/transcripts.ts
1882
2667
  var transcripts = /* @__PURE__ */ new Map();
@@ -2050,9 +2835,9 @@ function applyAgentPermissionMode(base, options) {
2050
2835
  return { ...base, mode: options.agentPermissionMode };
2051
2836
  }
2052
2837
  function readJsonArrayFile(path) {
2053
- if (!existsSync3(path)) return null;
2838
+ if (!existsSync5(path)) return null;
2054
2839
  try {
2055
- const raw = readFileSync3(path, "utf8");
2840
+ const raw = readFileSync4(path, "utf8");
2056
2841
  const parsed = JSON.parse(raw);
2057
2842
  return Array.isArray(parsed) ? parsed : null;
2058
2843
  } catch {