fix(claude-code): use native Windows claude lookup

This commit is contained in:
mastertyko 2026-04-08 09:12:53 +02:00
parent 66a824a8b8
commit 120949db19
2 changed files with 30 additions and 3 deletions

View file

@ -50,6 +50,17 @@ function createAssistantStream(): AssistantMessageEventStream {
let cachedClaudePath: string | null = null;
export function getClaudeLookupCommand(platform: NodeJS.Platform = process.platform): string {
return platform === "win32" ? "where claude" : "which claude";
}
export function parseClaudeLookupOutput(output: Buffer | string): string {
return output
.toString()
.trim()
.split(/\r?\n/)[0] ?? "";
}
/**
* Resolve the path to the system-installed `claude` binary.
* The SDK defaults to a bundled cli.js which doesn't exist when
@ -58,9 +69,7 @@ let cachedClaudePath: string | null = null;
function getClaudePath(): string {
if (cachedClaudePath) return cachedClaudePath;
try {
cachedClaudePath = execSync("which claude", { timeout: 5_000, stdio: "pipe" })
.toString()
.trim();
cachedClaudePath = parseClaudeLookupOutput(execSync(getClaudeLookupCommand(), { timeout: 5_000, stdio: "pipe" }));
} catch {
cachedClaudePath = "claude"; // fall back to PATH resolution
}

View file

@ -4,6 +4,8 @@ import {
makeStreamExhaustedErrorMessage,
buildPromptFromContext,
buildSdkOptions,
getClaudeLookupCommand,
parseClaudeLookupOutput,
} from "../stream-adapter.ts";
import type { Context, Message } from "@gsd/pi-ai";
@ -126,3 +128,19 @@ describe("stream-adapter — session persistence (#2859)", () => {
);
});
});
describe("stream-adapter — Windows Claude path lookup (#3770)", () => {
test("getClaudeLookupCommand uses where on Windows", () => {
assert.equal(getClaudeLookupCommand("win32"), "where claude");
});
test("getClaudeLookupCommand uses which on non-Windows platforms", () => {
assert.equal(getClaudeLookupCommand("darwin"), "which claude");
assert.equal(getClaudeLookupCommand("linux"), "which claude");
});
test("parseClaudeLookupOutput keeps the first native path from multi-line lookup output", () => {
const output = "C:\\Users\\Binoy\\.local\\bin\\claude.exe\r\nC:\\Program Files\\Claude\\claude.exe\r\n";
assert.equal(parseClaudeLookupOutput(output), "C:\\Users\\Binoy\\.local\\bin\\claude.exe");
});
});