authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-04 15:25:46-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-04 15:25:46-07:00
log300f7fd11d61704617119634a99563e16c0e6913
treebf12b09e5ad47747ee5189b3c9af967f537e6011
parent53042f47f85a986257573773d9854cf59b957514
signature Signed by PGP key B5690EEEBB952194

[codex] Avoid shell for system executables (#2950)

Co-authored-by: Julius Marminge <julius@mac.lan>

8 files changed, 10 insertions(+), 23 deletions(-)

apps/server/src/diagnostics/ProcessDiagnostics.ts-1
......@@ -280,7 +280,6 @@ const runProcess = Effect.fn("runProcess")(
280280 const child = yield* spawner.spawn(
281281 ChildProcess.make(input.command, input.args, {
282282 cwd: process.cwd(),
283 shell: process.platform === "win32",
284283 }),
285284 );
286285 const [stdout, stderr, exitCode] = yield* Effect.all(
apps/server/src/environment/Layers/ServerEnvironmentLabel.ts-1
......@@ -59,7 +59,6 @@ const runFriendlyLabelCommand = Effect.fn("runFriendlyLabelCommand")(function* (
5959 command,
6060 args,
6161 timeoutBehavior: "timedOutResult",
62 shell: process.platform === "win32",
6362 })
6463 .pipe(Effect.option);
6564
apps/server/src/project/Layers/RepositoryIdentityResolver.test.ts-1
......@@ -23,7 +23,6 @@ const git = (cwd: string, args: ReadonlyArray<string>) =>
2323 return yield* processRunner.run({
2424 command: "git",
2525 args: ["-C", cwd, ...args],
26 shell: process.platform === "win32",
2726 });
2827 }).pipe(Effect.provide(ProcessRunner.layer));
2928
apps/server/src/project/Layers/RepositoryIdentityResolver.ts-2
......@@ -94,7 +94,6 @@ const resolveRepositoryIdentityCacheKey = Effect.fn("resolveRepositoryIdentityCa
9494 command: "git",
9595 args: ["-C", cwd, "rev-parse", "--show-toplevel"],
9696 timeoutBehavior: "timedOutResult",
97 shell: process.platform === "win32",
9897 })
9998 .pipe(Effect.option);
10099 if (topLevelResult._tag === "None" || topLevelResult.value.code !== 0) {
......@@ -119,7 +118,6 @@ const resolveRepositoryIdentityFromCacheKey = Effect.fn("resolveRepositoryIdenti
119118 command: "git",
120119 args: ["-C", cacheKey, "remote", "-v"],
121120 timeoutBehavior: "timedOutResult",
122 shell: process.platform === "win32",
123121 })
124122 .pipe(Effect.option);
125123 if (remoteResult._tag === "None" || remoteResult.value.code !== 0) {
apps/server/src/terminal/Layers/Manager.ts-1
......@@ -519,7 +519,6 @@ function windowsInspectSubprocess(
519519 timeout: "1500 millis",
520520 maxOutputBytes: 32_768,
521521 outputMode: "truncate",
522 shell: process.platform === "win32",
523522 timeoutBehavior: "timedOutResult",
524523 });
525524 }).pipe(
packages/ssh/src/command.ts+4-4
......@@ -16,6 +16,7 @@ import { SshCommandError, SshInvalidTargetError } from "./errors.ts";
1616const PUBLISHABLE_T3_VERSION_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u;
1717const DEFAULT_SSH_COMMAND_TIMEOUT_MS = 60_000;
1818const MAX_SSH_ERROR_OUTPUT_LENGTH = 4_000;
19export const SSH_COMMAND = process.platform === "win32" ? "ssh.exe" : "ssh";
1920
2021const encoder = new TextEncoder();
2122
......@@ -192,15 +193,14 @@ const runSshCommandInScope = Effect.fn("ssh/command.runSshCommand.inScope")(func
192193 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
193194 yield* Effect.logDebug("ssh.command.start", {
194195 ...sshTargetLogFields(target),
195 command: ["ssh", ...args],
196 command: [SSH_COMMAND, ...args],
196197 hasStdin: input.stdin !== undefined,
197198 timeoutMs: input.timeoutMs ?? DEFAULT_SSH_COMMAND_TIMEOUT_MS,
198199 });
199200 const child = yield* spawner
200201 .spawn(
201 ChildProcess.make("ssh", args, {
202 ChildProcess.make(SSH_COMMAND, args, {
202203 env: environment,
203 shell: process.platform === "win32",
204204 stdin: {
205205 stream: stdinStream(input.stdin),
206206 endOnDone: true,
......@@ -212,7 +212,7 @@ const runSshCommandInScope = Effect.fn("ssh/command.runSshCommand.inScope")(func
212212 Effect.mapError(
213213 (cause) =>
214214 new SshCommandError({
215 command: ["ssh", ...args],
215 command: [SSH_COMMAND, ...args],
216216 exitCode: null,
217217 stderr: "",
218218 message:
packages/ssh/src/tunnel.ts+3-3
......@@ -36,6 +36,7 @@ import {
3636 remoteStateKey,
3737 resolveSshTarget,
3838 runSshCommand,
39 SSH_COMMAND,
3940 targetConnectionKey,
4041} from "./command.ts";
4142import {
......@@ -1068,7 +1069,7 @@ const startSshTunnel = Effect.fn("ssh/tunnel.startSshTunnel")(function* (input:
10681069 `${input.localPort}:127.0.0.1:${input.remotePort}`,
10691070 hostSpec,
10701071 ];
1071 const tunnelCommand = ["ssh", ...args];
1072 const tunnelCommand = [SSH_COMMAND, ...args];
10721073 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
10731074 const scope = yield* Scope.Scope;
10741075 yield* Effect.logDebug("ssh.tunnel.spawn.start", {
......@@ -1081,9 +1082,8 @@ const startSshTunnel = Effect.fn("ssh/tunnel.startSshTunnel")(function* (input:
10811082 });
10821083 const child = yield* spawner
10831084 .spawn(
1084 ChildProcess.make("ssh", args, {
1085 ChildProcess.make(SSH_COMMAND, args, {
10851086 env: childEnvironment,
1086 shell: process.platform === "win32",
10871087 stdin: {
10881088 stream: Stream.empty,
10891089 endOnDone: true,
packages/tailscale/src/tailscale.ts+3-10
......@@ -10,6 +10,7 @@ export const DEFAULT_TAILSCALE_SERVE_PORT = 443;
1010export const TAILSCALE_STATUS_TIMEOUT_MS = 1_500;
1111export const TAILSCALE_SERVE_TIMEOUT_MS = 10_000;
1212export const TAILSCALE_PROBE_TIMEOUT_MS = 2_500;
13const TAILSCALE_COMMAND = process.platform === "win32" ? "tailscale.exe" : "tailscale";
1314
1415export class TailscaleCommandError extends Data.TaggedError("TailscaleCommandError")<{
1516 readonly command: readonly string[];
......@@ -136,11 +137,7 @@ export const readTailscaleStatus: Effect.Effect<
136137 const args = ["status", "--json"];
137138 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
138139 const child = yield* spawner
139 .spawn(
140 ChildProcess.make("tailscale", args, {
141 shell: process.platform === "win32",
142 }),
143 )
140 .spawn(ChildProcess.make(TAILSCALE_COMMAND, args))
144141 .pipe(
145142 Effect.mapError((cause) =>
146143 tailscaleCommandError(
......@@ -215,11 +212,7 @@ const runTailscaleCommand = (
215212 Effect.gen(function* () {
216213 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
217214 const child = yield* spawner
218 .spawn(
219 ChildProcess.make("tailscale", args, {
220 shell: process.platform === "win32",
221 }),
222 )
215 .spawn(ChildProcess.make(TAILSCALE_COMMAND, args))
223216 .pipe(
224217 Effect.mapError((cause) =>
225218 tailscaleCommandError(