pybao-cli 1.3.21 → 1.3.24

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