From 1ac54505884d69279aebb78dbb4f9601a75dbe0c Mon Sep 17 00:00:00 2001 From: Abdel E Date: Sun, 5 Apr 2026 18:04:54 -0400 Subject: [PATCH 1/2] fix(windows): prefer executable provider command paths --- src/main/services/ConnectionsService.ts | 6 +++++ src/main/services/ptyManager.ts | 3 ++- src/test/main/ConnectionsService.test.ts | 28 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/main/services/ConnectionsService.ts b/src/main/services/ConnectionsService.ts index 6965d16aa..6bc9ed080 100644 --- a/src/main/services/ConnectionsService.ts +++ b/src/main/services/ConnectionsService.ts @@ -390,6 +390,12 @@ class ConnectionsService { .split(/\r?\n/) .map((l) => l.trim()) .filter(Boolean); + if (process.platform === 'win32') { + const executable = lines.find((line) => /\.(com|exe|bat|cmd|ps1)$/i.test(line)); + if (executable) { + return executable; + } + } return lines[0] ?? null; } catch { return null; diff --git a/src/main/services/ptyManager.ts b/src/main/services/ptyManager.ts index ff4cf36b7..77ced73d3 100644 --- a/src/main/services/ptyManager.ts +++ b/src/main/services/ptyManager.ts @@ -981,7 +981,8 @@ function resolveCommandPath(command: string): string | null { .split(';') .map((ext) => ext.trim()) .filter(Boolean); - return [base, ...exts.map((ext) => `${base}${ext.toLowerCase()}`)]; + const expanded = exts.map((ext) => `${base}${ext.toLowerCase()}`); + return [...expanded, base]; }; const resolveFromCandidates = (bases: string[], makeAbsolute: boolean): string | null => { diff --git a/src/test/main/ConnectionsService.test.ts b/src/test/main/ConnectionsService.test.ts index f8596406b..c9adda889 100644 --- a/src/test/main/ConnectionsService.test.ts +++ b/src/test/main/ConnectionsService.test.ts @@ -209,4 +209,32 @@ describe('ConnectionsService – resolveStatus', () => { expect(statusMap.claude?.installed).toBe(true); expect(statusMap.claude?.path).toBeNull(); }); + + it('prefers executable where results on Windows over extensionless shims', async () => { + const originalPlatformDescriptor = Object.getOwnPropertyDescriptor(process, 'platform'); + Object.defineProperty(process, 'platform', { + value: 'win32', + configurable: true, + }); + + execFileSyncMock.mockReturnValue( + 'C:\\Users\\test\\AppData\\Roaming\\npm\\codex\r\nC:\\Users\\test\\AppData\\Roaming\\npm\\codex.cmd\r\n' + ); + spawnEmits({ stdout: '0.27.0\n', closeCode: 0 }); + + try { + const { connectionsService } = await import('../../main/services/ConnectionsService'); + await connectionsService.checkProvider('codex', 'manual'); + } finally { + if (originalPlatformDescriptor) { + Object.defineProperty(process, 'platform', originalPlatformDescriptor); + } + } + + expect(statusMap.codex?.installed).toBe(true); + expect(statusMap.codex?.path).toBe('C:\\Users\\test\\AppData\\Roaming\\npm\\codex.cmd'); + const firstSpawnCall = spawnMock.mock.calls[0]; + expect(firstSpawnCall?.[0]).toMatch(/cmd\.exe$/i); + expect(firstSpawnCall?.[1]).toEqual(expect.arrayContaining(['/d', '/s', '/c'])); + }); }); From c47ec48cddbf2e2cceec3770a3f0a56a03ed60ba Mon Sep 17 00:00:00 2001 From: Abdel E Date: Sun, 5 Apr 2026 22:10:45 -0400 Subject: [PATCH 2/2] chore(windows): skip node-pty install script in pnpm allowlist node-pty is rebuilt for Electron in postinstall via electron-rebuild. Skipping the package install-time node-gyp step avoids Windows toolchains where VS2022 lacks a detected SDK while electron-rebuild still succeeds. Made-with: Cursor --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f22cf9ba7..bbaa1aad3 100644 --- a/package.json +++ b/package.json @@ -272,7 +272,6 @@ }, "onlyBuiltDependencies": [ "sqlite3", - "node-pty", "keytar", "electron" ], @@ -281,6 +280,7 @@ "core-js", "cpu-features", "esbuild", + "node-pty", "protobufjs", "ssh2" ],