fix(vscode): support Remote SSH by adding extensionKind and error handler (#2650)

* fix(vscode): add extensionKind and error handler for Remote SSH support

* fix(vscode): reject failed RPC startup
This commit is contained in:
Jeremy McSpadden 2026-03-26 09:14:08 -05:00 committed by GitHub
parent f0e727d369
commit af7da35384
2 changed files with 57 additions and 7 deletions

View file

@ -29,6 +29,7 @@
"color": "#1a1a2e",
"theme": "dark"
},
"extensionKind": ["workspace"],
"engines": {
"vscode": "^1.95.0"
},

View file

@ -118,28 +118,78 @@ export class GsdClient implements vscode.Disposable {
return;
}
this.process = spawn(this.binaryPath, ["--mode", "rpc", "--no-session"], {
const proc = spawn(this.binaryPath, ["--mode", "rpc", "--no-session"], {
cwd: this.cwd,
stdio: ["pipe", "pipe", "pipe"],
env: { ...process.env },
});
this.process = proc;
this.buffer = "";
this.process.stdout?.on("data", (chunk: Buffer) => {
proc.stdout?.on("data", (chunk: Buffer) => {
this.buffer += chunk.toString("utf8");
this.drainBuffer();
});
this.process.stderr?.on("data", (chunk: Buffer) => {
proc.stderr?.on("data", (chunk: Buffer) => {
const text = chunk.toString("utf8").trim();
if (text) {
this._onError.fire(text);
}
});
this.process.on("exit", (code, signal) => {
this.process = null;
let startupSettled = false;
const startupResult = new Promise<void>((resolve, reject) => {
const cleanup = () => {
proc.off("spawn", handleSpawn);
proc.off("error", handleStartupError);
};
const handleSpawn = () => {
if (startupSettled) return;
startupSettled = true;
cleanup();
this._onConnectionChange.fire(true);
this.restartCount = 0;
resolve();
};
const handleStartupError = (err: NodeJS.ErrnoException) => {
if (startupSettled) return;
startupSettled = true;
cleanup();
if (this.process === proc) {
this.process = null;
}
const hint = err.code === "ENOENT"
? ` Make sure GSD is installed ("npm install -g gsd-pi") and set "gsd.binaryPath" to the absolute path if it is not on PATH.`
: "";
const message = `Failed to start GSD process: ${err.message}.${hint}`;
this._onError.fire(message);
reject(new Error(message));
};
proc.once("spawn", handleSpawn);
proc.once("error", handleStartupError);
});
proc.on("error", (err: NodeJS.ErrnoException) => {
if (!startupSettled) {
return;
}
if (this.process === proc) {
this.process = null;
}
this._onConnectionChange.fire(false);
const hint = err.code === "ENOENT"
? ` Make sure GSD is installed ("npm install -g gsd-pi") and set "gsd.binaryPath" to the absolute path if it is not on PATH.`
: "";
this._onError.fire(`GSD process error: ${err.message}.${hint}`);
});
proc.on("exit", (code, signal) => {
if (this.process === proc) {
this.process = null;
}
this.rejectAllPending(`GSD process exited (code=${code}, signal=${signal})`);
this._onConnectionChange.fire(false);
@ -161,8 +211,7 @@ export class GsdClient implements vscode.Disposable {
}
});
this._onConnectionChange.fire(true);
this.restartCount = 0;
await startupResult;
}
/**