History

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

julius committed 8 months ago

Commit 0a123331 parent 9db54c97 files · +20 −37Browse files

Unified · Split

7 files
  1. apps/server/src/codexAppServerManager.ts +1 −0
  2. apps/server/src/git/Layers/CodexTextGeneration.ts +1 −0
  3. apps/server/src/open.ts +1 −0
  4. apps/server/src/processRunner.ts +1 −0
  5. apps/server/src/provider/Layers/ProviderHealth.test.ts +10 −35
  6. apps/server/src/provider/Layers/ProviderHealth.ts +1 −1
  7. apps/server/src/serverLayers.ts +5 −1
apps/server/src/codexAppServerManager.ts+1−0
@@ -185,6 +185,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve · 184 unmodified lines
185185 ...(codexHomePath ? { CODEX_HOME: codexHomePath } : {}),
186186 },
187187 stdio: ["pipe", "pipe", "pipe"],
188+ shell: process.platform === "win32",
188189 });
189190 const output = readline.createInterface({ input: child.stdout });
190191
apps/server/src/git/Layers/CodexTextGeneration.ts+1−0
@@ -224,6 +224,7 @@ const makeCodexTextGeneration = Effect.gen(function* () { · 223 unmodified lines
224224 ],
225225 {
226226 cwd,
227+ shell: process.platform === "win32",
227228 stdin: {
228229 stream: Stream.make(new TextEncoder().encode(prompt)),
229230 },
apps/server/src/open.ts+1−0
@@ -230,6 +230,7 @@ export const launchDetached = (launch: EditorLaunch) => · 229 unmodified lines
230230 child = spawn(launch.command, [...launch.args], {
231231 detached: true,
232232 stdio: "ignore",
233+ shell: process.platform === "win32",
233234 });
234235 } catch (error) {
235236 return resume(
apps/server/src/processRunner.ts+1−0
@@ -112,6 +112,7 @@ export async function runProcess( · 111 unmodified lines
112112 cwd: options.cwd,
113113 env: options.env,
114114 stdio: "pipe",
115+ shell: process.platform === "win32",
115116 });
116117
117118 let stdout = "";
apps/server/src/provider/Layers/ProviderHealth.test.ts+10−35
@@ -22,8 +22,8 @@ describe("checkProviderStatusesOnStartup", () => { · 21 unmodified lines
2222 if (args.join(" ") === "--version") {
2323 return result({ stdout: "codex 1.0.0\n" });
2424 }
25− if (args.join(" ") === "auth status --json") {
26− return result({ stdout: '{"authenticated":true}\n' });
25+ if (args.join(" ") === "login status") {
26+ return result({ stdout: "Logged in\n" });
2727 }
2828 throw new Error(`Unexpected command: ${args.join(" ")}`);
2929 });
@@ -59,7 +59,7 @@ describe("checkProviderStatusesOnStartup", () => { · 29 unmodified lines
5959 if (args.join(" ") === "--version") {
6060 return result({ stdout: "codex 1.0.0\n" });
6161 }
62− if (args.join(" ") === "auth status --json") {
62+ if (args.join(" ") === "login status") {
6363 return result({
6464 code: 1,
6565 stderr: "Not logged in. Run codex login.",
@@ -79,14 +79,15 @@ describe("checkProviderStatusesOnStartup", () => { · 13 unmodified lines
7979 ]);
8080 });
8181
82− it("returns unauthenticated when auth probe JSON array includes authenticated=false", async () => {
82+ it("returns unauthenticated when login status output includes 'not logged in'", async () => {
8383 const status = await checkProviderStatusesOnStartup(async (_command, args) => {
8484 if (args.join(" ") === "--version") {
8585 return result({ stdout: "codex 1.0.0\n" });
8686 }
87− if (args.join(" ") === "auth status --json") {
87+ if (args.join(" ") === "login status") {
8888 return result({
89− stdout: '[{"authenticated":false}]\n',
89+ code: 1,
90+ stdout: "Not logged in\n",
9091 });
9192 }
9293 throw new Error(`Unexpected command: ${args.join(" ")}`);
@@ -103,41 +104,15 @@ describe("checkProviderStatusesOnStartup", () => { · 10 unmodified lines
103104 ]);
104105 });
105106
106− it("returns warning when auth probe JSON array has no auth marker", async () => {
107− const status = await checkProviderStatusesOnStartup(async (_command, args) => {
108− if (args.join(" ") === "--version") {
109− return result({ stdout: "codex 1.0.0\n" });
110− }
111− if (args.join(" ") === "auth status --json") {
112− return result({
113− code: 0,
114− stdout: '[{"ok":true}]\n',
115− });
116− }
117− throw new Error(`Unexpected command: ${args.join(" ")}`);
118− });
119−
120− expect(status).toEqual([
121− expect.objectContaining({
122− provider: "codex",
123− status: "warning",
124− available: true,
125− authStatus: "unknown",
126− message:
127− "Could not verify Codex authentication status from JSON output (missing auth marker).",
128− }),
129− ]);
130− });
131−
132− it("returns warning when auth status command is unsupported", async () => {
107+ it("returns warning when login status command is unsupported", async () => {
133108 const status = await checkProviderStatusesOnStartup(async (_command, args) => {
134109 if (args.join(" ") === "--version") {
135110 return result({ stdout: "codex 1.0.0\n" });
136111 }
137− if (args.join(" ") === "auth status --json") {
112+ if (args.join(" ") === "login status") {
138113 return result({
139114 code: 2,
140− stderr: "error: unknown command 'auth'",
115+ stderr: "error: unknown command 'login'",
141116 });
142117 }
143118 throw new Error(`Unexpected command: ${args.join(" ")}`);
apps/server/src/provider/Layers/ProviderHealth.ts+1−1
@@ -223,7 +223,7 @@ async function checkCodexProviderStatus(run: CommandRunner): Promise<ServerProvi · 222 unmodified lines
223223 }
224224
225225 try {
226− const auth = await run("codex", ["auth", "status", "--json"], {
226+ const auth = await run("codex", ["login", "status"], {
227227 timeoutMs: DEFAULT_TIMEOUT_MS,
228228 allowNonZeroExit: true,
229229 outputMode: "truncate",
apps/server/src/serverLayers.ts+5−1
@@ -105,7 +105,11 @@ export function makeServerRuntimeServicesLayer() { · 104 unmodified lines
105105 );
106106
107107 const terminalLayer = TerminalManagerLive.pipe(
108− Layer.provide(typeof Bun !== "undefined" ? BunPtyAdapterLive : NodePtyAdapterLive),
108+ Layer.provide(
109+ typeof Bun !== "undefined" && process.platform !== "win32"
110+ ? BunPtyAdapterLive
111+ : NodePtyAdapterLive,
112+ ),
109113 );
110114
111115 const gitManagerLayer = GitManagerLive.pipe(