Skip to content

Commit 792e346

Browse files
committed
fix: quote bash path and validate SSH cwd in spawnBackground
- Quote bash path in buildSpawnCommand to handle Windows paths with spaces (e.g., C:\Program Files\Git\bin\bash.exe) - Add cwd validation to SSH spawnBackground (parity with local runtime) - Add test for bash paths with spaces
1 parent 42b7338 commit 792e346

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

src/node/runtime/SSHRuntime.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ export class SSHRuntime implements Runtime {
282282
): Promise<BackgroundSpawnResult> {
283283
log.debug(`SSHRuntime.spawnBackground: Spawning in ${options.cwd}`);
284284

285+
// Verify working directory exists on remote (parity with local runtime)
286+
const cwdCheck = await execBuffered(this, cdCommandForSSH(options.cwd), {
287+
cwd: "/",
288+
timeout: 10,
289+
});
290+
if (cwdCheck.exitCode !== 0) {
291+
return { success: false, error: `Working directory does not exist: ${options.cwd}` };
292+
}
293+
285294
// Generate unique process ID and compute output directory
286295
// /tmp is cleaned by OS, so no explicit cleanup needed
287296
const processId = `bg-${randomBytes(4).toString("hex")}`;

src/node/runtime/backgroundCommands.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ describe("backgroundCommands", () => {
110110
stderrPath: "/tmp/stderr.log",
111111
});
112112

113-
expect(result).toMatch(/^\(setsid nohup bash -c /);
113+
// bash path is quoted to handle paths with spaces (e.g., Windows Git Bash)
114+
expect(result).toMatch(/^\(setsid nohup 'bash' -c /);
114115
});
115116

116117
it("should include niceness prefix when provided", () => {
@@ -142,7 +143,20 @@ describe("backgroundCommands", () => {
142143
bashPath: "/usr/local/bin/bash",
143144
});
144145

145-
expect(result).toContain("/usr/local/bin/bash -c");
146+
// bash path is quoted
147+
expect(result).toContain("'/usr/local/bin/bash' -c");
148+
});
149+
150+
it("should handle bash path with spaces (Windows Git Bash)", () => {
151+
const result = buildSpawnCommand({
152+
wrapperScript: "echo hello",
153+
stdoutPath: "/tmp/stdout.log",
154+
stderrPath: "/tmp/stderr.log",
155+
bashPath: "/c/Program Files/Git/bin/bash.exe",
156+
});
157+
158+
// Path with spaces must be quoted to work correctly
159+
expect(result).toContain("'/c/Program Files/Git/bin/bash.exe' -c");
146160
});
147161

148162
it("should redirect stdout and stderr", () => {

src/node/runtime/backgroundCommands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function buildSpawnCommand(options: SpawnCommandOptions): string {
103103
const quotePath = options.quotePath ?? shellQuote;
104104

105105
return (
106-
`(${nicePrefix}${setsidPrefix}nohup ${bash} -c ${shellQuote(options.wrapperScript)} ` +
106+
`(${nicePrefix}${setsidPrefix}nohup ${shellQuote(bash)} -c ${shellQuote(options.wrapperScript)} ` +
107107
`> ${quotePath(options.stdoutPath)} ` +
108108
`2> ${quotePath(options.stderrPath)} ` +
109109
`< /dev/null & echo $!)`

0 commit comments

Comments
 (0)