mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 22:16:41 +00:00
fix(codex): prefer cmd wrappers over powershell on windows
- keep Windows Codex detection on the npm cmd shim when available - add regression tests for cmd-first and ps1-to-cmd fallback selection
This commit is contained in:
@@ -10,17 +10,26 @@ const CODEX_CONFIG_OVERRIDE_PROBE_ARGS = ['-c', 'model="gpt-5"', '--version'];
|
|||||||
function buildWindowsCodexCandidates(matches: string[]): string[] {
|
function buildWindowsCodexCandidates(matches: string[]): string[] {
|
||||||
const shellCandidates = matches.filter((entry) => /\.(exe|cmd|bat|ps1)$/i.test(entry));
|
const shellCandidates = matches.filter((entry) => /\.(exe|cmd|bat|ps1)$/i.test(entry));
|
||||||
const bareCandidates = matches.filter((entry) => !/\.(exe|cmd|bat|ps1)$/i.test(entry));
|
const bareCandidates = matches.filter((entry) => !/\.(exe|cmd|bat|ps1)$/i.test(entry));
|
||||||
const prioritized: string[] = [];
|
const prioritized = shellCandidates.map((entry) => {
|
||||||
|
if (!/\.ps1$/i.test(entry)) {
|
||||||
for (const entry of shellCandidates) {
|
return entry;
|
||||||
if (/\.(cmd|bat)$/i.test(entry)) {
|
|
||||||
prioritized.push(entry.replace(/\.(cmd|bat)$/i, '.ps1'));
|
|
||||||
}
|
|
||||||
prioritized.push(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prioritized.push(...bareCandidates);
|
for (const preferredExtension of ['.cmd', '.bat', '.exe']) {
|
||||||
return [...new Set(prioritized)];
|
const siblingCandidate = entry.replace(/\.ps1$/i, preferredExtension);
|
||||||
|
try {
|
||||||
|
if (fs.statSync(siblingCandidate).isFile()) {
|
||||||
|
return siblingCandidate;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore missing sibling wrappers and keep the original PowerShell path.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
});
|
||||||
|
|
||||||
|
return [...new Set([...prioritized, ...bareCandidates])];
|
||||||
}
|
}
|
||||||
|
|
||||||
function runCodexProbe(codexPath: string, args: string[]): string | undefined {
|
function runCodexProbe(codexPath: string, args: string[]): string | undefined {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ describe('codex-detector', () => {
|
|||||||
execFileSyncSpy.mockRestore();
|
execFileSyncSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('prefers a sibling PowerShell wrapper over cmd when Windows PATH only exposes codex.cmd', () => {
|
it('keeps the cmd wrapper when Windows PATH exposes codex.cmd and a sibling ps1 also exists', () => {
|
||||||
const fakeCmdCodex = path.join(tmpDir, 'codex.cmd');
|
const fakeCmdCodex = path.join(tmpDir, 'codex.cmd');
|
||||||
const fakePsCodex = path.join(tmpDir, 'codex.ps1');
|
const fakePsCodex = path.join(tmpDir, 'codex.ps1');
|
||||||
fs.writeFileSync(fakeCmdCodex, '');
|
fs.writeFileSync(fakeCmdCodex, '');
|
||||||
@@ -82,7 +82,21 @@ describe('codex-detector', () => {
|
|||||||
|
|
||||||
const execSyncSpy = spyOn(childProcess, 'execSync').mockImplementation(() => `${fakeCmdCodex}\n`);
|
const execSyncSpy = spyOn(childProcess, 'execSync').mockImplementation(() => `${fakeCmdCodex}\n`);
|
||||||
|
|
||||||
expect(detectCodexCli()).toBe(fakePsCodex);
|
expect(detectCodexCli()).toBe(fakeCmdCodex);
|
||||||
|
|
||||||
|
execSyncSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('replaces a Windows PowerShell wrapper with a sibling cmd shim when PATH returns codex.ps1', () => {
|
||||||
|
const fakeCmdCodex = path.join(tmpDir, 'codex.cmd');
|
||||||
|
const fakePsCodex = path.join(tmpDir, 'codex.ps1');
|
||||||
|
fs.writeFileSync(fakeCmdCodex, '');
|
||||||
|
fs.writeFileSync(fakePsCodex, '');
|
||||||
|
Object.defineProperty(process, 'platform', { value: 'win32' });
|
||||||
|
|
||||||
|
const execSyncSpy = spyOn(childProcess, 'execSync').mockImplementation(() => `${fakePsCodex}\n`);
|
||||||
|
|
||||||
|
expect(detectCodexCli()).toBe(fakeCmdCodex);
|
||||||
|
|
||||||
execSyncSpy.mockRestore();
|
execSyncSpy.mockRestore();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user