From 0a1233344896376ec8b31b79ee65500eeef3a09e Mon Sep 17 00:00:00 2001 From: julius Date: Wed, 4 Mar 2026 04:14:42 -0800 Subject: [PATCH] Fix Codex process spawning and health checks on Windows - Run Codex-related child processes with `shell` on Windows for reliable command execution - Switch provider auth probe to `codex login status` and update health-check expectations - Use Node PTY on Windows instead of Bun PTY in server runtime setup --- apps/server/src/codexAppServerManager.ts | 1 + .../src/git/Layers/CodexTextGeneration.ts | 1 + apps/server/src/open.ts | 1 + apps/server/src/processRunner.ts | 1 + .../provider/Layers/ProviderHealth.test.ts | 45 +++++-------------- .../src/provider/Layers/ProviderHealth.ts | 2 +- apps/server/src/serverLayers.ts | 6 ++- 7 files changed, 20 insertions(+), 37 deletions(-) diff --git a/apps/server/src/codexAppServerManager.ts b/apps/server/src/codexAppServerManager.ts index cb50a302f9389101cd940fc56d460c321e51d10a..b197a07fd447a54fd553ad089a4715c1114cd840 100644 --- a/apps/server/src/codexAppServerManager.ts +++ b/apps/server/src/codexAppServerManager.ts @@ -185,6 +185,7 @@ export class CodexAppServerManager extends EventEmitter child = spawn(launch.command, [...launch.args], { detached: true, stdio: "ignore", + shell: process.platform === "win32", }); } catch (error) { return resume( diff --git a/apps/server/src/processRunner.ts b/apps/server/src/processRunner.ts index 858da5ae3f4279f2334ae50976df77e339122cf7..75c939617f160135759ca10f6a1752eda00b441a 100644 --- a/apps/server/src/processRunner.ts +++ b/apps/server/src/processRunner.ts @@ -112,6 +112,7 @@ export async function runProcess( cwd: options.cwd, env: options.env, stdio: "pipe", + shell: process.platform === "win32", }); let stdout = ""; diff --git a/apps/server/src/provider/Layers/ProviderHealth.test.ts b/apps/server/src/provider/Layers/ProviderHealth.test.ts index b75c358baa0e7d8bfa5dcfd8ea3520c7158daf7f..2c8efd9253b894d99df6ffbdde47491ec6b9459f 100644 --- a/apps/server/src/provider/Layers/ProviderHealth.test.ts +++ b/apps/server/src/provider/Layers/ProviderHealth.test.ts @@ -22,8 +22,8 @@ describe("checkProviderStatusesOnStartup", () => { if (args.join(" ") === "--version") { return result({ stdout: "codex 1.0.0\n" }); } - if (args.join(" ") === "auth status --json") { - return result({ stdout: '{"authenticated":true}\n' }); + if (args.join(" ") === "login status") { + return result({ stdout: "Logged in\n" }); } throw new Error(`Unexpected command: ${args.join(" ")}`); }); @@ -59,7 +59,7 @@ describe("checkProviderStatusesOnStartup", () => { if (args.join(" ") === "--version") { return result({ stdout: "codex 1.0.0\n" }); } - if (args.join(" ") === "auth status --json") { + if (args.join(" ") === "login status") { return result({ code: 1, stderr: "Not logged in. Run codex login.", @@ -79,14 +79,15 @@ describe("checkProviderStatusesOnStartup", () => { ]); }); - it("returns unauthenticated when auth probe JSON array includes authenticated=false", async () => { + it("returns unauthenticated when login status output includes 'not logged in'", async () => { const status = await checkProviderStatusesOnStartup(async (_command, args) => { if (args.join(" ") === "--version") { return result({ stdout: "codex 1.0.0\n" }); } - if (args.join(" ") === "auth status --json") { + if (args.join(" ") === "login status") { return result({ - stdout: '[{"authenticated":false}]\n', + code: 1, + stdout: "Not logged in\n", }); } throw new Error(`Unexpected command: ${args.join(" ")}`); @@ -103,41 +104,15 @@ describe("checkProviderStatusesOnStartup", () => { ]); }); - it("returns warning when auth probe JSON array has no auth marker", async () => { + it("returns warning when login status command is unsupported", async () => { const status = await checkProviderStatusesOnStartup(async (_command, args) => { if (args.join(" ") === "--version") { return result({ stdout: "codex 1.0.0\n" }); } - if (args.join(" ") === "auth status --json") { - return result({ - code: 0, - stdout: '[{"ok":true}]\n', - }); - } - throw new Error(`Unexpected command: ${args.join(" ")}`); - }); - - expect(status).toEqual([ - expect.objectContaining({ - provider: "codex", - status: "warning", - available: true, - authStatus: "unknown", - message: - "Could not verify Codex authentication status from JSON output (missing auth marker).", - }), - ]); - }); - - it("returns warning when auth status command is unsupported", async () => { - const status = await checkProviderStatusesOnStartup(async (_command, args) => { - if (args.join(" ") === "--version") { - return result({ stdout: "codex 1.0.0\n" }); - } - if (args.join(" ") === "auth status --json") { + if (args.join(" ") === "login status") { return result({ code: 2, - stderr: "error: unknown command 'auth'", + stderr: "error: unknown command 'login'", }); } throw new Error(`Unexpected command: ${args.join(" ")}`); diff --git a/apps/server/src/provider/Layers/ProviderHealth.ts b/apps/server/src/provider/Layers/ProviderHealth.ts index 3bab83f19204a173b35155e0183cb5e2a8c14086..40d75f0af30d889c6952dd367605c7f25df1f40f 100644 --- a/apps/server/src/provider/Layers/ProviderHealth.ts +++ b/apps/server/src/provider/Layers/ProviderHealth.ts @@ -223,7 +223,7 @@ async function checkCodexProviderStatus(run: CommandRunner): Promise