fix(windows): resolve cli shim path handling

This commit is contained in:
777genius 2026-04-25 20:31:14 +03:00
parent 427f48dd71
commit 6113e27006
3 changed files with 25 additions and 5 deletions

View file

@ -43,10 +43,29 @@ function expandWindowsExtensions(candidate: string): string[] {
return [...pathext.map((ext) => `${candidate}${ext.toLowerCase()}`), candidate];
}
function isPathLikeCandidate(candidate: string): boolean {
if (process.platform === 'win32') {
return path.win32.isAbsolute(candidate) || candidate.includes('\\') || candidate.includes('/');
}
return path.isAbsolute(candidate) || candidate.includes(path.sep);
}
function getPathEntries(): string[] {
const delimiter = process.platform === 'win32' ? ';' : path.delimiter;
return (process.env.PATH ?? '').split(delimiter).filter(Boolean);
}
function resolvePathEntryCandidate(pathEntry: string, candidate: string): string {
if (process.platform === 'win32') {
return path.win32.join(pathEntry, candidate);
}
return path.join(pathEntry, candidate);
}
async function verifyBinary(candidate: string): Promise<string | null> {
const expandedCandidates = expandWindowsExtensions(candidate);
if (path.isAbsolute(candidate) || candidate.includes(path.sep)) {
if (isPathLikeCandidate(candidate)) {
for (const expandedCandidate of expandedCandidates) {
if (await fileExists(expandedCandidate)) {
return expandedCandidate;
@ -55,10 +74,10 @@ async function verifyBinary(candidate: string): Promise<string | null> {
return null;
}
const pathEntries = (process.env.PATH ?? '').split(path.delimiter).filter(Boolean);
const pathEntries = getPathEntries();
for (const pathEntry of pathEntries) {
for (const expandedCandidate of expandedCandidates) {
const resolvedCandidate = path.join(pathEntry, expandedCandidate);
const resolvedCandidate = resolvePathEntryCandidate(pathEntry, expandedCandidate);
if (await fileExists(resolvedCandidate)) {
return resolvedCandidate;
}

View file

@ -42,8 +42,8 @@ describe('CodexBinaryResolver', () => {
it('prefers the Windows command shim over the extensionless POSIX shim on PATH', async () => {
const binDir = 'C:\\Program Files\\nodejs';
const extensionless = path.join(binDir, 'codex');
const cmdShim = path.join(binDir, 'codex.cmd');
const extensionless = path.win32.join(binDir, 'codex');
const cmdShim = path.win32.join(binDir, 'codex.cmd');
process.env.PATH = binDir;
accessMock.mockImplementation((filePath, mode) => {

View file

@ -112,6 +112,7 @@ function resolveCmdPathTemplate(template: string, launcherDir: string): string {
.replace(/%SCRIPT_DIR%/gi, dirWithSep)
.replace(/%~dp0/gi, dirWithSep)
.replace(/%dp0%/gi, dirWithSep)
.replace(/\\/g, path.sep)
);
}