Skip to content

Commit 27a8248

Browse files
committed
fix(server): support Windows provider paths with spaces
Run Windows provider probes through a shell command string so custom binary paths containing spaces are quoted the way cmd.exe expects.
1 parent c66a714 commit 27a8248

3 files changed

Lines changed: 28 additions & 21 deletions

File tree

apps/server/src/provider/Layers/ProviderRegistry.test.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,11 @@ function unwrapWindowsProviderCommand(
4646
command: string,
4747
args: ReadonlyArray<string>,
4848
): { command: string; args: ReadonlyArray<string> } {
49-
const comSpec = process.env.ComSpec ?? "cmd.exe";
50-
if (command !== comSpec || args.length !== 5) {
49+
if (args.length > 0) {
5150
return { command, args };
5251
}
5352

54-
const [u, d, s, c, shellCommand] = args;
55-
if (u !== "/u" || d !== "/d" || s !== "/s" || c !== "/c") {
56-
return { command, args };
57-
}
58-
59-
if (!shellCommand) {
60-
return { command, args };
61-
}
62-
63-
const parts = shellCommand.split(" ");
53+
const parts = command.split(" ");
6454
return {
6555
command: parts[0] ?? command,
6656
args: parts.slice(1),

apps/server/src/provider/providerSnapshot.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { Effect, Stream } from "effect";
22
import { afterEach, describe, expect, it, vi } from "vitest";
33

4-
import { collectStreamAsString, quoteWindowsShellArgument } from "./providerSnapshot";
4+
import {
5+
collectStreamAsString,
6+
makeProviderCommand,
7+
quoteWindowsShellArgument,
8+
} from "./providerSnapshot";
59

610
afterEach(() => {
711
vi.unstubAllGlobals();
@@ -44,3 +48,20 @@ describe("quoteWindowsShellArgument", () => {
4448
);
4549
});
4650
});
51+
52+
describe("makeProviderCommand", () => {
53+
it("uses a shell command string for Windows paths with spaces", () => {
54+
vi.stubGlobal("process", { ...process, platform: "win32" });
55+
56+
const command = makeProviderCommand("C:\\Program Files\\Codex\\codex.exe", ["--version"]);
57+
const resolved = command as unknown as {
58+
command: string;
59+
args: ReadonlyArray<string>;
60+
options: { shell?: boolean };
61+
};
62+
63+
expect(resolved.command).toBe('"C:\\Program Files\\Codex\\codex.exe" --version');
64+
expect(resolved.args).toEqual([]);
65+
expect(resolved.options.shell).toBe(true);
66+
});
67+
});

apps/server/src/provider/providerSnapshot.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,10 @@ export function makeProviderCommand(
7070
...args.map(quoteWindowsShellArgument),
7171
].join(" ");
7272

73-
return ChildProcess.make(
74-
process.env.ComSpec ?? "cmd.exe",
75-
["/u", "/d", "/s", "/c", shellCommand],
76-
{
77-
shell: false,
78-
env: options?.env,
79-
},
80-
);
73+
return ChildProcess.make(shellCommand, [], {
74+
shell: true,
75+
env: options?.env,
76+
});
8177
}
8278

8379
function decodeProcessOutput(output: Uint8Array): string {

0 commit comments

Comments
 (0)