Skip to content

Commit 538f89b

Browse files
committed
fix codex wrapper compatibility handling
1 parent 852e585 commit 538f89b

3 files changed

Lines changed: 1125 additions & 70 deletions

File tree

scripts/codex-bin-resolver.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { spawnSync } from "node:child_process";
2+
import { existsSync } from "node:fs";
3+
import { createRequire } from "node:module";
4+
import { dirname, join } from "node:path";
5+
import process from "node:process";
6+
import { fileURLToPath } from "node:url";
7+
8+
function defaultResolvePackageBin(moduleUrl) {
9+
try {
10+
const require = createRequire(moduleUrl);
11+
return require.resolve("@openai/codex/bin/codex.js");
12+
} catch {
13+
return null;
14+
}
15+
}
16+
17+
function resolveWindowsCmdPath(env) {
18+
const comSpec = (env.ComSpec ?? env.COMSPEC ?? "").trim();
19+
if (comSpec.length > 0) return comSpec;
20+
21+
const systemRoot = (env.SystemRoot ?? env.SYSTEMROOT ?? "").trim();
22+
if (systemRoot.length > 0) {
23+
return `${systemRoot.replace(/[\\/]+$/, "")}\\System32\\cmd.exe`;
24+
}
25+
26+
return "cmd.exe";
27+
}
28+
29+
export function resolveRealCodexBin(options = {}) {
30+
const {
31+
env = process.env,
32+
argv = process.argv,
33+
platform = process.platform,
34+
moduleUrl = import.meta.url,
35+
existsSyncImpl = existsSync,
36+
spawnSyncImpl = spawnSync,
37+
resolvePackageBin = defaultResolvePackageBin,
38+
} = options;
39+
40+
const override = (env.CODEX_MULTI_AUTH_REAL_CODEX_BIN ?? "").trim();
41+
if (override.length > 0) {
42+
if (existsSyncImpl(override)) return override;
43+
return null;
44+
}
45+
46+
const resolved = resolvePackageBin(moduleUrl);
47+
if (typeof resolved === "string" && resolved.length > 0 && existsSyncImpl(resolved)) {
48+
return resolved;
49+
}
50+
51+
const searchRoots = [];
52+
const scriptDir = dirname(fileURLToPath(moduleUrl));
53+
searchRoots.push(join(scriptDir, "..", ".."));
54+
55+
const invokedScript = argv[1];
56+
if (typeof invokedScript === "string" && invokedScript.length > 0) {
57+
searchRoots.push(join(dirname(invokedScript), "..", ".."));
58+
}
59+
60+
const npmPrefix = (env.npm_config_prefix ?? env.PREFIX ?? "").trim();
61+
if (npmPrefix.length > 0) {
62+
searchRoots.push(join(npmPrefix, "node_modules"));
63+
searchRoots.push(join(npmPrefix, "lib", "node_modules"));
64+
}
65+
66+
for (const root of searchRoots) {
67+
const candidate = join(root, "@openai", "codex", "bin", "codex.js");
68+
if (existsSyncImpl(candidate)) return candidate;
69+
}
70+
71+
try {
72+
const rootResult =
73+
platform === "win32"
74+
? spawnSyncImpl(resolveWindowsCmdPath(env), ["/d", "/s", "/c", "npm root -g"], {
75+
encoding: "utf8",
76+
env,
77+
stdio: ["ignore", "pipe", "ignore"],
78+
windowsHide: true,
79+
})
80+
: spawnSyncImpl("npm", ["root", "-g"], {
81+
encoding: "utf8",
82+
env,
83+
stdio: ["ignore", "pipe", "ignore"],
84+
});
85+
if (rootResult.status === 0) {
86+
const globalRoot = rootResult.stdout.trim();
87+
if (globalRoot.length > 0) {
88+
const globalBin = join(globalRoot, "@openai", "codex", "bin", "codex.js");
89+
if (existsSyncImpl(globalBin)) return globalBin;
90+
}
91+
}
92+
} catch {
93+
// Ignore and fall through to null.
94+
}
95+
96+
return null;
97+
}

0 commit comments

Comments
 (0)