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.
- package/dist/REPL-75KL6GAB.js +42 -0
- package/dist/{acp-5COUMMLN.js → acp-HQIMVQVE.js} +26 -26
- package/dist/{agentsValidate-DKGJ5OX4.js → agentsValidate-HP2QZOGZ.js} +7 -7
- package/dist/{ask-QW644CAZ.js → ask-3WO2HDRK.js} +25 -25
- package/dist/{autoUpdater-WUTZGWEM.js → autoUpdater-WBADQJDS.js} +3 -3
- package/dist/{chunk-UDXJD3B5.js → chunk-2JFF2W36.js} +18 -6
- package/dist/chunk-2JFF2W36.js.map +7 -0
- package/dist/{chunk-PJ2UYD4Q.js → chunk-4AWVNHCM.js} +2 -2
- package/dist/{chunk-WU4SXVFN.js → chunk-56EE3NJ2.js} +1182 -345
- package/dist/chunk-56EE3NJ2.js.map +7 -0
- package/dist/{chunk-4FSJIGYW.js → chunk-6MUYPW7Q.js} +2 -2
- package/dist/{chunk-6IQ6RNSC.js → chunk-AGMS7BAU.js} +2 -2
- package/dist/{chunk-Q27MKRQ5.js → chunk-AIJXHCQJ.js} +4 -4
- package/dist/{chunk-RSCGHYX4.js → chunk-C5IUVXAK.js} +3 -3
- package/dist/{chunk-Q74XWGWS.js → chunk-D2OUHFOX.js} +1 -1
- package/dist/{chunk-PWZPQLA5.js → chunk-DGQOYCQ4.js} +3 -3
- package/dist/{chunk-HJPCQROC.js → chunk-F5NR7QE5.js} +1 -1
- package/dist/{chunk-LCN6UMC2.js → chunk-FHCT4F4H.js} +1 -1
- package/dist/{chunk-IA565ACR.js → chunk-MBYDWUYD.js} +3 -3
- package/dist/{chunk-X2LHX4TN.js → chunk-MNSPB7QF.js} +1 -1
- package/dist/{chunk-YEDGG2CM.js → chunk-MVTPSMKC.js} +6 -12
- package/dist/chunk-MVTPSMKC.js.map +7 -0
- package/dist/{chunk-PF3A6LJD.js → chunk-O2HPDW7E.js} +1 -1
- package/dist/{chunk-LTUBDTY7.js → chunk-O6EAVDYJ.js} +1 -1
- package/dist/{chunk-KAAPCK6R.js → chunk-OS3PRGER.js} +4 -4
- package/dist/{chunk-ILKTL4HO.js → chunk-PN453X6K.js} +2 -2
- package/dist/{chunk-VXPAJIEJ.js → chunk-PWGVKIQ7.js} +3 -3
- package/dist/{chunk-LFT6GMDJ.js → chunk-RAFAX7UH.js} +3 -3
- package/dist/{chunk-DTOUFBLG.js → chunk-SN6CKFJP.js} +3 -3
- package/dist/{chunk-KANFF7SM.js → chunk-TPTCH44R.js} +1 -1
- package/dist/{chunk-YVLQDPDN.js → chunk-UC5GVD7H.js} +2 -2
- package/dist/{chunk-3NZTTP2W.js → chunk-V5WZJEVQ.js} +34 -33
- package/dist/chunk-V5WZJEVQ.js.map +7 -0
- package/dist/{chunk-TBU6CIW7.js → chunk-X2JUNUGX.js} +1 -1
- package/dist/{chunk-ZQLAZEQ6.js → chunk-Z3FCTWM5.js} +1 -1
- package/dist/{chunk-Z7P6CYVJ.js → chunk-ZMEZLZSY.js} +2 -2
- package/dist/{cli-5AQQAMDZ.js → cli-ABH2I5QQ.js} +77 -77
- package/dist/commands-ZZDHT2TO.js +46 -0
- package/dist/{config-XUTCS32D.js → config-YZ5SH7PT.js} +4 -4
- package/dist/{context-BJBOG5ML.js → context-UX3EZ3PA.js} +5 -5
- package/dist/{customCommands-FCGJVPMM.js → customCommands-NTZP2HM3.js} +4 -4
- package/dist/{env-PCEHNXQ7.js → env-PV2KGERM.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{llm-YXYHYLLL.js → llm-OTAQ7LEG.js} +26 -26
- package/dist/{llmLazy-BWNMELGK.js → llmLazy-NBVRO2UR.js} +1 -1
- package/dist/{loader-UXDARCPS.js → loader-F3GV54J2.js} +4 -4
- package/dist/{mcp-OD4RSPAA.js → mcp-Q7OQHMV7.js} +7 -7
- package/dist/{mentionProcessor-MRLHJCG7.js → mentionProcessor-GLCUGCM3.js} +5 -5
- package/dist/{messages-WDA7YIIR.js → messages-ISLBFDID.js} +1 -1
- package/dist/{model-E7A4ZTH3.js → model-OV6AVHYX.js} +5 -5
- package/dist/{openai-6VE4E33T.js → openai-IFK7QCX7.js} +5 -5
- package/dist/{outputStyles-ALNI7DMM.js → outputStyles-2NMFE3TD.js} +4 -4
- package/dist/{pluginRuntime-ZJM5CYBI.js → pluginRuntime-RYXZP2NG.js} +6 -6
- package/dist/{pluginValidation-P7F37TRM.js → pluginValidation-HOAJE2IY.js} +6 -6
- package/dist/prompts-NHLWAHOF.js +48 -0
- package/dist/{pybAgentSessionLoad-DXA2GXAD.js → pybAgentSessionLoad-AI3GJDZB.js} +4 -4
- package/dist/{pybAgentSessionResume-GSTPB6PZ.js → pybAgentSessionResume-NY5H4GWY.js} +4 -4
- package/dist/{pybAgentStreamJsonSession-NJYZ5ZC5.js → pybAgentStreamJsonSession-YU2I7WZY.js} +1 -1
- package/dist/{pybHooks-G4QW3QWC.js → pybHooks-UOLCTMA4.js} +4 -4
- package/dist/query-AFX52UW5.js +50 -0
- package/dist/{ripgrep-RLDVZ7XG.js → ripgrep-G67OVBVY.js} +3 -3
- package/dist/{skillMarketplace-N45WWBB3.js → skillMarketplace-BW46UATH.js} +3 -3
- package/dist/{state-PVTHPFRK.js → state-FIT4XMBS.js} +2 -2
- package/dist/{theme-7YQL4AQ4.js → theme-TTXLGM5F.js} +5 -5
- package/dist/{toolPermissionSettings-EGYQOIYG.js → toolPermissionSettings-MGZHTVUO.js} +6 -6
- package/dist/tools-WGI7NLCF.js +47 -0
- package/dist/{userInput-6Z5PYOLR.js → userInput-ESF4AGO6.js} +27 -27
- package/package.json +18 -6
- package/dist/REPL-4QRH44HC.js +0 -42
- package/dist/chunk-3NZTTP2W.js.map +0 -7
- package/dist/chunk-UDXJD3B5.js.map +0 -7
- package/dist/chunk-WU4SXVFN.js.map +0 -7
- package/dist/chunk-YEDGG2CM.js.map +0 -7
- package/dist/commands-UAI6QEAI.js +0 -46
- package/dist/prompts-VPJ5WN33.js +0 -48
- package/dist/query-LGA6DMR3.js +0 -50
- package/dist/tools-CMR3PLSX.js +0 -47
- /package/dist/{REPL-4QRH44HC.js.map → REPL-75KL6GAB.js.map} +0 -0
- /package/dist/{acp-5COUMMLN.js.map → acp-HQIMVQVE.js.map} +0 -0
- /package/dist/{agentsValidate-DKGJ5OX4.js.map → agentsValidate-HP2QZOGZ.js.map} +0 -0
- /package/dist/{ask-QW644CAZ.js.map → ask-3WO2HDRK.js.map} +0 -0
- /package/dist/{autoUpdater-WUTZGWEM.js.map → autoUpdater-WBADQJDS.js.map} +0 -0
- /package/dist/{chunk-PJ2UYD4Q.js.map → chunk-4AWVNHCM.js.map} +0 -0
- /package/dist/{chunk-4FSJIGYW.js.map → chunk-6MUYPW7Q.js.map} +0 -0
- /package/dist/{chunk-6IQ6RNSC.js.map → chunk-AGMS7BAU.js.map} +0 -0
- /package/dist/{chunk-Q27MKRQ5.js.map → chunk-AIJXHCQJ.js.map} +0 -0
- /package/dist/{chunk-RSCGHYX4.js.map → chunk-C5IUVXAK.js.map} +0 -0
- /package/dist/{chunk-Q74XWGWS.js.map → chunk-D2OUHFOX.js.map} +0 -0
- /package/dist/{chunk-PWZPQLA5.js.map → chunk-DGQOYCQ4.js.map} +0 -0
- /package/dist/{chunk-HJPCQROC.js.map → chunk-F5NR7QE5.js.map} +0 -0
- /package/dist/{chunk-LCN6UMC2.js.map → chunk-FHCT4F4H.js.map} +0 -0
- /package/dist/{chunk-IA565ACR.js.map → chunk-MBYDWUYD.js.map} +0 -0
- /package/dist/{chunk-X2LHX4TN.js.map → chunk-MNSPB7QF.js.map} +0 -0
- /package/dist/{chunk-PF3A6LJD.js.map → chunk-O2HPDW7E.js.map} +0 -0
- /package/dist/{chunk-LTUBDTY7.js.map → chunk-O6EAVDYJ.js.map} +0 -0
- /package/dist/{chunk-KAAPCK6R.js.map → chunk-OS3PRGER.js.map} +0 -0
- /package/dist/{chunk-ILKTL4HO.js.map → chunk-PN453X6K.js.map} +0 -0
- /package/dist/{chunk-VXPAJIEJ.js.map → chunk-PWGVKIQ7.js.map} +0 -0
- /package/dist/{chunk-LFT6GMDJ.js.map → chunk-RAFAX7UH.js.map} +0 -0
- /package/dist/{chunk-DTOUFBLG.js.map → chunk-SN6CKFJP.js.map} +0 -0
- /package/dist/{chunk-KANFF7SM.js.map → chunk-TPTCH44R.js.map} +0 -0
- /package/dist/{chunk-YVLQDPDN.js.map → chunk-UC5GVD7H.js.map} +0 -0
- /package/dist/{chunk-TBU6CIW7.js.map → chunk-X2JUNUGX.js.map} +0 -0
- /package/dist/{chunk-ZQLAZEQ6.js.map → chunk-Z3FCTWM5.js.map} +0 -0
- /package/dist/{chunk-Z7P6CYVJ.js.map → chunk-ZMEZLZSY.js.map} +0 -0
- /package/dist/{cli-5AQQAMDZ.js.map → cli-ABH2I5QQ.js.map} +0 -0
- /package/dist/{commands-UAI6QEAI.js.map → commands-ZZDHT2TO.js.map} +0 -0
- /package/dist/{config-XUTCS32D.js.map → config-YZ5SH7PT.js.map} +0 -0
- /package/dist/{context-BJBOG5ML.js.map → context-UX3EZ3PA.js.map} +0 -0
- /package/dist/{customCommands-FCGJVPMM.js.map → customCommands-NTZP2HM3.js.map} +0 -0
- /package/dist/{env-PCEHNXQ7.js.map → env-PV2KGERM.js.map} +0 -0
- /package/dist/{llm-YXYHYLLL.js.map → llm-OTAQ7LEG.js.map} +0 -0
- /package/dist/{llmLazy-BWNMELGK.js.map → llmLazy-NBVRO2UR.js.map} +0 -0
- /package/dist/{loader-UXDARCPS.js.map → loader-F3GV54J2.js.map} +0 -0
- /package/dist/{mcp-OD4RSPAA.js.map → mcp-Q7OQHMV7.js.map} +0 -0
- /package/dist/{mentionProcessor-MRLHJCG7.js.map → mentionProcessor-GLCUGCM3.js.map} +0 -0
- /package/dist/{messages-WDA7YIIR.js.map → messages-ISLBFDID.js.map} +0 -0
- /package/dist/{model-E7A4ZTH3.js.map → model-OV6AVHYX.js.map} +0 -0
- /package/dist/{openai-6VE4E33T.js.map → openai-IFK7QCX7.js.map} +0 -0
- /package/dist/{outputStyles-ALNI7DMM.js.map → outputStyles-2NMFE3TD.js.map} +0 -0
- /package/dist/{pluginRuntime-ZJM5CYBI.js.map → pluginRuntime-RYXZP2NG.js.map} +0 -0
- /package/dist/{pluginValidation-P7F37TRM.js.map → pluginValidation-HOAJE2IY.js.map} +0 -0
- /package/dist/{prompts-VPJ5WN33.js.map → prompts-NHLWAHOF.js.map} +0 -0
- /package/dist/{pybAgentSessionLoad-DXA2GXAD.js.map → pybAgentSessionLoad-AI3GJDZB.js.map} +0 -0
- /package/dist/{pybAgentSessionResume-GSTPB6PZ.js.map → pybAgentSessionResume-NY5H4GWY.js.map} +0 -0
- /package/dist/{pybAgentStreamJsonSession-NJYZ5ZC5.js.map → pybAgentStreamJsonSession-YU2I7WZY.js.map} +0 -0
- /package/dist/{pybHooks-G4QW3QWC.js.map → pybHooks-UOLCTMA4.js.map} +0 -0
- /package/dist/{query-LGA6DMR3.js.map → query-AFX52UW5.js.map} +0 -0
- /package/dist/{ripgrep-RLDVZ7XG.js.map → ripgrep-G67OVBVY.js.map} +0 -0
- /package/dist/{skillMarketplace-N45WWBB3.js.map → skillMarketplace-BW46UATH.js.map} +0 -0
- /package/dist/{state-PVTHPFRK.js.map → state-FIT4XMBS.js.map} +0 -0
- /package/dist/{theme-7YQL4AQ4.js.map → theme-TTXLGM5F.js.map} +0 -0
- /package/dist/{toolPermissionSettings-EGYQOIYG.js.map → toolPermissionSettings-MGZHTVUO.js.map} +0 -0
- /package/dist/{tools-CMR3PLSX.js.map → tools-WGI7NLCF.js.map} +0 -0
- /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-
|
|
29
|
+
} from "./chunk-V5WZJEVQ.js";
|
|
30
30
|
import {
|
|
31
31
|
FallbackToolUseRejectedMessage,
|
|
32
32
|
MCPTool,
|
|
33
33
|
getClients,
|
|
34
34
|
getMCPTools
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-AIJXHCQJ.js";
|
|
36
36
|
import {
|
|
37
37
|
queryLLM
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-OS3PRGER.js";
|
|
39
39
|
import {
|
|
40
40
|
generateAgentId
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-4AWVNHCM.js";
|
|
42
42
|
import {
|
|
43
43
|
getActiveAgents,
|
|
44
44
|
getAgentByType,
|
|
45
45
|
getAvailableAgentTypes
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-AGMS7BAU.js";
|
|
47
47
|
import {
|
|
48
48
|
INTERRUPT_MESSAGE,
|
|
49
49
|
createAssistantMessage,
|
|
50
50
|
createUserMessage,
|
|
51
51
|
getLastAssistantMessageId
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-FHCT4F4H.js";
|
|
53
53
|
import {
|
|
54
54
|
getModelManager
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-MBYDWUYD.js";
|
|
56
56
|
import {
|
|
57
57
|
getContext
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-DGQOYCQ4.js";
|
|
59
59
|
import {
|
|
60
60
|
getTheme
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-MNSPB7QF.js";
|
|
62
62
|
import {
|
|
63
63
|
debug
|
|
64
|
-
} from "./chunk-
|
|
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-
|
|
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
|
|
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 {
|
|
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
|
|
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/
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 =
|
|
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
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
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
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
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
|
|
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 (!
|
|
2890
|
+
if (!existsSync5(path)) return null;
|
|
2054
2891
|
try {
|
|
2055
|
-
const raw =
|
|
2892
|
+
const raw = readFileSync4(path, "utf8");
|
|
2056
2893
|
const parsed = JSON.parse(raw);
|
|
2057
2894
|
return Array.isArray(parsed) ? parsed : null;
|
|
2058
2895
|
} catch {
|