Skip to content

Commit 660f088

Browse files
committed
feat: implement background execution for Claude CLI install and enhance error handling
1 parent a5322e3 commit 660f088

File tree

1 file changed

+72
-17
lines changed

1 file changed

+72
-17
lines changed

src/panels/ExtensionPanel.ts

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as vscode from "vscode";
22
import { getNonce } from "../utilities/getNonce";
33
import { getUri } from "../utilities/getUri";
44
import { searchMcpServers2 } from "../utilities/repoSearch";
5-
import { type TelemetryReporter } from "@vscode/extension-telemetry";
65
import { openMcpInstallUri, readmeExtractionRequest } from "../McpAgent";
76
import {
87
logWebviewSearch,
@@ -41,7 +40,7 @@ import type {
4140
import axios from "axios";
4241
import { outputLogger } from "../utilities/outputLogger";
4342
import { GITHUB_AUTH_PROVIDER_ID, SCOPES } from "../utilities/const";
44-
43+
import { spawn } from "node:child_process";
4544
// Helper function to read servers from .vscode/mcp.json
4645
async function getServersFromMcpJsonFile(
4746
folder: vscode.WorkspaceFolder
@@ -203,26 +202,82 @@ async function runClaudeCliTask(
203202
const configJson = JSON.stringify(config);
204203
outputLogger.info("Config", config);
205204

206-
const shellExecution = vscode.window.createTerminal({
207-
name: `Claude MCP Install (${name})`,
208-
});
209-
210-
shellExecution.show();
211-
const command = `${claudeBinary} mcp add-json ${name} '${configJson}'`;
212-
shellExecution.sendText(command);
205+
const commandArgs = ["mcp", "add-json", name, configJson];
206+
const clipboardCommand = `${claudeBinary} mcp add-json ${JSON.stringify(name)} ${JSON.stringify(configJson)}`;
213207

214208
void vscode.window.showInformationMessage(
215-
"Claude CLI install started. See Terminal Output for progress.",
209+
"Claude Code install started. Running command in the background...",
216210
);
217211

218-
try {
219-
await vscode.env.clipboard.writeText(command);
220-
void vscode.window.showInformationMessage(
221-
"Claude CLI command copied to your clipboard in case you need to rerun it if the install fails.",
222-
);
223-
} catch (clipboardError) {
224-
outputLogger.warn("Failed to copy Claude CLI command to clipboard", clipboardError);
212+
const pathSeparator = process.platform === "win32" ? ";" : ":";
213+
const basePath = process.env.PATH ?? "";
214+
const pathEntries = basePath.split(pathSeparator).filter(Boolean);
215+
if (process.platform === "darwin") {
216+
for (const candidate of ["/opt/homebrew/bin", "/usr/local/bin"]) {
217+
if (!pathEntries.includes(candidate)) {
218+
pathEntries.unshift(candidate);
219+
}
220+
}
225221
}
222+
const env = {
223+
...process.env,
224+
PATH: pathEntries.join(pathSeparator),
225+
};
226+
227+
let stdout = "";
228+
let stderr = "";
229+
230+
await new Promise<void>((resolve, reject) => {
231+
const child = spawn(claudeBinary, commandArgs, { env });
232+
233+
if (child.stdout) {
234+
child.stdout.on("data", (chunk: Buffer) => {
235+
stdout += chunk.toString();
236+
});
237+
}
238+
239+
if (child.stderr) {
240+
child.stderr.on("data", (chunk: Buffer) => {
241+
stderr += chunk.toString();
242+
});
243+
}
244+
245+
child.on("error", (error) => {
246+
outputLogger.error("Failed to start Claude CLI", error);
247+
reject(error);
248+
});
249+
250+
child.on("close", async (code) => {
251+
const messageParts: string[] = [];
252+
messageParts.push(`Claude CLI exited with code ${code ?? "unknown"}.`);
253+
if (stdout.trim()) {
254+
messageParts.push(`\n${stdout.trim()}`);
255+
}
256+
if (stderr.trim()) {
257+
messageParts.push(`\n${stderr.trim()}`);
258+
}
259+
260+
if (code === 0) {
261+
void vscode.window.showInformationMessage(messageParts.join("\n\n"));
262+
resolve();
263+
} else {
264+
try {
265+
const selectedAction = await vscode.window.showInformationMessage(messageParts.join("\n\n"), "Copy Command to Clipboard");
266+
if (selectedAction === "Copy Command to Clipboard") {
267+
await vscode.env.clipboard.writeText(clipboardCommand);
268+
void vscode.window.showInformationMessage(
269+
"Claude Code MCP install command copied to your clipboard for manual install.",
270+
);
271+
}
272+
} catch (clipboardError) {
273+
outputLogger.warn("Failed to copy Claude CLI command to clipboard", clipboardError);
274+
}
275+
const error = new Error(`Claude CLI exited with code ${code}`);
276+
outputLogger.error("Claude CLI exited with non-zero code", error, { stdout, stderr });
277+
reject(error);
278+
}
279+
});
280+
});
226281
}
227282

228283

0 commit comments

Comments
 (0)