codex-multi-auth 1.3.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -26
- package/config/README.md +3 -3
- package/dist/lib/codex-manager/commands/rotation.d.ts +22 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/rotation.js +287 -0
- package/dist/lib/codex-manager/commands/rotation.js.map +1 -0
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +38 -7
- package/dist/lib/codex-manager/commands/status.js.map +1 -1
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +1 -0
- package/dist/lib/codex-manager/help.js.map +1 -1
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +59 -1
- package/dist/lib/codex-manager.js.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +9 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +2 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/fs-retry.d.ts +7 -0
- package/dist/lib/fs-retry.d.ts.map +1 -0
- package/dist/lib/fs-retry.js +35 -0
- package/dist/lib/fs-retry.js.map +1 -0
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +1 -0
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/runtime/app-bind.d.ts +74 -0
- package/dist/lib/runtime/app-bind.d.ts.map +1 -0
- package/dist/lib/runtime/app-bind.js +620 -0
- package/dist/lib/runtime/app-bind.js.map +1 -0
- package/dist/lib/runtime/config-toml.d.ts +10 -0
- package/dist/lib/runtime/config-toml.d.ts.map +1 -0
- package/dist/lib/runtime/config-toml.js +128 -0
- package/dist/lib/runtime/config-toml.js.map +1 -0
- package/dist/lib/runtime/runtime-observability.d.ts +5 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +5 -0
- package/dist/lib/runtime/runtime-observability.js.map +1 -1
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -0
- package/dist/lib/runtime-constants.js +3 -0
- package/dist/lib/runtime-constants.js.map +1 -0
- package/dist/lib/runtime-rotation-proxy.d.ts +36 -0
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -0
- package/dist/lib/runtime-rotation-proxy.js +828 -0
- package/dist/lib/runtime-rotation-proxy.js.map +1 -0
- package/dist/lib/schemas.d.ts +1 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +1 -0
- package/dist/lib/schemas.js.map +1 -1
- package/package.json +13 -11
- package/scripts/bench-format/codex-host.mjs +142 -73
- package/scripts/bench-format/models.mjs +17 -16
- package/scripts/benchmark-edit-formats.mjs +8 -6
- package/scripts/check-pack-budget-lib.js +49 -6
- package/scripts/codex-app-launcher.js +653 -0
- package/scripts/codex-app-router.js +322 -0
- package/scripts/codex-multi-auth.js +3 -1
- package/scripts/codex-routing.js +6 -0
- package/scripts/codex.js +3390 -1570
- package/scripts/postinstall.js +237 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// @ts-check
|
|
4
|
+
|
|
5
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join, resolve } from "node:path";
|
|
8
|
+
import process from "node:process";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const TRUE_VALUES = new Set(["1", "true", "yes"]);
|
|
12
|
+
const FALSE_VALUES = new Set(["0", "false", "no"]);
|
|
13
|
+
const CI_ENV_KEYS = [
|
|
14
|
+
"CI",
|
|
15
|
+
"GITHUB_ACTIONS",
|
|
16
|
+
"GITLAB_CI",
|
|
17
|
+
"CIRCLECI",
|
|
18
|
+
"BUILDKITE",
|
|
19
|
+
"TF_BUILD",
|
|
20
|
+
"TEAMCITY_VERSION",
|
|
21
|
+
"JENKINS_URL",
|
|
22
|
+
"TRAVIS",
|
|
23
|
+
"APPVEYOR",
|
|
24
|
+
"BITBUCKET_BUILD_NUMBER",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {string | undefined} value
|
|
29
|
+
*/
|
|
30
|
+
export function readOptionalBoolean(value) {
|
|
31
|
+
if (value === undefined || value.trim().length === 0) return null;
|
|
32
|
+
const normalized = value.trim().toLowerCase();
|
|
33
|
+
if (TRUE_VALUES.has(normalized)) return true;
|
|
34
|
+
if (FALSE_VALUES.has(normalized)) return false;
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {NodeJS.ProcessEnv} env
|
|
40
|
+
*/
|
|
41
|
+
export function isGlobalNpmInstall(env = process.env) {
|
|
42
|
+
const globalFlag = readOptionalBoolean(env.npm_config_global);
|
|
43
|
+
if (globalFlag === true) return true;
|
|
44
|
+
return (env.npm_config_location ?? "").trim().toLowerCase() === "global";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {NodeJS.ProcessEnv} env
|
|
49
|
+
* @param {string} key
|
|
50
|
+
*/
|
|
51
|
+
function isEnabledEnvFlag(env, key) {
|
|
52
|
+
const value = env[key];
|
|
53
|
+
if (value === undefined || value.trim().length === 0) return false;
|
|
54
|
+
const parsed = readOptionalBoolean(value);
|
|
55
|
+
return parsed !== false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {NodeJS.ProcessEnv} [env]
|
|
60
|
+
*/
|
|
61
|
+
export function isCiEnvironment(env = process.env) {
|
|
62
|
+
if (readOptionalBoolean(env.npm_config_ignore_scripts) === true) return true;
|
|
63
|
+
return CI_ENV_KEYS.some((key) => isEnabledEnvFlag(env, key));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {string} directory
|
|
68
|
+
* @param {string} prefix
|
|
69
|
+
*/
|
|
70
|
+
function directoryContainsEntryWithPrefix(directory, prefix) {
|
|
71
|
+
try {
|
|
72
|
+
return readdirSync(directory, { withFileTypes: true }).some((entry) =>
|
|
73
|
+
entry.name.startsWith(prefix),
|
|
74
|
+
);
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {{ env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, home?: string }} [options]
|
|
82
|
+
*/
|
|
83
|
+
export function hasCodexDesktopApp(options = {}) {
|
|
84
|
+
const env = options.env ?? process.env;
|
|
85
|
+
const platform = options.platform ?? process.platform;
|
|
86
|
+
const home = options.home ?? homedir();
|
|
87
|
+
|
|
88
|
+
if (platform === "win32") {
|
|
89
|
+
const localAppData =
|
|
90
|
+
(env.LOCALAPPDATA ?? "").trim() || join(home, "AppData", "Local");
|
|
91
|
+
const programFiles =
|
|
92
|
+
(env.ProgramFiles ?? env.ProgramW6432 ?? "").trim() || "C:\\Program Files";
|
|
93
|
+
return (
|
|
94
|
+
directoryContainsEntryWithPrefix(
|
|
95
|
+
join(localAppData, "Packages"),
|
|
96
|
+
"OpenAI.Codex_",
|
|
97
|
+
) ||
|
|
98
|
+
directoryContainsEntryWithPrefix(
|
|
99
|
+
join(programFiles, "WindowsApps"),
|
|
100
|
+
"OpenAI.Codex_",
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (platform === "darwin") {
|
|
106
|
+
return (
|
|
107
|
+
existsSync("/Applications/Codex.app") ||
|
|
108
|
+
existsSync(join(home, "Applications", "Codex.app"))
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {{
|
|
117
|
+
* env?: NodeJS.ProcessEnv,
|
|
118
|
+
* platform?: NodeJS.Platform,
|
|
119
|
+
* home?: string,
|
|
120
|
+
* rotationEnabled: boolean,
|
|
121
|
+
* appDetected?: boolean,
|
|
122
|
+
* }} options
|
|
123
|
+
*/
|
|
124
|
+
export function shouldAutoBindCodexAppOnInstall(options) {
|
|
125
|
+
const env = options.env ?? process.env;
|
|
126
|
+
if (isCiEnvironment(env)) return false;
|
|
127
|
+
|
|
128
|
+
const bindOverride = readOptionalBoolean(env.CODEX_MULTI_AUTH_APP_BIND);
|
|
129
|
+
if (bindOverride !== null) return bindOverride;
|
|
130
|
+
|
|
131
|
+
const installOverride = readOptionalBoolean(
|
|
132
|
+
env.CODEX_MULTI_AUTH_APP_BIND_INSTALL,
|
|
133
|
+
);
|
|
134
|
+
if (installOverride !== null) return installOverride;
|
|
135
|
+
|
|
136
|
+
if (!isGlobalNpmInstall(env)) return false;
|
|
137
|
+
if (!options.rotationEnabled) return false;
|
|
138
|
+
return (
|
|
139
|
+
options.appDetected ??
|
|
140
|
+
hasCodexDesktopApp({
|
|
141
|
+
env,
|
|
142
|
+
platform: options.platform,
|
|
143
|
+
home: options.home,
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function loadConfigModule() {
|
|
149
|
+
try {
|
|
150
|
+
return await import("../dist/lib/config.js");
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (
|
|
153
|
+
error &&
|
|
154
|
+
typeof error === "object" &&
|
|
155
|
+
"code" in error &&
|
|
156
|
+
error.code === "ERR_MODULE_NOT_FOUND"
|
|
157
|
+
) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async function loadAppBindModule() {
|
|
165
|
+
try {
|
|
166
|
+
return await import("../dist/lib/runtime/app-bind.js");
|
|
167
|
+
} catch (error) {
|
|
168
|
+
if (
|
|
169
|
+
error &&
|
|
170
|
+
typeof error === "object" &&
|
|
171
|
+
"code" in error &&
|
|
172
|
+
error.code === "ERR_MODULE_NOT_FOUND"
|
|
173
|
+
) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function resolveRotationEnabled(configModule) {
|
|
181
|
+
const envOverride = readOptionalBoolean(
|
|
182
|
+
process.env.CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY,
|
|
183
|
+
);
|
|
184
|
+
if (envOverride !== null) return envOverride;
|
|
185
|
+
if (
|
|
186
|
+
!configModule ||
|
|
187
|
+
typeof configModule.loadPluginConfig !== "function" ||
|
|
188
|
+
typeof configModule.getCodexRuntimeRotationProxy !== "function"
|
|
189
|
+
) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
return (
|
|
193
|
+
configModule.getCodexRuntimeRotationProxy(configModule.loadPluginConfig()) ===
|
|
194
|
+
true
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function main() {
|
|
199
|
+
const appBindModule = await loadAppBindModule();
|
|
200
|
+
if (!appBindModule || typeof appBindModule.bindCodexAppRuntimeRotation !== "function") {
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const configModule = await loadConfigModule();
|
|
205
|
+
const rotationEnabled = resolveRotationEnabled(configModule);
|
|
206
|
+
const currentStatus =
|
|
207
|
+
typeof appBindModule.getAppBindStatus === "function"
|
|
208
|
+
? await appBindModule.getAppBindStatus().catch(() => null)
|
|
209
|
+
: null;
|
|
210
|
+
const appDetected = hasCodexDesktopApp() || currentStatus?.bound === true;
|
|
211
|
+
if (!shouldAutoBindCodexAppOnInstall({ rotationEnabled, appDetected })) {
|
|
212
|
+
return 0;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const result = await appBindModule.bindCodexAppRuntimeRotation();
|
|
216
|
+
if (result?.message) {
|
|
217
|
+
console.error(`codex-multi-auth: ${result.message}`);
|
|
218
|
+
}
|
|
219
|
+
return 0;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const isDirectRun = (() => {
|
|
223
|
+
try {
|
|
224
|
+
return resolve(process.argv[1] ?? "") === fileURLToPath(import.meta.url);
|
|
225
|
+
} catch {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
|
|
230
|
+
if (isDirectRun) {
|
|
231
|
+
main().catch((error) => {
|
|
232
|
+
console.error(
|
|
233
|
+
`codex-multi-auth: app bind postinstall skipped: ${error instanceof Error ? error.message : String(error)}`,
|
|
234
|
+
);
|
|
235
|
+
process.exitCode = 0;
|
|
236
|
+
});
|
|
237
|
+
}
|