vibe-coding-master 0.9.5 → 0.9.6
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/README.md +10 -16
- package/dist/backend/adapters/claude-adapter.js +4 -5
- package/dist/backend/role-tool-policy.js +11 -10
- package/dist/backend/runtime/node-pty-runtime.js +39 -8
- package/dist/backend/server.js +0 -4
- package/dist/backend/services/gate-review-service.js +6 -2
- package/dist/backend/services/harness-service.js +6 -23
- package/dist/backend/services/session-service.js +2 -19
- package/dist/backend/services/workflow-control-service.js +9 -3
- package/dist/backend/templates/harness/architect-agent.js +8 -11
- package/dist/backend/templates/harness/architect-evidence-worker-agent.js +3 -3
- package/dist/backend/templates/harness/gate-review.js +29 -27
- package/dist/backend/templates/harness/project-manager-agent.js +2 -2
- package/dist/backend/templates/harness/vcm-code-navigation-skill.js +13 -9
- package/dist-frontend/assets/{index-CjM9OqZh.js → index-Bsd4k8YI.js} +35 -35
- package/dist-frontend/assets/{index-Bs4g_1yF.css → index-CRUqb0PX.css} +1 -1
- package/dist-frontend/index.html +2 -2
- package/package.json +1 -1
- package/scripts/verify-package.mjs +0 -2
- package/dist/backend/services/code-intelligence-service.js +0 -255
- package/dist/backend/services/lsp-plugin.js +0 -64
- package/scripts/claude-plugins/vcm-lsp-bridge/.claude-plugin/plugin.json +0 -88
- package/scripts/claude-plugins/vcm-lsp-bridge/vcm-lsp-proxy.mjs +0 -273
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
-
export { roleUsesLsp } from "../role-tool-policy.js";
|
|
4
|
-
export const VCM_LSP_PLUGIN_NAME = "vcm-lsp-bridge";
|
|
5
|
-
export const VCM_LSP_PLUGIN_DIR = fileURLToPath(new URL("../../../scripts/claude-plugins/vcm-lsp-bridge", import.meta.url));
|
|
6
|
-
export const VCM_LSP_PLUGIN_MANIFEST = path.join(VCM_LSP_PLUGIN_DIR, ".claude-plugin", "plugin.json");
|
|
7
|
-
export const VCM_LSP_PROXY_PATH = path.join(VCM_LSP_PLUGIN_DIR, "vcm-lsp-proxy.mjs");
|
|
8
|
-
export async function prepareTaskLspPlugin(fs, taskRepoRoot, status) {
|
|
9
|
-
const runnable = status.languages.filter((language) => language.state === "server_runnable");
|
|
10
|
-
if (runnable.length === 0)
|
|
11
|
-
return [];
|
|
12
|
-
const manifest = await fs.readJson(VCM_LSP_PLUGIN_MANIFEST);
|
|
13
|
-
const commands = new Set(runnable.map((language) => language.serverCommand));
|
|
14
|
-
const lspServers = Object.fromEntries(Object.entries(manifest.lspServers)
|
|
15
|
-
.filter(([, server]) => commands.has(server.command))
|
|
16
|
-
.map(([name, server]) => [name, withReadinessProxy(server)]));
|
|
17
|
-
const pluginDir = path.join(taskRepoRoot, ".ai/vcm/lsp-plugin");
|
|
18
|
-
const pluginManifestPath = path.join(pluginDir, ".claude-plugin/plugin.json");
|
|
19
|
-
await fs.ensureDir(path.dirname(pluginManifestPath));
|
|
20
|
-
await fs.writeJsonAtomic(pluginManifestPath, { ...manifest, lspServers });
|
|
21
|
-
return [pluginDir];
|
|
22
|
-
}
|
|
23
|
-
// Runs the server behind vcm-lsp-proxy so navigation queries wait for indexing
|
|
24
|
-
// to finish, or fail explicitly, instead of returning partial or empty results.
|
|
25
|
-
function withReadinessProxy(server) {
|
|
26
|
-
return {
|
|
27
|
-
...server,
|
|
28
|
-
command: process.execPath,
|
|
29
|
-
args: [VCM_LSP_PROXY_PATH, "--", server.command, ...(server.args ?? [])]
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
export function lspUnavailableWarning(language) {
|
|
33
|
-
const installCommands = {
|
|
34
|
-
"rust-analyzer": "rustup component add rust-analyzer",
|
|
35
|
-
"typescript-language-server": "npm install -g typescript typescript-language-server",
|
|
36
|
-
"pyright-langserver": "npm install -g pyright",
|
|
37
|
-
"gopls": "go install golang.org/x/tools/gopls@latest"
|
|
38
|
-
};
|
|
39
|
-
const recovery = language.state === "plugin_missing"
|
|
40
|
-
? "Refresh the VCM Harness to restore the LSP plugin."
|
|
41
|
-
: `Install or repair ${language.serverCommand} in the environment running the VCM backend${installCommands[language.serverCommand] ? ` (${installCommands[language.serverCommand]})` : ""} and ensure it is executable on PATH.`;
|
|
42
|
-
return `LSP for ${language.label} is unavailable: ${language.error ?? `${language.serverCommand} is not runnable.`} ${recovery} Restart the LSP roles (Architect, Reviewer) after fixing the environment so VCM can detect and register the server again.`;
|
|
43
|
-
}
|
|
44
|
-
// Architect stops semantic work in an unavailable language; Reviewer completes
|
|
45
|
-
// the review and records those relationships as not LSP-verified.
|
|
46
|
-
export function renderLspNotice(status, role = "architect") {
|
|
47
|
-
if (status.languages.length === 0)
|
|
48
|
-
return undefined;
|
|
49
|
-
const available = status.languages.filter((language) => language.state === "server_runnable");
|
|
50
|
-
const unavailable = status.languages.filter((language) => language.state !== "server_runnable");
|
|
51
|
-
return [
|
|
52
|
-
"[VCM LSP Availability]",
|
|
53
|
-
`Registered language servers: ${available.map((language) => `${language.label} (${language.serverCommand})`).join(", ") || "none"}.`,
|
|
54
|
-
...(available.length > 0 ? [
|
|
55
|
-
"While a server is still indexing, VCM holds LSP queries until it is ready. A query that fails with \"Language server is still indexing\" did not return a result: retry it later or record the relationship as unresolved; never read the failure as an empty result."
|
|
56
|
-
] : []),
|
|
57
|
-
...unavailable.map(lspUnavailableWarning),
|
|
58
|
-
...(unavailable.length > 0 ? [
|
|
59
|
-
role === "reviewer"
|
|
60
|
-
? "For relationships in an unavailable language, complete the review by reading the complete candidate code, record each such relationship as not LSP-verified in the report, and name the missing server. Do not stop the review or treat text matches as verified relationships."
|
|
61
|
-
: "If your assignment requires a semantic query in an unavailable language, stop that work and report the environment prerequisite through the current communication channel. Do not substitute source text search or claim the relationship is verified. Continue only after the server is available."
|
|
62
|
-
] : [])
|
|
63
|
-
].join("\n");
|
|
64
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vcm-lsp-bridge",
|
|
3
|
-
"description": "VCM-managed Claude Code LSP bridge for supported project languages",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "VibeCodingMaster"
|
|
7
|
-
},
|
|
8
|
-
"lspServers": {
|
|
9
|
-
"rust-analyzer": {
|
|
10
|
-
"command": "rust-analyzer",
|
|
11
|
-
"extensionToLanguage": {
|
|
12
|
-
".rs": "rust"
|
|
13
|
-
},
|
|
14
|
-
"initializationOptions": {
|
|
15
|
-
"checkOnSave": false
|
|
16
|
-
},
|
|
17
|
-
"startupTimeout": 180000,
|
|
18
|
-
"restartOnCrash": true,
|
|
19
|
-
"maxRestarts": 3
|
|
20
|
-
},
|
|
21
|
-
"typescript": {
|
|
22
|
-
"command": "typescript-language-server",
|
|
23
|
-
"args": [
|
|
24
|
-
"--stdio"
|
|
25
|
-
],
|
|
26
|
-
"extensionToLanguage": {
|
|
27
|
-
".ts": "typescript",
|
|
28
|
-
".tsx": "typescriptreact",
|
|
29
|
-
".js": "javascript",
|
|
30
|
-
".jsx": "javascriptreact",
|
|
31
|
-
".mts": "typescript",
|
|
32
|
-
".cts": "typescript",
|
|
33
|
-
".mjs": "javascript",
|
|
34
|
-
".cjs": "javascript"
|
|
35
|
-
},
|
|
36
|
-
"restartOnCrash": true,
|
|
37
|
-
"maxRestarts": 3
|
|
38
|
-
},
|
|
39
|
-
"pyright": {
|
|
40
|
-
"command": "pyright-langserver",
|
|
41
|
-
"args": [
|
|
42
|
-
"--stdio"
|
|
43
|
-
],
|
|
44
|
-
"extensionToLanguage": {
|
|
45
|
-
".py": "python",
|
|
46
|
-
".pyi": "python"
|
|
47
|
-
},
|
|
48
|
-
"restartOnCrash": true,
|
|
49
|
-
"maxRestarts": 3
|
|
50
|
-
},
|
|
51
|
-
"gopls": {
|
|
52
|
-
"command": "gopls",
|
|
53
|
-
"extensionToLanguage": {
|
|
54
|
-
".go": "go"
|
|
55
|
-
},
|
|
56
|
-
"restartOnCrash": true,
|
|
57
|
-
"maxRestarts": 3
|
|
58
|
-
},
|
|
59
|
-
"clangd": {
|
|
60
|
-
"command": "clangd",
|
|
61
|
-
"args": [
|
|
62
|
-
"--background-index"
|
|
63
|
-
],
|
|
64
|
-
"extensionToLanguage": {
|
|
65
|
-
".c": "c",
|
|
66
|
-
".h": "c",
|
|
67
|
-
".cpp": "cpp",
|
|
68
|
-
".cc": "cpp",
|
|
69
|
-
".cxx": "cpp",
|
|
70
|
-
".hpp": "cpp",
|
|
71
|
-
".hxx": "cpp",
|
|
72
|
-
".C": "cpp",
|
|
73
|
-
".H": "cpp"
|
|
74
|
-
},
|
|
75
|
-
"restartOnCrash": true,
|
|
76
|
-
"maxRestarts": 3
|
|
77
|
-
},
|
|
78
|
-
"jdtls": {
|
|
79
|
-
"command": "jdtls",
|
|
80
|
-
"extensionToLanguage": {
|
|
81
|
-
".java": "java"
|
|
82
|
-
},
|
|
83
|
-
"startupTimeout": 120000,
|
|
84
|
-
"restartOnCrash": true,
|
|
85
|
-
"maxRestarts": 3
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Stdio proxy between Claude Code's LSP client and one language server.
|
|
3
|
-
//
|
|
4
|
-
// Usage: node vcm-lsp-proxy.mjs -- <server-command> [server-args...]
|
|
5
|
-
//
|
|
6
|
-
// A language server that is still loading or indexing answers navigation
|
|
7
|
-
// queries with partial or empty results, which reads as "no references".
|
|
8
|
-
// The proxy tracks the server's work-done progress (and rust-analyzer's
|
|
9
|
-
// quiescence status), holds navigation queries until the server is idle, and
|
|
10
|
-
// fails a query with an explicit "still indexing" error when the server does
|
|
11
|
-
// not become idle in time. Every other message passes through unchanged.
|
|
12
|
-
|
|
13
|
-
import { spawn } from "node:child_process";
|
|
14
|
-
import { realpathSync } from "node:fs";
|
|
15
|
-
import { fileURLToPath } from "node:url";
|
|
16
|
-
|
|
17
|
-
const NAVIGATION_METHODS = new Set([
|
|
18
|
-
"textDocument/definition",
|
|
19
|
-
"textDocument/declaration",
|
|
20
|
-
"textDocument/typeDefinition",
|
|
21
|
-
"textDocument/implementation",
|
|
22
|
-
"textDocument/references",
|
|
23
|
-
"textDocument/hover",
|
|
24
|
-
"textDocument/documentSymbol",
|
|
25
|
-
"textDocument/prepareCallHierarchy",
|
|
26
|
-
"callHierarchy/incomingCalls",
|
|
27
|
-
"callHierarchy/outgoingCalls",
|
|
28
|
-
"workspace/symbol"
|
|
29
|
-
]);
|
|
30
|
-
|
|
31
|
-
const READY_TIMEOUT_MS = positiveNumber(process.env.VCM_LSP_READY_TIMEOUT_MS, 180_000);
|
|
32
|
-
// Servers announce indexing shortly after "initialized"; a query sent before
|
|
33
|
-
// any progress appears waits this long for indexing to start.
|
|
34
|
-
const STARTUP_GRACE_MS = positiveNumber(process.env.VCM_LSP_STARTUP_GRACE_MS, 2_000);
|
|
35
|
-
const REQUEST_FAILED = -32803;
|
|
36
|
-
const REQUEST_CANCELLED = -32800;
|
|
37
|
-
|
|
38
|
-
function positiveNumber(raw, fallback) {
|
|
39
|
-
const value = Number(raw);
|
|
40
|
-
return Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Parses Content-Length framed JSON-RPC messages from a byte stream.
|
|
44
|
-
export function createMessageReader(onMessage) {
|
|
45
|
-
let buffer = Buffer.alloc(0);
|
|
46
|
-
return (chunk) => {
|
|
47
|
-
buffer = Buffer.concat([buffer, chunk]);
|
|
48
|
-
while (true) {
|
|
49
|
-
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
50
|
-
if (headerEnd < 0) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const header = buffer.subarray(0, headerEnd).toString("ascii");
|
|
54
|
-
const match = /content-length:\s*(\d+)/i.exec(header);
|
|
55
|
-
if (!match) {
|
|
56
|
-
// Unframed bytes cannot be routed; drop the header and resynchronize.
|
|
57
|
-
buffer = buffer.subarray(headerEnd + 4);
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
const length = Number(match[1]);
|
|
61
|
-
const bodyStart = headerEnd + 4;
|
|
62
|
-
if (buffer.length < bodyStart + length) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const body = buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
|
|
66
|
-
buffer = buffer.subarray(bodyStart + length);
|
|
67
|
-
onMessage(JSON.parse(body));
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function frameMessage(message) {
|
|
73
|
-
const body = Buffer.from(JSON.stringify(message), "utf8");
|
|
74
|
-
return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, "ascii"), body]);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Readiness state shared by both directions of the proxy.
|
|
78
|
-
export function createReadinessTracker(options = {}) {
|
|
79
|
-
const now = options.now ?? Date.now;
|
|
80
|
-
const activeProgress = new Map();
|
|
81
|
-
let quiescent = true;
|
|
82
|
-
let initializedAt;
|
|
83
|
-
let progressSeen = false;
|
|
84
|
-
const listeners = new Set();
|
|
85
|
-
|
|
86
|
-
function notify() {
|
|
87
|
-
for (const listener of [...listeners]) {
|
|
88
|
-
listener();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
markInitialized() {
|
|
94
|
-
initializedAt = now();
|
|
95
|
-
},
|
|
96
|
-
progressBegin(token, title) {
|
|
97
|
-
progressSeen = true;
|
|
98
|
-
activeProgress.set(String(token), title || "indexing");
|
|
99
|
-
notify();
|
|
100
|
-
},
|
|
101
|
-
progressEnd(token) {
|
|
102
|
-
activeProgress.delete(String(token));
|
|
103
|
-
notify();
|
|
104
|
-
},
|
|
105
|
-
serverStatus(isQuiescent) {
|
|
106
|
-
progressSeen = true;
|
|
107
|
-
quiescent = isQuiescent;
|
|
108
|
-
notify();
|
|
109
|
-
},
|
|
110
|
-
// Remaining startup grace in ms, or 0 once it no longer applies.
|
|
111
|
-
graceRemaining() {
|
|
112
|
-
if (progressSeen || initializedAt === undefined) {
|
|
113
|
-
return 0;
|
|
114
|
-
}
|
|
115
|
-
return Math.max(0, initializedAt + (options.startupGraceMs ?? STARTUP_GRACE_MS) - now());
|
|
116
|
-
},
|
|
117
|
-
isBusy() {
|
|
118
|
-
return activeProgress.size > 0 || !quiescent;
|
|
119
|
-
},
|
|
120
|
-
busyReason() {
|
|
121
|
-
const titles = [...new Set(activeProgress.values())];
|
|
122
|
-
if (!quiescent) {
|
|
123
|
-
titles.push("server not quiescent");
|
|
124
|
-
}
|
|
125
|
-
return titles.join(", ") || "starting up";
|
|
126
|
-
},
|
|
127
|
-
onChange(listener) {
|
|
128
|
-
listeners.add(listener);
|
|
129
|
-
return () => listeners.delete(listener);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export function startProxy({ command, args, input, output, errorOutput, readyTimeoutMs = READY_TIMEOUT_MS, startupGraceMs = STARTUP_GRACE_MS }) {
|
|
135
|
-
const server = spawn(command, args, { stdio: ["pipe", "pipe", "pipe"] });
|
|
136
|
-
const readiness = createReadinessTracker({ startupGraceMs });
|
|
137
|
-
const pending = new Map();
|
|
138
|
-
let clientWantsProgress = false;
|
|
139
|
-
let clientWantsServerStatus = false;
|
|
140
|
-
|
|
141
|
-
const toClient = (message) => output.write(frameMessage(message));
|
|
142
|
-
const toServer = (message) => {
|
|
143
|
-
if (server.stdin.writable) {
|
|
144
|
-
server.stdin.write(frameMessage(message));
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
server.stderr.pipe(errorOutput);
|
|
149
|
-
server.on("error", (error) => {
|
|
150
|
-
errorOutput.write(`vcm-lsp-proxy: cannot start ${command}: ${error.message}\n`);
|
|
151
|
-
process.exitCode = 1;
|
|
152
|
-
output.end?.();
|
|
153
|
-
});
|
|
154
|
-
server.on("exit", (code, signal) => {
|
|
155
|
-
for (const entry of pending.values()) {
|
|
156
|
-
entry.dispose();
|
|
157
|
-
}
|
|
158
|
-
process.exitCode = code ?? (signal ? 1 : 0);
|
|
159
|
-
output.end?.();
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
function releaseWhenReady(message) {
|
|
163
|
-
const key = String(message.id);
|
|
164
|
-
let timer;
|
|
165
|
-
let graceTimer;
|
|
166
|
-
let unsubscribe = () => undefined;
|
|
167
|
-
const dispose = () => {
|
|
168
|
-
clearTimeout(timer);
|
|
169
|
-
clearTimeout(graceTimer);
|
|
170
|
-
unsubscribe();
|
|
171
|
-
pending.delete(key);
|
|
172
|
-
};
|
|
173
|
-
const attempt = () => {
|
|
174
|
-
const grace = readiness.graceRemaining();
|
|
175
|
-
if (grace > 0) {
|
|
176
|
-
clearTimeout(graceTimer);
|
|
177
|
-
graceTimer = setTimeout(attempt, grace);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
if (!readiness.isBusy()) {
|
|
181
|
-
dispose();
|
|
182
|
-
toServer(message);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
pending.set(key, {
|
|
186
|
-
dispose,
|
|
187
|
-
cancel() {
|
|
188
|
-
dispose();
|
|
189
|
-
toClient({ jsonrpc: "2.0", id: message.id, error: { code: REQUEST_CANCELLED, message: "Request cancelled." } });
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
unsubscribe = readiness.onChange(attempt);
|
|
193
|
-
timer = setTimeout(() => {
|
|
194
|
-
dispose();
|
|
195
|
-
toClient({
|
|
196
|
-
jsonrpc: "2.0",
|
|
197
|
-
id: message.id,
|
|
198
|
-
error: {
|
|
199
|
-
code: REQUEST_FAILED,
|
|
200
|
-
message: `Language server is still indexing (${readiness.busyReason()}) after ${Math.round(readyTimeoutMs / 1000)}s; ${message.method} results would be incomplete. Retry after indexing finishes, or record the relationship as unresolved.`
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
}, readyTimeoutMs);
|
|
204
|
-
attempt();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
input.on("data", createMessageReader((message) => {
|
|
208
|
-
if (message.method === "initialize" && message.params) {
|
|
209
|
-
const capabilities = message.params.capabilities ?? {};
|
|
210
|
-
clientWantsProgress = capabilities.window?.workDoneProgress === true;
|
|
211
|
-
clientWantsServerStatus = capabilities.experimental?.serverStatusNotification === true;
|
|
212
|
-
message.params.capabilities = {
|
|
213
|
-
...capabilities,
|
|
214
|
-
window: { ...capabilities.window, workDoneProgress: true },
|
|
215
|
-
experimental: { ...capabilities.experimental, serverStatusNotification: true }
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
if (message.method === "initialized") {
|
|
219
|
-
readiness.markInitialized();
|
|
220
|
-
}
|
|
221
|
-
if (message.method === "$/cancelRequest" && pending.has(String(message.params?.id))) {
|
|
222
|
-
pending.get(String(message.params.id)).cancel();
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
if (message.id !== undefined && NAVIGATION_METHODS.has(message.method)) {
|
|
226
|
-
releaseWhenReady(message);
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
toServer(message);
|
|
230
|
-
}));
|
|
231
|
-
input.on("end", () => server.stdin.end());
|
|
232
|
-
|
|
233
|
-
server.stdout.on("data", createMessageReader((message) => {
|
|
234
|
-
if (message.method === "window/workDoneProgress/create") {
|
|
235
|
-
if (!clientWantsProgress) {
|
|
236
|
-
toServer({ jsonrpc: "2.0", id: message.id, result: null });
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
} else if (message.method === "$/progress") {
|
|
240
|
-
const value = message.params?.value;
|
|
241
|
-
if (value?.kind === "begin") {
|
|
242
|
-
readiness.progressBegin(message.params.token, value.title);
|
|
243
|
-
} else if (value?.kind === "end") {
|
|
244
|
-
readiness.progressEnd(message.params.token);
|
|
245
|
-
}
|
|
246
|
-
if (!clientWantsProgress) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
} else if (message.method === "experimental/serverStatus") {
|
|
250
|
-
readiness.serverStatus(message.params?.quiescent !== false);
|
|
251
|
-
if (!clientWantsServerStatus) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
toClient(message);
|
|
256
|
-
}));
|
|
257
|
-
|
|
258
|
-
return { server, readiness };
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const separator = process.argv.indexOf("--");
|
|
262
|
-
if (separator >= 0 && process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
263
|
-
const [command, ...args] = process.argv.slice(separator + 1);
|
|
264
|
-
if (!command) {
|
|
265
|
-
process.stderr.write("usage: vcm-lsp-proxy.mjs -- <server-command> [args...]\n");
|
|
266
|
-
process.exit(2);
|
|
267
|
-
}
|
|
268
|
-
const { server } = startProxy({ command, args, input: process.stdin, output: process.stdout, errorOutput: process.stderr });
|
|
269
|
-
// Exit with the server so Claude Code sees the crash and restarts it; an open
|
|
270
|
-
// stdin would otherwise keep the proxy alive with no server behind it.
|
|
271
|
-
server.on("exit", (code, signal) => process.exit(code ?? (signal ? 1 : 0)));
|
|
272
|
-
server.on("error", () => process.exit(1));
|
|
273
|
-
}
|