@mastra/code-sdk 1.0.3-alpha.0 → 1.1.0-alpha.2
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/CHANGELOG.md +49 -0
- package/dist/acp/agent.js +155 -167
- package/dist/acp/agent.js.map +1 -1
- package/dist/acp/event-mapper.js +193 -168
- package/dist/acp/event-mapper.js.map +1 -1
- package/dist/acp/index.js +60 -49
- package/dist/acp/index.js.map +1 -1
- package/dist/acp/server.js +31 -30
- package/dist/acp/server.js.map +1 -1
- package/dist/acp.js +1 -4
- package/dist/agents/credential-resolver.js +40 -29
- package/dist/agents/credential-resolver.js.map +1 -1
- package/dist/agents/custom-provider-source.js +16 -9
- package/dist/agents/custom-provider-source.js.map +1 -1
- package/dist/agents/instructions.js +27 -36
- package/dist/agents/instructions.js.map +1 -1
- package/dist/agents/mastracode-gateway.js +355 -428
- package/dist/agents/mastracode-gateway.js.map +1 -1
- package/dist/agents/memory.js +87 -78
- package/dist/agents/memory.js.map +1 -1
- package/dist/agents/model.js +114 -119
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/modes/build.js +12 -13
- package/dist/agents/modes/build.js.map +1 -1
- package/dist/agents/modes/explore.js +14 -13
- package/dist/agents/modes/explore.js.map +1 -1
- package/dist/agents/modes/plan.js +14 -15
- package/dist/agents/modes/plan.js.map +1 -1
- package/dist/agents/prompts/agent-instructions.js +78 -69
- package/dist/agents/prompts/agent-instructions.js.map +1 -1
- package/dist/agents/prompts/build.js +19 -16
- package/dist/agents/prompts/build.js.map +1 -1
- package/dist/agents/prompts/fast.js +8 -4
- package/dist/agents/prompts/fast.js.map +1 -1
- package/dist/agents/prompts/index.js +48 -47
- package/dist/agents/prompts/index.js.map +1 -1
- package/dist/agents/prompts/model.js +6 -5
- package/dist/agents/prompts/model.js.map +1 -1
- package/dist/agents/prompts/plan.js +20 -16
- package/dist/agents/prompts/plan.js.map +1 -1
- package/dist/agents/prompts/tool-guidance.js +77 -109
- package/dist/agents/prompts/tool-guidance.js.map +1 -1
- package/dist/agents/sandbox-filesystem.js +245 -259
- package/dist/agents/sandbox-filesystem.js.map +1 -1
- package/dist/agents/sandbox-reattach.js +9 -11
- package/dist/agents/sandbox-reattach.js.map +1 -1
- package/dist/agents/thread-caveman-state.js +92 -81
- package/dist/agents/thread-caveman-state.js.map +1 -1
- package/dist/agents/tool-availability.js +62 -80
- package/dist/agents/tool-availability.js.map +1 -1
- package/dist/agents/tools.js +99 -139
- package/dist/agents/tools.js.map +1 -1
- package/dist/agents/workspace.js +232 -225
- package/dist/agents/workspace.js.map +1 -1
- package/dist/analytics.js +139 -128
- package/dist/analytics.js.map +1 -1
- package/dist/auth/authorization-input.js +39 -25
- package/dist/auth/authorization-input.js.map +1 -1
- package/dist/auth/device-code.js +112 -80
- package/dist/auth/device-code.js.map +1 -1
- package/dist/auth/index.js +2 -9
- package/dist/auth/pkce.js +27 -16
- package/dist/auth/pkce.js.map +1 -1
- package/dist/auth/providers/anthropic.js +107 -93
- package/dist/auth/providers/anthropic.js.map +1 -1
- package/dist/auth/providers/github-copilot.js +304 -293
- package/dist/auth/providers/github-copilot.js.map +1 -1
- package/dist/auth/providers/openai-codex.js +442 -460
- package/dist/auth/providers/openai-codex.js.map +1 -1
- package/dist/auth/providers/xai.js +179 -145
- package/dist/auth/providers/xai.js.map +1 -1
- package/dist/auth/storage.js +182 -175
- package/dist/auth/storage.js.map +1 -1
- package/dist/auth/types.js +1 -1
- package/dist/clipboard/index.js +206 -172
- package/dist/clipboard/index.js.map +1 -1
- package/dist/constants.js +11 -16
- package/dist/constants.js.map +1 -1
- package/dist/error-classification.js +19 -11
- package/dist/error-classification.js.map +1 -1
- package/dist/evals/context-builder.js +145 -104
- package/dist/evals/context-builder.js.map +1 -1
- package/dist/evals/index.js +4 -7
- package/dist/evals/scorers/classify-command.js +62 -41
- package/dist/evals/scorers/classify-command.js.map +1 -1
- package/dist/evals/scorers/efficiency.js +239 -181
- package/dist/evals/scorers/efficiency.js.map +1 -1
- package/dist/evals/scorers/extract-tools.js +51 -47
- package/dist/evals/scorers/extract-tools.js.map +1 -1
- package/dist/evals/scorers/index.js +1 -5
- package/dist/evals/scorers/outcome.js +321 -212
- package/dist/evals/scorers/outcome.js.map +1 -1
- package/dist/goal-manager.js +266 -261
- package/dist/goal-manager.js.map +1 -1
- package/dist/goal-signal.js +14 -13
- package/dist/goal-signal.js.map +1 -1
- package/dist/headless/cli.js +153 -154
- package/dist/headless/cli.js.map +1 -1
- package/dist/headless/flags.js +180 -178
- package/dist/headless/flags.js.map +1 -1
- package/dist/headless/format.js +72 -71
- package/dist/headless/format.js.map +1 -1
- package/dist/headless/index.js +5 -31
- package/dist/headless/policy.js +35 -31
- package/dist/headless/policy.js.map +1 -1
- package/dist/headless/run-mc.js +332 -334
- package/dist/headless/run-mc.js.map +1 -1
- package/dist/headless/types.js +16 -7
- package/dist/headless/types.js.map +1 -1
- package/dist/hooks/config.js +56 -61
- package/dist/hooks/config.js.map +1 -1
- package/dist/hooks/executor.js +118 -116
- package/dist/hooks/executor.js.map +1 -1
- package/dist/hooks/index.js +4 -15
- package/dist/hooks/manager.js +221 -280
- package/dist/hooks/manager.js.map +1 -1
- package/dist/hooks/types.js +5 -4
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +632 -712
- package/dist/index.js.map +1 -1
- package/dist/ipc/ipc-reporter.js +19 -22
- package/dist/ipc/ipc-reporter.js.map +1 -1
- package/dist/lsp/client.js +248 -306
- package/dist/lsp/client.js.map +1 -1
- package/dist/lsp/index.js +1 -6
- package/dist/lsp/language.js +39 -43
- package/dist/lsp/language.js.map +1 -1
- package/dist/lsp/manager.js +78 -93
- package/dist/lsp/manager.js.map +1 -1
- package/dist/lsp/server.js +151 -120
- package/dist/lsp/server.js.map +1 -1
- package/dist/lsp/workspace.js +50 -47
- package/dist/lsp/workspace.js.map +1 -1
- package/dist/mcp/config.js +210 -199
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/index.js +2 -9
- package/dist/mcp/manager.js +482 -475
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/types.js +1 -1
- package/dist/onboarding/custom-packs.js +14 -17
- package/dist/onboarding/custom-packs.js.map +1 -1
- package/dist/onboarding/custom-providers.js +22 -20
- package/dist/onboarding/custom-providers.js.map +1 -1
- package/dist/onboarding/index.d.ts +1 -1
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/index.js +3 -21
- package/dist/onboarding/om-settings.d.ts +5 -0
- package/dist/onboarding/om-settings.d.ts.map +1 -1
- package/dist/onboarding/om-settings.js +41 -20
- package/dist/onboarding/om-settings.js.map +1 -1
- package/dist/onboarding/packs.d.ts +4 -6
- package/dist/onboarding/packs.d.ts.map +1 -1
- package/dist/onboarding/packs.js +154 -105
- package/dist/onboarding/packs.js.map +1 -1
- package/dist/onboarding/settings.js +575 -517
- package/dist/onboarding/settings.js.map +1 -1
- package/dist/permissions.js +112 -99
- package/dist/permissions.js.map +1 -1
- package/dist/plugin.js +21 -23
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/dependencies.js +64 -87
- package/dist/plugins/dependencies.js.map +1 -1
- package/dist/plugins/install.js +159 -169
- package/dist/plugins/install.js.map +1 -1
- package/dist/plugins/loader.js +170 -185
- package/dist/plugins/loader.js.map +1 -1
- package/dist/plugins/manager.js +374 -380
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/manifest.js +38 -63
- package/dist/plugins/manifest.js.map +1 -1
- package/dist/plugins/package-link.js +48 -64
- package/dist/plugins/package-link.js.map +1 -1
- package/dist/plugins/paths.js +18 -19
- package/dist/plugins/paths.js.map +1 -1
- package/dist/plugins/registry.js +97 -81
- package/dist/plugins/registry.js.map +1 -1
- package/dist/plugins/scaffold.js +62 -98
- package/dist/plugins/scaffold.js.map +1 -1
- package/dist/plugins/types.js +1 -1
- package/dist/processors/plan-rejection-abort.js +45 -44
- package/dist/processors/plan-rejection-abort.js.map +1 -1
- package/dist/providers/amazon-bedrock-gateway.js +134 -125
- package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
- package/dist/providers/amazon-bedrock.js +68 -47
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/claude-max.js +153 -133
- package/dist/providers/claude-max.js.map +1 -1
- package/dist/providers/github-copilot.js +232 -230
- package/dist/providers/github-copilot.js.map +1 -1
- package/dist/providers/openai-codex.js +271 -260
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/providers/xai.js +57 -50
- package/dist/providers/xai.js.map +1 -1
- package/dist/schema.js +91 -89
- package/dist/schema.js.map +1 -1
- package/dist/theme-palette.js +18 -14
- package/dist/theme-palette.js.map +1 -1
- package/dist/tool-names.js +46 -37
- package/dist/tool-names.js.map +1 -1
- package/dist/tools/index.js +2 -8
- package/dist/tools/request-sandbox-access.js +71 -80
- package/dist/tools/request-sandbox-access.js.map +1 -1
- package/dist/tools/utils.js +26 -16
- package/dist/tools/utils.js.map +1 -1
- package/dist/tools/web-search.js +51 -55
- package/dist/tools/web-search.js.map +1 -1
- package/dist/utils/binaries.js +65 -61
- package/dist/utils/binaries.js.map +1 -1
- package/dist/utils/debug-log.js +51 -47
- package/dist/utils/debug-log.js.map +1 -1
- package/dist/utils/errors.js +157 -192
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/gateway-sync.js +49 -37
- package/dist/utils/gateway-sync.js.map +1 -1
- package/dist/utils/path-security.js +7 -6
- package/dist/utils/path-security.js.map +1 -1
- package/dist/utils/plan-diff.js +58 -39
- package/dist/utils/plan-diff.js.map +1 -1
- package/dist/utils/plans.js +92 -74
- package/dist/utils/plans.js.map +1 -1
- package/dist/utils/project.js +318 -256
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/signals-pubsub.js +117 -99
- package/dist/utils/signals-pubsub.js.map +1 -1
- package/dist/utils/slash-command-loader.js +118 -154
- package/dist/utils/slash-command-loader.js.map +1 -1
- package/dist/utils/slash-command-processor.js +92 -83
- package/dist/utils/slash-command-processor.js.map +1 -1
- package/dist/utils/stdin-pipe.js +87 -63
- package/dist/utils/stdin-pipe.js.map +1 -1
- package/dist/utils/storage-factory.js +104 -84
- package/dist/utils/storage-factory.js.map +1 -1
- package/dist/utils/storage-maintenance.js +249 -211
- package/dist/utils/storage-maintenance.js.map +1 -1
- package/dist/utils/thread-lock.js +96 -92
- package/dist/utils/thread-lock.js.map +1 -1
- package/dist/utils/token-estimator.js +12 -12
- package/dist/utils/token-estimator.js.map +1 -1
- package/dist/utils/update-check.d.ts +1 -1
- package/dist/utils/update-check.js +341 -259
- package/dist/utils/update-check.js.map +1 -1
- package/dist/voice/stt-registry.js +131 -113
- package/dist/voice/stt-registry.js.map +1 -1
- package/package.json +11 -11
- package/dist/acp.js.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/evals/index.js.map +0 -1
- package/dist/evals/scorers/index.js.map +0 -1
- package/dist/headless/index.js.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/lsp/index.js.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/types.js.map +0 -1
- package/dist/onboarding/index.js.map +0 -1
- package/dist/plugins/types.js.map +0 -1
- package/dist/tools/index.js.map +0 -1
package/dist/lsp/client.js
CHANGED
|
@@ -1,309 +1,251 @@
|
|
|
1
1
|
import { StreamMessageReader, StreamMessageWriter, createMessageConnection } from "vscode-jsonrpc/node.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
getAllDiagnostics() {
|
|
248
|
-
const allDiagnostics = [];
|
|
249
|
-
for (const diagnostics of this.diagnostics.values()) {
|
|
250
|
-
allDiagnostics.push(...diagnostics);
|
|
251
|
-
}
|
|
252
|
-
return allDiagnostics;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Notify server that a file was closed
|
|
256
|
-
*/
|
|
257
|
-
notifyClose(filePath) {
|
|
258
|
-
if (!this.connection) return;
|
|
259
|
-
const uri = `file://${filePath}`;
|
|
260
|
-
this.diagnostics.delete(uri);
|
|
261
|
-
this.connection.sendNotification("textDocument/didClose", {
|
|
262
|
-
textDocument: TextDocumentIdentifier.create(uri)
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Restart the LSP client
|
|
267
|
-
*/
|
|
268
|
-
async restart() {
|
|
269
|
-
await this.shutdown();
|
|
270
|
-
await this.initialize();
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Shutdown the connection
|
|
274
|
-
*/
|
|
275
|
-
async shutdown() {
|
|
276
|
-
if (this.connection) {
|
|
277
|
-
try {
|
|
278
|
-
const processAlive = this.process && !this.process.killed;
|
|
279
|
-
if (processAlive) {
|
|
280
|
-
await Promise.race([
|
|
281
|
-
this.connection.sendRequest("shutdown"),
|
|
282
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("Shutdown request timed out")), 1e3))
|
|
283
|
-
]);
|
|
284
|
-
this.connection.sendNotification("exit");
|
|
285
|
-
}
|
|
286
|
-
} catch {
|
|
287
|
-
}
|
|
288
|
-
try {
|
|
289
|
-
this.connection.dispose();
|
|
290
|
-
} catch {
|
|
291
|
-
}
|
|
292
|
-
this.connection = null;
|
|
293
|
-
}
|
|
294
|
-
if (this.process) {
|
|
295
|
-
try {
|
|
296
|
-
if (!this.process.killed) {
|
|
297
|
-
this.process.kill();
|
|
298
|
-
}
|
|
299
|
-
} catch {
|
|
300
|
-
}
|
|
301
|
-
this.process = null;
|
|
302
|
-
}
|
|
303
|
-
this.diagnostics = /* @__PURE__ */ new Map();
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
export {
|
|
307
|
-
LSPClient
|
|
2
|
+
import { Position, TextDocumentIdentifier } from "vscode-languageserver-protocol";
|
|
3
|
+
//#region src/lsp/client.ts
|
|
4
|
+
/**
|
|
5
|
+
* LSP Client wrapper for JSON-RPC communication
|
|
6
|
+
*/
|
|
7
|
+
var LSPClient = class {
|
|
8
|
+
connection = null;
|
|
9
|
+
process = null;
|
|
10
|
+
serverInfo;
|
|
11
|
+
workspaceRoot;
|
|
12
|
+
diagnostics = /* @__PURE__ */ new Map();
|
|
13
|
+
initializationOptions = null;
|
|
14
|
+
constructor(serverInfo, workspaceRoot) {
|
|
15
|
+
this.serverInfo = serverInfo;
|
|
16
|
+
this.workspaceRoot = workspaceRoot;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Initialize the LSP connection
|
|
20
|
+
*/
|
|
21
|
+
async initialize() {
|
|
22
|
+
const spawnResult = await this.serverInfo.spawn(this.workspaceRoot);
|
|
23
|
+
if (!spawnResult) throw new Error("Failed to spawn LSP server");
|
|
24
|
+
let initializationOptions = void 0;
|
|
25
|
+
if ("process" in spawnResult) {
|
|
26
|
+
this.process = spawnResult.process;
|
|
27
|
+
initializationOptions = spawnResult.initialization;
|
|
28
|
+
} else this.process = spawnResult;
|
|
29
|
+
if (!this.process.stdin || !this.process.stdout) throw new Error("Failed to create LSP process with proper stdio");
|
|
30
|
+
const reader = new StreamMessageReader(this.process.stdout);
|
|
31
|
+
const writer = new StreamMessageWriter(this.process.stdin);
|
|
32
|
+
this.connection = createMessageConnection(reader, writer);
|
|
33
|
+
this.connection.onError((error) => {
|
|
34
|
+
if ((error?.[0])?.code !== "ERR_STREAM_DESTROYED") {}
|
|
35
|
+
});
|
|
36
|
+
this.connection.onNotification("textDocument/publishDiagnostics", (params) => {
|
|
37
|
+
if (params.diagnostics && params.diagnostics.length > 0) {}
|
|
38
|
+
this.diagnostics.set(params.uri, params.diagnostics);
|
|
39
|
+
});
|
|
40
|
+
this.connection.onNotification((_method, _params) => {});
|
|
41
|
+
this.connection.listen();
|
|
42
|
+
if (this.process.stderr) this.process.stderr.on("data", (_data) => {});
|
|
43
|
+
this.process.on("error", (_error) => {});
|
|
44
|
+
this.process.on("exit", (_code, _signal) => {});
|
|
45
|
+
const initParams = {
|
|
46
|
+
processId: process.pid,
|
|
47
|
+
rootUri: `file://${this.workspaceRoot}`,
|
|
48
|
+
workspaceFolders: [{
|
|
49
|
+
name: "workspace",
|
|
50
|
+
uri: `file://${this.workspaceRoot}`
|
|
51
|
+
}],
|
|
52
|
+
capabilities: {
|
|
53
|
+
window: { workDoneProgress: true },
|
|
54
|
+
workspace: { configuration: true },
|
|
55
|
+
textDocument: {
|
|
56
|
+
publishDiagnostics: {
|
|
57
|
+
relatedInformation: true,
|
|
58
|
+
tagSupport: { valueSet: [1, 2] },
|
|
59
|
+
versionSupport: false
|
|
60
|
+
},
|
|
61
|
+
synchronization: {
|
|
62
|
+
didOpen: true,
|
|
63
|
+
didChange: true,
|
|
64
|
+
dynamicRegistration: false,
|
|
65
|
+
willSave: false,
|
|
66
|
+
willSaveWaitUntil: false,
|
|
67
|
+
didSave: false
|
|
68
|
+
},
|
|
69
|
+
completion: {
|
|
70
|
+
dynamicRegistration: false,
|
|
71
|
+
completionItem: {
|
|
72
|
+
snippetSupport: false,
|
|
73
|
+
commitCharactersSupport: false,
|
|
74
|
+
documentationFormat: ["markdown", "plaintext"],
|
|
75
|
+
deprecatedSupport: false,
|
|
76
|
+
preselectSupport: false
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
definition: {
|
|
80
|
+
dynamicRegistration: false,
|
|
81
|
+
linkSupport: true
|
|
82
|
+
},
|
|
83
|
+
typeDefinition: {
|
|
84
|
+
dynamicRegistration: false,
|
|
85
|
+
linkSupport: true
|
|
86
|
+
},
|
|
87
|
+
implementation: {
|
|
88
|
+
dynamicRegistration: false,
|
|
89
|
+
linkSupport: true
|
|
90
|
+
},
|
|
91
|
+
references: { dynamicRegistration: false },
|
|
92
|
+
documentHighlight: { dynamicRegistration: false },
|
|
93
|
+
documentSymbol: {
|
|
94
|
+
dynamicRegistration: false,
|
|
95
|
+
hierarchicalDocumentSymbolSupport: true
|
|
96
|
+
},
|
|
97
|
+
codeAction: {
|
|
98
|
+
dynamicRegistration: false,
|
|
99
|
+
codeActionLiteralSupport: { codeActionKind: { valueSet: [
|
|
100
|
+
"quickfix",
|
|
101
|
+
"refactor",
|
|
102
|
+
"refactor.extract",
|
|
103
|
+
"refactor.inline",
|
|
104
|
+
"refactor.rewrite",
|
|
105
|
+
"source",
|
|
106
|
+
"source.organizeImports"
|
|
107
|
+
] } }
|
|
108
|
+
},
|
|
109
|
+
hover: {
|
|
110
|
+
dynamicRegistration: false,
|
|
111
|
+
contentFormat: ["markdown", "plaintext"]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
if (initializationOptions) {
|
|
117
|
+
initParams.initializationOptions = initializationOptions;
|
|
118
|
+
this.initializationOptions = initializationOptions;
|
|
119
|
+
}
|
|
120
|
+
this.connection.onRequest("workspace/configuration", (params) => {
|
|
121
|
+
return params.items?.map(() => ({})) || [];
|
|
122
|
+
});
|
|
123
|
+
this.connection.onRequest("window/workDoneProgress/create", (_params) => {
|
|
124
|
+
return null;
|
|
125
|
+
});
|
|
126
|
+
await Promise.race([this.connection.sendRequest("initialize", initParams), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("LSP initialize request timed out")), 1e4))]);
|
|
127
|
+
this.connection.sendNotification("initialized", {});
|
|
128
|
+
if (this.initializationOptions) this.connection.sendNotification("workspace/didChangeConfiguration", { settings: this.initializationOptions });
|
|
129
|
+
else this.connection.sendNotification("workspace/didChangeConfiguration", { settings: {} });
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Notify the server that a document has been opened
|
|
133
|
+
*/
|
|
134
|
+
notifyOpen(filePath, content, languageId) {
|
|
135
|
+
if (!this.connection) return;
|
|
136
|
+
const uri = `file://${filePath}`;
|
|
137
|
+
this.diagnostics.delete(uri);
|
|
138
|
+
this.connection.sendNotification("textDocument/didOpen", { textDocument: {
|
|
139
|
+
uri,
|
|
140
|
+
languageId,
|
|
141
|
+
version: 0,
|
|
142
|
+
text: content
|
|
143
|
+
} });
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Notify the server that a document has changed
|
|
147
|
+
*/
|
|
148
|
+
notifyChange(filePath, content, version) {
|
|
149
|
+
if (!this.connection) return;
|
|
150
|
+
this.connection.sendNotification("textDocument/didChange", {
|
|
151
|
+
textDocument: {
|
|
152
|
+
uri: `file://${filePath}`,
|
|
153
|
+
version
|
|
154
|
+
},
|
|
155
|
+
contentChanges: [{ text: content }]
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Wait for diagnostics to be available for a specific file
|
|
160
|
+
* @param waitForChange If true, waits for diagnostics to change from their initial state
|
|
161
|
+
*/
|
|
162
|
+
async waitForDiagnostics(filePath, timeoutMs = 5e3, waitForChange = false) {
|
|
163
|
+
if (!this.connection) return [];
|
|
164
|
+
const uri = `file://${filePath}`;
|
|
165
|
+
const startTime = Date.now();
|
|
166
|
+
const initialDiagnostics = this.diagnostics.get(uri);
|
|
167
|
+
const initialCount = initialDiagnostics?.length || 0;
|
|
168
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
169
|
+
const currentDiagnostics = this.diagnostics.get(uri);
|
|
170
|
+
const currentCount = currentDiagnostics?.length || 0;
|
|
171
|
+
if (waitForChange) {
|
|
172
|
+
if (currentDiagnostics !== void 0 && currentCount !== initialCount) return currentDiagnostics;
|
|
173
|
+
} else if (currentDiagnostics !== void 0) return currentDiagnostics;
|
|
174
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
175
|
+
}
|
|
176
|
+
return waitForChange ? initialDiagnostics || [] : [];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get hover information for a position
|
|
180
|
+
*/
|
|
181
|
+
async getHover(filePath, line, character) {
|
|
182
|
+
if (!this.connection) return null;
|
|
183
|
+
try {
|
|
184
|
+
return await this.connection.sendRequest("textDocument/hover", {
|
|
185
|
+
textDocument: TextDocumentIdentifier.create(`file://${filePath}`),
|
|
186
|
+
position: Position.create(line, character)
|
|
187
|
+
});
|
|
188
|
+
} catch {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get diagnostics for a specific file
|
|
194
|
+
*/
|
|
195
|
+
getDiagnostics(filePath) {
|
|
196
|
+
const uri = `file://${filePath}`;
|
|
197
|
+
return this.diagnostics.get(uri) || [];
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Get all diagnostics from all files
|
|
201
|
+
*/
|
|
202
|
+
getAllDiagnostics() {
|
|
203
|
+
const allDiagnostics = [];
|
|
204
|
+
for (const diagnostics of this.diagnostics.values()) allDiagnostics.push(...diagnostics);
|
|
205
|
+
return allDiagnostics;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Notify server that a file was closed
|
|
209
|
+
*/
|
|
210
|
+
notifyClose(filePath) {
|
|
211
|
+
if (!this.connection) return;
|
|
212
|
+
const uri = `file://${filePath}`;
|
|
213
|
+
this.diagnostics.delete(uri);
|
|
214
|
+
this.connection.sendNotification("textDocument/didClose", { textDocument: TextDocumentIdentifier.create(uri) });
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Restart the LSP client
|
|
218
|
+
*/
|
|
219
|
+
async restart() {
|
|
220
|
+
await this.shutdown();
|
|
221
|
+
await this.initialize();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Shutdown the connection
|
|
225
|
+
*/
|
|
226
|
+
async shutdown() {
|
|
227
|
+
if (this.connection) {
|
|
228
|
+
try {
|
|
229
|
+
if (this.process && !this.process.killed) {
|
|
230
|
+
await Promise.race([this.connection.sendRequest("shutdown"), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Shutdown request timed out")), 1e3))]);
|
|
231
|
+
this.connection.sendNotification("exit");
|
|
232
|
+
}
|
|
233
|
+
} catch {}
|
|
234
|
+
try {
|
|
235
|
+
this.connection.dispose();
|
|
236
|
+
} catch {}
|
|
237
|
+
this.connection = null;
|
|
238
|
+
}
|
|
239
|
+
if (this.process) {
|
|
240
|
+
try {
|
|
241
|
+
if (!this.process.killed) this.process.kill();
|
|
242
|
+
} catch {}
|
|
243
|
+
this.process = null;
|
|
244
|
+
}
|
|
245
|
+
this.diagnostics = /* @__PURE__ */ new Map();
|
|
246
|
+
}
|
|
308
247
|
};
|
|
248
|
+
//#endregion
|
|
249
|
+
export { LSPClient };
|
|
250
|
+
|
|
309
251
|
//# sourceMappingURL=client.js.map
|
package/dist/lsp/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lsp/client.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport { StreamMessageReader, StreamMessageWriter, createMessageConnection } from 'vscode-jsonrpc/node.js';\nimport type { MessageConnection } from 'vscode-jsonrpc/node.js';\nimport { TextDocumentIdentifier, Position } from 'vscode-languageserver-protocol';\nimport type { Diagnostic } from 'vscode-languageserver-protocol';\nimport type { LSPServerInfo } from './server.js';\n\n/**\n * LSP Client wrapper for JSON-RPC communication\n */\nexport class LSPClient {\n private connection: MessageConnection | null = null;\n private process: ChildProcess | null = null;\n private serverInfo: LSPServerInfo;\n private workspaceRoot: string;\n private diagnostics: Map<string, Diagnostic[]> = new Map();\n private initializationOptions: any = null;\n\n constructor(serverInfo: LSPServerInfo, workspaceRoot: string) {\n this.serverInfo = serverInfo;\n this.workspaceRoot = workspaceRoot;\n }\n\n /**\n * Initialize the LSP connection\n */\n async initialize(): Promise<void> {\n const spawnResult = await this.serverInfo.spawn(this.workspaceRoot);\n\n if (!spawnResult) {\n throw new Error('Failed to spawn LSP server');\n }\n\n // Handle both ChildProcess and { process: ChildProcess, initialization? } formats\n let initializationOptions: any = undefined;\n if ('process' in spawnResult) {\n this.process = spawnResult.process;\n initializationOptions = spawnResult.initialization;\n } else {\n this.process = spawnResult;\n }\n\n if (!this.process.stdin || !this.process.stdout) {\n throw new Error('Failed to create LSP process with proper stdio');\n }\n\n const reader = new StreamMessageReader(this.process.stdout);\n const writer = new StreamMessageWriter(this.process.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n // Handle connection errors (e.g., ERR_STREAM_DESTROYED during shutdown)\n this.connection.onError(error => {\n // Silently ignore stream destroyed errors during shutdown\n const errorObj = error?.[0] as any;\n if (errorObj?.code !== 'ERR_STREAM_DESTROYED') {\n }\n });\n\n // Set up diagnostic listener before starting connection\n\n this.connection.onNotification('textDocument/publishDiagnostics', (params: any) => {\n if (params.diagnostics && params.diagnostics.length > 0) {\n }\n this.diagnostics.set(params.uri, params.diagnostics);\n });\n (this.connection as any).onNotification((_method: string, _params: any) => {});\n\n this.connection.listen();\n\n // Capture stderr for debugging\n if (this.process.stderr) {\n this.process.stderr.on('data', _data => {});\n }\n\n // Handle process errors\n this.process.on('error', _error => {});\n\n this.process.on('exit', (_code, _signal) => {});\n\n // Send initialize request matching OpenCode's structure\n const initParams: any = {\n processId: process.pid,\n rootUri: `file://${this.workspaceRoot}`,\n workspaceFolders: [\n {\n name: 'workspace',\n uri: `file://${this.workspaceRoot}`,\n },\n ],\n capabilities: {\n window: {\n workDoneProgress: true,\n },\n workspace: {\n configuration: true,\n },\n textDocument: {\n publishDiagnostics: {\n relatedInformation: true,\n tagSupport: {\n valueSet: [1, 2],\n },\n versionSupport: false,\n },\n synchronization: {\n didOpen: true,\n didChange: true,\n dynamicRegistration: false,\n willSave: false,\n willSaveWaitUntil: false,\n didSave: false,\n },\n completion: {\n dynamicRegistration: false,\n completionItem: {\n snippetSupport: false,\n commitCharactersSupport: false,\n documentationFormat: ['markdown', 'plaintext'],\n deprecatedSupport: false,\n preselectSupport: false,\n },\n },\n definition: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n typeDefinition: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n implementation: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n references: {\n dynamicRegistration: false,\n },\n documentHighlight: {\n dynamicRegistration: false,\n },\n documentSymbol: {\n dynamicRegistration: false,\n hierarchicalDocumentSymbolSupport: true,\n },\n codeAction: {\n dynamicRegistration: false,\n codeActionLiteralSupport: {\n codeActionKind: {\n valueSet: [\n 'quickfix',\n 'refactor',\n 'refactor.extract',\n 'refactor.inline',\n 'refactor.rewrite',\n 'source',\n 'source.organizeImports',\n ],\n },\n },\n },\n hover: {\n dynamicRegistration: false,\n contentFormat: ['markdown', 'plaintext'],\n },\n },\n },\n };\n\n // Add initialization options if provided by the server\n if (initializationOptions) {\n initParams.initializationOptions = initializationOptions;\n this.initializationOptions = initializationOptions;\n }\n\n // Add workspace/configuration request handler like OpenCode\n this.connection.onRequest('workspace/configuration', (params: any) => {\n return params.items?.map(() => ({})) || [];\n });\n\n // Handle window/workDoneProgress/create requests\n this.connection.onRequest('window/workDoneProgress/create', (_params: any) => {\n return null;\n });\n\n await Promise.race([\n this.connection.sendRequest('initialize', initParams),\n new Promise((_, reject) => setTimeout(() => reject(new Error('LSP initialize request timed out')), 10000)),\n ]);\n\n // Send initialized notification with empty object like OpenCode\n this.connection.sendNotification('initialized', {});\n\n // Send workspace/didChangeConfiguration with initialization options like OpenCode\n if (this.initializationOptions) {\n this.connection.sendNotification('workspace/didChangeConfiguration', {\n settings: this.initializationOptions,\n });\n } else {\n this.connection.sendNotification('workspace/didChangeConfiguration', {\n settings: {},\n });\n }\n }\n\n /**\n * Notify the server that a document has been opened\n */\n notifyOpen(filePath: string, content: string, languageId: string): void {\n if (!this.connection) return;\n\n const uri = `file://${filePath}`;\n\n // Clear diagnostics for this file before sending didOpen (like OpenCode does)\n this.diagnostics.delete(uri);\n\n this.connection.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri,\n languageId,\n version: 0,\n text: content,\n },\n });\n }\n\n /**\n * Notify the server that a document has changed\n */\n notifyChange(filePath: string, content: string, version: number): void {\n if (!this.connection) return;\n\n this.connection.sendNotification('textDocument/didChange', {\n textDocument: {\n uri: `file://${filePath}`,\n version,\n },\n contentChanges: [{ text: content }],\n });\n }\n\n /**\n * Wait for diagnostics to be available for a specific file\n * @param waitForChange If true, waits for diagnostics to change from their initial state\n */\n async waitForDiagnostics(\n filePath: string,\n timeoutMs: number = 5000,\n waitForChange: boolean = false,\n ): Promise<Diagnostic[]> {\n if (!this.connection) return [];\n\n const uri = `file://${filePath}`;\n const startTime = Date.now();\n const initialDiagnostics = this.diagnostics.get(uri);\n const initialCount = initialDiagnostics?.length || 0;\n\n // Poll for diagnostics to be updated\n while (Date.now() - startTime < timeoutMs) {\n const currentDiagnostics = this.diagnostics.get(uri);\n const currentCount = currentDiagnostics?.length || 0;\n\n // If waiting for change, check if diagnostics have changed\n if (waitForChange) {\n if (currentDiagnostics !== undefined && currentCount !== initialCount) {\n return currentDiagnostics;\n }\n } else {\n // Return if we have diagnostics (even if empty array)\n if (currentDiagnostics !== undefined) {\n return currentDiagnostics;\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n\n return waitForChange ? initialDiagnostics || [] : [];\n }\n\n /**\n * Get hover information for a position\n */\n async getHover(filePath: string, line: number, character: number): Promise<any> {\n if (!this.connection) return null;\n\n try {\n return await this.connection.sendRequest('textDocument/hover', {\n textDocument: TextDocumentIdentifier.create(`file://${filePath}`),\n position: Position.create(line, character),\n });\n } catch {\n return null;\n }\n }\n\n /**\n * Get diagnostics for a specific file\n */\n getDiagnostics(filePath: string): Diagnostic[] {\n const uri = `file://${filePath}`;\n return this.diagnostics.get(uri) || [];\n }\n\n /**\n * Get all diagnostics from all files\n */\n getAllDiagnostics(): Diagnostic[] {\n const allDiagnostics: Diagnostic[] = [];\n for (const diagnostics of this.diagnostics.values()) {\n allDiagnostics.push(...diagnostics);\n }\n return allDiagnostics;\n }\n\n /**\n * Notify server that a file was closed\n */\n notifyClose(filePath: string): void {\n if (!this.connection) return;\n\n const uri = `file://${filePath}`;\n\n // Clear diagnostics for this file\n this.diagnostics.delete(uri);\n\n // Send didClose notification\n this.connection.sendNotification('textDocument/didClose', {\n textDocument: TextDocumentIdentifier.create(uri),\n });\n }\n\n /**\n * Restart the LSP client\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n // Re-initialize (this will re-spawn the server)\n await this.initialize();\n }\n\n /**\n * Shutdown the connection\n */\n async shutdown(): Promise<void> {\n if (this.connection) {\n try {\n // Only send shutdown request if the process is still alive\n const processAlive = this.process && !this.process.killed;\n if (processAlive) {\n await Promise.race([\n this.connection.sendRequest('shutdown'),\n new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown request timed out')), 1000)),\n ]);\n this.connection.sendNotification('exit');\n }\n } catch {\n // Ignore shutdown errors (process may have already crashed)\n }\n try {\n this.connection.dispose();\n } catch {\n // Ignore dispose errors (stream may already be destroyed)\n }\n this.connection = null;\n }\n\n if (this.process) {\n try {\n if (!this.process.killed) {\n this.process.kill();\n }\n } catch {\n // Ignore kill errors\n }\n this.process = null;\n }\n\n this.diagnostics = new Map();\n }\n}\n"],"mappings":"AACA,SAAS,qBAAqB,qBAAqB,+BAA+B;AAElF,SAAS,wBAAwB,gBAAgB;AAO1C,MAAM,UAAU;AAAA,EACb,aAAuC;AAAA,EACvC,UAA+B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,cAAyC,oBAAI,IAAI;AAAA,EACjD,wBAA6B;AAAA,EAErC,YAAY,YAA2B,eAAuB;AAC5D,SAAK,aAAa;AAClB,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,UAAM,cAAc,MAAM,KAAK,WAAW,MAAM,KAAK,aAAa;AAElE,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AAGA,QAAI,wBAA6B;AACjC,QAAI,aAAa,aAAa;AAC5B,WAAK,UAAU,YAAY;AAC3B,8BAAwB,YAAY;AAAA,IACtC,OAAO;AACL,WAAK,UAAU;AAAA,IACjB;AAEA,QAAI,CAAC,KAAK,QAAQ,SAAS,CAAC,KAAK,QAAQ,QAAQ;AAC/C,YAAM,IAAI,MAAM,gDAAgD;AAAA,IAClE;AAEA,UAAM,SAAS,IAAI,oBAAoB,KAAK,QAAQ,MAAM;AAC1D,UAAM,SAAS,IAAI,oBAAoB,KAAK,QAAQ,KAAK;AACzD,SAAK,aAAa,wBAAwB,QAAQ,MAAM;AAGxD,SAAK,WAAW,QAAQ,WAAS;AAE/B,YAAM,WAAW,QAAQ,CAAC;AAC1B,UAAI,UAAU,SAAS,wBAAwB;AAAA,MAC/C;AAAA,IACF,CAAC;AAID,SAAK,WAAW,eAAe,mCAAmC,CAAC,WAAgB;AACjF,UAAI,OAAO,eAAe,OAAO,YAAY,SAAS,GAAG;AAAA,MACzD;AACA,WAAK,YAAY,IAAI,OAAO,KAAK,OAAO,WAAW;AAAA,IACrD,CAAC;AACD,IAAC,KAAK,WAAmB,eAAe,CAAC,SAAiB,YAAiB;AAAA,IAAC,CAAC;AAE7E,SAAK,WAAW,OAAO;AAGvB,QAAI,KAAK,QAAQ,QAAQ;AACvB,WAAK,QAAQ,OAAO,GAAG,QAAQ,WAAS;AAAA,MAAC,CAAC;AAAA,IAC5C;AAGA,SAAK,QAAQ,GAAG,SAAS,YAAU;AAAA,IAAC,CAAC;AAErC,SAAK,QAAQ,GAAG,QAAQ,CAAC,OAAO,YAAY;AAAA,IAAC,CAAC;AAG9C,UAAM,aAAkB;AAAA,MACtB,WAAW,QAAQ;AAAA,MACnB,SAAS,UAAU,KAAK,aAAa;AAAA,MACrC,kBAAkB;AAAA,QAChB;AAAA,UACE,MAAM;AAAA,UACN,KAAK,UAAU,KAAK,aAAa;AAAA,QACnC;AAAA,MACF;AAAA,MACA,cAAc;AAAA,QACZ,QAAQ;AAAA,UACN,kBAAkB;AAAA,QACpB;AAAA,QACA,WAAW;AAAA,UACT,eAAe;AAAA,QACjB;AAAA,QACA,cAAc;AAAA,UACZ,oBAAoB;AAAA,YAClB,oBAAoB;AAAA,YACpB,YAAY;AAAA,cACV,UAAU,CAAC,GAAG,CAAC;AAAA,YACjB;AAAA,YACA,gBAAgB;AAAA,UAClB;AAAA,UACA,iBAAiB;AAAA,YACf,SAAS;AAAA,YACT,WAAW;AAAA,YACX,qBAAqB;AAAA,YACrB,UAAU;AAAA,YACV,mBAAmB;AAAA,YACnB,SAAS;AAAA,UACX;AAAA,UACA,YAAY;AAAA,YACV,qBAAqB;AAAA,YACrB,gBAAgB;AAAA,cACd,gBAAgB;AAAA,cAChB,yBAAyB;AAAA,cACzB,qBAAqB,CAAC,YAAY,WAAW;AAAA,cAC7C,mBAAmB;AAAA,cACnB,kBAAkB;AAAA,YACpB;AAAA,UACF;AAAA,UACA,YAAY;AAAA,YACV,qBAAqB;AAAA,YACrB,aAAa;AAAA,UACf;AAAA,UACA,gBAAgB;AAAA,YACd,qBAAqB;AAAA,YACrB,aAAa;AAAA,UACf;AAAA,UACA,gBAAgB;AAAA,YACd,qBAAqB;AAAA,YACrB,aAAa;AAAA,UACf;AAAA,UACA,YAAY;AAAA,YACV,qBAAqB;AAAA,UACvB;AAAA,UACA,mBAAmB;AAAA,YACjB,qBAAqB;AAAA,UACvB;AAAA,UACA,gBAAgB;AAAA,YACd,qBAAqB;AAAA,YACrB,mCAAmC;AAAA,UACrC;AAAA,UACA,YAAY;AAAA,YACV,qBAAqB;AAAA,YACrB,0BAA0B;AAAA,cACxB,gBAAgB;AAAA,gBACd,UAAU;AAAA,kBACR;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,UACA,OAAO;AAAA,YACL,qBAAqB;AAAA,YACrB,eAAe,CAAC,YAAY,WAAW;AAAA,UACzC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,uBAAuB;AACzB,iBAAW,wBAAwB;AACnC,WAAK,wBAAwB;AAAA,IAC/B;AAGA,SAAK,WAAW,UAAU,2BAA2B,CAAC,WAAgB;AACpE,aAAO,OAAO,OAAO,IAAI,OAAO,CAAC,EAAE,KAAK,CAAC;AAAA,IAC3C,CAAC;AAGD,SAAK,WAAW,UAAU,kCAAkC,CAAC,YAAiB;AAC5E,aAAO;AAAA,IACT,CAAC;AAED,UAAM,QAAQ,KAAK;AAAA,MACjB,KAAK,WAAW,YAAY,cAAc,UAAU;AAAA,MACpD,IAAI,QAAQ,CAAC,GAAG,WAAW,WAAW,MAAM,OAAO,IAAI,MAAM,kCAAkC,CAAC,GAAG,GAAK,CAAC;AAAA,IAC3G,CAAC;AAGD,SAAK,WAAW,iBAAiB,eAAe,CAAC,CAAC;AAGlD,QAAI,KAAK,uBAAuB;AAC9B,WAAK,WAAW,iBAAiB,oCAAoC;AAAA,QACnE,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IACH,OAAO;AACL,WAAK,WAAW,iBAAiB,oCAAoC;AAAA,QACnE,UAAU,CAAC;AAAA,MACb,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,UAAkB,SAAiB,YAA0B;AACtE,QAAI,CAAC,KAAK,WAAY;AAEtB,UAAM,MAAM,UAAU,QAAQ;AAG9B,SAAK,YAAY,OAAO,GAAG;AAE3B,SAAK,WAAW,iBAAiB,wBAAwB;AAAA,MACvD,cAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,UAAkB,SAAiB,SAAuB;AACrE,QAAI,CAAC,KAAK,WAAY;AAEtB,SAAK,WAAW,iBAAiB,0BAA0B;AAAA,MACzD,cAAc;AAAA,QACZ,KAAK,UAAU,QAAQ;AAAA,QACvB;AAAA,MACF;AAAA,MACA,gBAAgB,CAAC,EAAE,MAAM,QAAQ,CAAC;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,mBACJ,UACA,YAAoB,KACpB,gBAAyB,OACF;AACvB,QAAI,CAAC,KAAK,WAAY,QAAO,CAAC;AAE9B,UAAM,MAAM,UAAU,QAAQ;AAC9B,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,qBAAqB,KAAK,YAAY,IAAI,GAAG;AACnD,UAAM,eAAe,oBAAoB,UAAU;AAGnD,WAAO,KAAK,IAAI,IAAI,YAAY,WAAW;AACzC,YAAM,qBAAqB,KAAK,YAAY,IAAI,GAAG;AACnD,YAAM,eAAe,oBAAoB,UAAU;AAGnD,UAAI,eAAe;AACjB,YAAI,uBAAuB,UAAa,iBAAiB,cAAc;AACrE,iBAAO;AAAA,QACT;AAAA,MACF,OAAO;AAEL,YAAI,uBAAuB,QAAW;AACpC,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,IAAI,QAAQ,aAAW,WAAW,SAAS,GAAG,CAAC;AAAA,IACvD;AAEA,WAAO,gBAAgB,sBAAsB,CAAC,IAAI,CAAC;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,UAAkB,MAAc,WAAiC;AAC9E,QAAI,CAAC,KAAK,WAAY,QAAO;AAE7B,QAAI;AACF,aAAO,MAAM,KAAK,WAAW,YAAY,sBAAsB;AAAA,QAC7D,cAAc,uBAAuB,OAAO,UAAU,QAAQ,EAAE;AAAA,QAChE,UAAU,SAAS,OAAO,MAAM,SAAS;AAAA,MAC3C,CAAC;AAAA,IACH,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,UAAgC;AAC7C,UAAM,MAAM,UAAU,QAAQ;AAC9B,WAAO,KAAK,YAAY,IAAI,GAAG,KAAK,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAkC;AAChC,UAAM,iBAA+B,CAAC;AACtC,eAAW,eAAe,KAAK,YAAY,OAAO,GAAG;AACnD,qBAAe,KAAK,GAAG,WAAW;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,UAAwB;AAClC,QAAI,CAAC,KAAK,WAAY;AAEtB,UAAM,MAAM,UAAU,QAAQ;AAG9B,SAAK,YAAY,OAAO,GAAG;AAG3B,SAAK,WAAW,iBAAiB,yBAAyB;AAAA,MACxD,cAAc,uBAAuB,OAAO,GAAG;AAAA,IACjD,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC7B,UAAM,KAAK,SAAS;AAGpB,UAAM,KAAK,WAAW;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,QAAI,KAAK,YAAY;AACnB,UAAI;AAEF,cAAM,eAAe,KAAK,WAAW,CAAC,KAAK,QAAQ;AACnD,YAAI,cAAc;AAChB,gBAAM,QAAQ,KAAK;AAAA,YACjB,KAAK,WAAW,YAAY,UAAU;AAAA,YACtC,IAAI,QAAQ,CAAC,GAAG,WAAW,WAAW,MAAM,OAAO,IAAI,MAAM,4BAA4B,CAAC,GAAG,GAAI,CAAC;AAAA,UACpG,CAAC;AACD,eAAK,WAAW,iBAAiB,MAAM;AAAA,QACzC;AAAA,MACF,QAAQ;AAAA,MAER;AACA,UAAI;AACF,aAAK,WAAW,QAAQ;AAAA,MAC1B,QAAQ;AAAA,MAER;AACA,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,KAAK,SAAS;AAChB,UAAI;AACF,YAAI,CAAC,KAAK,QAAQ,QAAQ;AACxB,eAAK,QAAQ,KAAK;AAAA,QACpB;AAAA,MACF,QAAQ;AAAA,MAER;AACA,WAAK,UAAU;AAAA,IACjB;AAEA,SAAK,cAAc,oBAAI,IAAI;AAAA,EAC7B;AACF;","names":[]}
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../src/lsp/client.ts"],"sourcesContent":["import type { ChildProcess } from 'node:child_process';\nimport { StreamMessageReader, StreamMessageWriter, createMessageConnection } from 'vscode-jsonrpc/node.js';\nimport type { MessageConnection } from 'vscode-jsonrpc/node.js';\nimport { TextDocumentIdentifier, Position } from 'vscode-languageserver-protocol';\nimport type { Diagnostic } from 'vscode-languageserver-protocol';\nimport type { LSPServerInfo } from './server.js';\n\n/**\n * LSP Client wrapper for JSON-RPC communication\n */\nexport class LSPClient {\n private connection: MessageConnection | null = null;\n private process: ChildProcess | null = null;\n private serverInfo: LSPServerInfo;\n private workspaceRoot: string;\n private diagnostics: Map<string, Diagnostic[]> = new Map();\n private initializationOptions: any = null;\n\n constructor(serverInfo: LSPServerInfo, workspaceRoot: string) {\n this.serverInfo = serverInfo;\n this.workspaceRoot = workspaceRoot;\n }\n\n /**\n * Initialize the LSP connection\n */\n async initialize(): Promise<void> {\n const spawnResult = await this.serverInfo.spawn(this.workspaceRoot);\n\n if (!spawnResult) {\n throw new Error('Failed to spawn LSP server');\n }\n\n // Handle both ChildProcess and { process: ChildProcess, initialization? } formats\n let initializationOptions: any = undefined;\n if ('process' in spawnResult) {\n this.process = spawnResult.process;\n initializationOptions = spawnResult.initialization;\n } else {\n this.process = spawnResult;\n }\n\n if (!this.process.stdin || !this.process.stdout) {\n throw new Error('Failed to create LSP process with proper stdio');\n }\n\n const reader = new StreamMessageReader(this.process.stdout);\n const writer = new StreamMessageWriter(this.process.stdin);\n this.connection = createMessageConnection(reader, writer);\n\n // Handle connection errors (e.g., ERR_STREAM_DESTROYED during shutdown)\n this.connection.onError(error => {\n // Silently ignore stream destroyed errors during shutdown\n const errorObj = error?.[0] as any;\n if (errorObj?.code !== 'ERR_STREAM_DESTROYED') {\n }\n });\n\n // Set up diagnostic listener before starting connection\n\n this.connection.onNotification('textDocument/publishDiagnostics', (params: any) => {\n if (params.diagnostics && params.diagnostics.length > 0) {\n }\n this.diagnostics.set(params.uri, params.diagnostics);\n });\n (this.connection as any).onNotification((_method: string, _params: any) => {});\n\n this.connection.listen();\n\n // Capture stderr for debugging\n if (this.process.stderr) {\n this.process.stderr.on('data', _data => {});\n }\n\n // Handle process errors\n this.process.on('error', _error => {});\n\n this.process.on('exit', (_code, _signal) => {});\n\n // Send initialize request matching OpenCode's structure\n const initParams: any = {\n processId: process.pid,\n rootUri: `file://${this.workspaceRoot}`,\n workspaceFolders: [\n {\n name: 'workspace',\n uri: `file://${this.workspaceRoot}`,\n },\n ],\n capabilities: {\n window: {\n workDoneProgress: true,\n },\n workspace: {\n configuration: true,\n },\n textDocument: {\n publishDiagnostics: {\n relatedInformation: true,\n tagSupport: {\n valueSet: [1, 2],\n },\n versionSupport: false,\n },\n synchronization: {\n didOpen: true,\n didChange: true,\n dynamicRegistration: false,\n willSave: false,\n willSaveWaitUntil: false,\n didSave: false,\n },\n completion: {\n dynamicRegistration: false,\n completionItem: {\n snippetSupport: false,\n commitCharactersSupport: false,\n documentationFormat: ['markdown', 'plaintext'],\n deprecatedSupport: false,\n preselectSupport: false,\n },\n },\n definition: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n typeDefinition: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n implementation: {\n dynamicRegistration: false,\n linkSupport: true,\n },\n references: {\n dynamicRegistration: false,\n },\n documentHighlight: {\n dynamicRegistration: false,\n },\n documentSymbol: {\n dynamicRegistration: false,\n hierarchicalDocumentSymbolSupport: true,\n },\n codeAction: {\n dynamicRegistration: false,\n codeActionLiteralSupport: {\n codeActionKind: {\n valueSet: [\n 'quickfix',\n 'refactor',\n 'refactor.extract',\n 'refactor.inline',\n 'refactor.rewrite',\n 'source',\n 'source.organizeImports',\n ],\n },\n },\n },\n hover: {\n dynamicRegistration: false,\n contentFormat: ['markdown', 'plaintext'],\n },\n },\n },\n };\n\n // Add initialization options if provided by the server\n if (initializationOptions) {\n initParams.initializationOptions = initializationOptions;\n this.initializationOptions = initializationOptions;\n }\n\n // Add workspace/configuration request handler like OpenCode\n this.connection.onRequest('workspace/configuration', (params: any) => {\n return params.items?.map(() => ({})) || [];\n });\n\n // Handle window/workDoneProgress/create requests\n this.connection.onRequest('window/workDoneProgress/create', (_params: any) => {\n return null;\n });\n\n await Promise.race([\n this.connection.sendRequest('initialize', initParams),\n new Promise((_, reject) => setTimeout(() => reject(new Error('LSP initialize request timed out')), 10000)),\n ]);\n\n // Send initialized notification with empty object like OpenCode\n this.connection.sendNotification('initialized', {});\n\n // Send workspace/didChangeConfiguration with initialization options like OpenCode\n if (this.initializationOptions) {\n this.connection.sendNotification('workspace/didChangeConfiguration', {\n settings: this.initializationOptions,\n });\n } else {\n this.connection.sendNotification('workspace/didChangeConfiguration', {\n settings: {},\n });\n }\n }\n\n /**\n * Notify the server that a document has been opened\n */\n notifyOpen(filePath: string, content: string, languageId: string): void {\n if (!this.connection) return;\n\n const uri = `file://${filePath}`;\n\n // Clear diagnostics for this file before sending didOpen (like OpenCode does)\n this.diagnostics.delete(uri);\n\n this.connection.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri,\n languageId,\n version: 0,\n text: content,\n },\n });\n }\n\n /**\n * Notify the server that a document has changed\n */\n notifyChange(filePath: string, content: string, version: number): void {\n if (!this.connection) return;\n\n this.connection.sendNotification('textDocument/didChange', {\n textDocument: {\n uri: `file://${filePath}`,\n version,\n },\n contentChanges: [{ text: content }],\n });\n }\n\n /**\n * Wait for diagnostics to be available for a specific file\n * @param waitForChange If true, waits for diagnostics to change from their initial state\n */\n async waitForDiagnostics(\n filePath: string,\n timeoutMs: number = 5000,\n waitForChange: boolean = false,\n ): Promise<Diagnostic[]> {\n if (!this.connection) return [];\n\n const uri = `file://${filePath}`;\n const startTime = Date.now();\n const initialDiagnostics = this.diagnostics.get(uri);\n const initialCount = initialDiagnostics?.length || 0;\n\n // Poll for diagnostics to be updated\n while (Date.now() - startTime < timeoutMs) {\n const currentDiagnostics = this.diagnostics.get(uri);\n const currentCount = currentDiagnostics?.length || 0;\n\n // If waiting for change, check if diagnostics have changed\n if (waitForChange) {\n if (currentDiagnostics !== undefined && currentCount !== initialCount) {\n return currentDiagnostics;\n }\n } else {\n // Return if we have diagnostics (even if empty array)\n if (currentDiagnostics !== undefined) {\n return currentDiagnostics;\n }\n }\n\n await new Promise(resolve => setTimeout(resolve, 100));\n }\n\n return waitForChange ? initialDiagnostics || [] : [];\n }\n\n /**\n * Get hover information for a position\n */\n async getHover(filePath: string, line: number, character: number): Promise<any> {\n if (!this.connection) return null;\n\n try {\n return await this.connection.sendRequest('textDocument/hover', {\n textDocument: TextDocumentIdentifier.create(`file://${filePath}`),\n position: Position.create(line, character),\n });\n } catch {\n return null;\n }\n }\n\n /**\n * Get diagnostics for a specific file\n */\n getDiagnostics(filePath: string): Diagnostic[] {\n const uri = `file://${filePath}`;\n return this.diagnostics.get(uri) || [];\n }\n\n /**\n * Get all diagnostics from all files\n */\n getAllDiagnostics(): Diagnostic[] {\n const allDiagnostics: Diagnostic[] = [];\n for (const diagnostics of this.diagnostics.values()) {\n allDiagnostics.push(...diagnostics);\n }\n return allDiagnostics;\n }\n\n /**\n * Notify server that a file was closed\n */\n notifyClose(filePath: string): void {\n if (!this.connection) return;\n\n const uri = `file://${filePath}`;\n\n // Clear diagnostics for this file\n this.diagnostics.delete(uri);\n\n // Send didClose notification\n this.connection.sendNotification('textDocument/didClose', {\n textDocument: TextDocumentIdentifier.create(uri),\n });\n }\n\n /**\n * Restart the LSP client\n */\n async restart(): Promise<void> {\n await this.shutdown();\n\n // Re-initialize (this will re-spawn the server)\n await this.initialize();\n }\n\n /**\n * Shutdown the connection\n */\n async shutdown(): Promise<void> {\n if (this.connection) {\n try {\n // Only send shutdown request if the process is still alive\n const processAlive = this.process && !this.process.killed;\n if (processAlive) {\n await Promise.race([\n this.connection.sendRequest('shutdown'),\n new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown request timed out')), 1000)),\n ]);\n this.connection.sendNotification('exit');\n }\n } catch {\n // Ignore shutdown errors (process may have already crashed)\n }\n try {\n this.connection.dispose();\n } catch {\n // Ignore dispose errors (stream may already be destroyed)\n }\n this.connection = null;\n }\n\n if (this.process) {\n try {\n if (!this.process.killed) {\n this.process.kill();\n }\n } catch {\n // Ignore kill errors\n }\n this.process = null;\n }\n\n this.diagnostics = new Map();\n }\n}\n"],"mappings":"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"}
|