codex-multi-auth 1.3.2 → 2.0.1

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.
Files changed (132) hide show
  1. package/README.md +40 -26
  2. package/config/README.md +4 -4
  3. package/config/codex-legacy.json +571 -646
  4. package/config/codex-modern.json +258 -274
  5. package/config/minimal-codex.json +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +85 -14
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/auto-update-checker.d.ts +23 -1
  11. package/dist/lib/auto-update-checker.d.ts.map +1 -1
  12. package/dist/lib/auto-update-checker.js +481 -8
  13. package/dist/lib/auto-update-checker.js.map +1 -1
  14. package/dist/lib/cli.d.ts +5 -0
  15. package/dist/lib/cli.d.ts.map +1 -1
  16. package/dist/lib/cli.js.map +1 -1
  17. package/dist/lib/codex-manager/commands/best.js +1 -1
  18. package/dist/lib/codex-manager/commands/best.js.map +1 -1
  19. package/dist/lib/codex-manager/commands/forecast.js +3 -3
  20. package/dist/lib/codex-manager/commands/forecast.js.map +1 -1
  21. package/dist/lib/codex-manager/commands/report.js +3 -3
  22. package/dist/lib/codex-manager/commands/report.js.map +1 -1
  23. package/dist/lib/codex-manager/commands/rotation.d.ts +26 -0
  24. package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -0
  25. package/dist/lib/codex-manager/commands/rotation.js +313 -0
  26. package/dist/lib/codex-manager/commands/rotation.js.map +1 -0
  27. package/dist/lib/codex-manager/commands/status.d.ts +6 -0
  28. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  29. package/dist/lib/codex-manager/commands/status.js +64 -10
  30. package/dist/lib/codex-manager/commands/status.js.map +1 -1
  31. package/dist/lib/codex-manager/forecast-report-commands.js +4 -4
  32. package/dist/lib/codex-manager/forecast-report-commands.js.map +1 -1
  33. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  34. package/dist/lib/codex-manager/help.js +3 -2
  35. package/dist/lib/codex-manager/help.js.map +1 -1
  36. package/dist/lib/codex-manager/rate-limit-markers.d.ts +2 -0
  37. package/dist/lib/codex-manager/rate-limit-markers.d.ts.map +1 -0
  38. package/dist/lib/codex-manager/rate-limit-markers.js +4 -0
  39. package/dist/lib/codex-manager/rate-limit-markers.js.map +1 -0
  40. package/dist/lib/codex-manager/repair-commands.js +3 -3
  41. package/dist/lib/codex-manager/repair-commands.js.map +1 -1
  42. package/dist/lib/codex-manager.d.ts.map +1 -1
  43. package/dist/lib/codex-manager.js +115 -87
  44. package/dist/lib/codex-manager.js.map +1 -1
  45. package/dist/lib/config.d.ts +1 -0
  46. package/dist/lib/config.d.ts.map +1 -1
  47. package/dist/lib/config.js +9 -0
  48. package/dist/lib/config.js.map +1 -1
  49. package/dist/lib/constants.d.ts +2 -0
  50. package/dist/lib/constants.d.ts.map +1 -1
  51. package/dist/lib/constants.js +2 -0
  52. package/dist/lib/constants.js.map +1 -1
  53. package/dist/lib/fs-retry.d.ts +7 -0
  54. package/dist/lib/fs-retry.d.ts.map +1 -0
  55. package/dist/lib/fs-retry.js +35 -0
  56. package/dist/lib/fs-retry.js.map +1 -0
  57. package/dist/lib/index.d.ts +1 -0
  58. package/dist/lib/index.d.ts.map +1 -1
  59. package/dist/lib/index.js +1 -0
  60. package/dist/lib/index.js.map +1 -1
  61. package/dist/lib/logger.d.ts.map +1 -1
  62. package/dist/lib/logger.js +1 -0
  63. package/dist/lib/logger.js.map +1 -1
  64. package/dist/lib/prompts/codex.d.ts +1 -1
  65. package/dist/lib/prompts/codex.d.ts.map +1 -1
  66. package/dist/lib/prompts/codex.js +3 -3
  67. package/dist/lib/prompts/codex.js.map +1 -1
  68. package/dist/lib/quota-probe.js +1 -1
  69. package/dist/lib/quota-probe.js.map +1 -1
  70. package/dist/lib/quota-readiness.d.ts +16 -0
  71. package/dist/lib/quota-readiness.d.ts.map +1 -0
  72. package/dist/lib/quota-readiness.js +82 -0
  73. package/dist/lib/quota-readiness.js.map +1 -0
  74. package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
  75. package/dist/lib/request/fetch-helpers.js +19 -8
  76. package/dist/lib/request/fetch-helpers.js.map +1 -1
  77. package/dist/lib/request/helpers/model-map.d.ts +2 -1
  78. package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
  79. package/dist/lib/request/helpers/model-map.js +52 -60
  80. package/dist/lib/request/helpers/model-map.js.map +1 -1
  81. package/dist/lib/request/request-transformer.d.ts +2 -2
  82. package/dist/lib/request/request-transformer.js +4 -3
  83. package/dist/lib/request/request-transformer.js.map +1 -1
  84. package/dist/lib/runtime/app-bind.d.ts +74 -0
  85. package/dist/lib/runtime/app-bind.d.ts.map +1 -0
  86. package/dist/lib/runtime/app-bind.js +620 -0
  87. package/dist/lib/runtime/app-bind.js.map +1 -0
  88. package/dist/lib/runtime/config-toml.d.ts +10 -0
  89. package/dist/lib/runtime/config-toml.d.ts.map +1 -0
  90. package/dist/lib/runtime/config-toml.js +128 -0
  91. package/dist/lib/runtime/config-toml.js.map +1 -0
  92. package/dist/lib/runtime/login-menu-accounts.d.ts +5 -0
  93. package/dist/lib/runtime/login-menu-accounts.d.ts.map +1 -1
  94. package/dist/lib/runtime/login-menu-accounts.js +7 -2
  95. package/dist/lib/runtime/login-menu-accounts.js.map +1 -1
  96. package/dist/lib/runtime/quota-probe.js +1 -1
  97. package/dist/lib/runtime/quota-probe.js.map +1 -1
  98. package/dist/lib/runtime/runtime-current-account.d.ts +52 -0
  99. package/dist/lib/runtime/runtime-current-account.d.ts.map +1 -0
  100. package/dist/lib/runtime/runtime-current-account.js +252 -0
  101. package/dist/lib/runtime/runtime-current-account.js.map +1 -0
  102. package/dist/lib/runtime/runtime-observability.d.ts +5 -0
  103. package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
  104. package/dist/lib/runtime/runtime-observability.js +5 -0
  105. package/dist/lib/runtime/runtime-observability.js.map +1 -1
  106. package/dist/lib/runtime-constants.d.ts +3 -0
  107. package/dist/lib/runtime-constants.d.ts.map +1 -0
  108. package/dist/lib/runtime-constants.js +3 -0
  109. package/dist/lib/runtime-constants.js.map +1 -0
  110. package/dist/lib/runtime-rotation-proxy.d.ts +36 -0
  111. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -0
  112. package/dist/lib/runtime-rotation-proxy.js +828 -0
  113. package/dist/lib/runtime-rotation-proxy.js.map +1 -0
  114. package/dist/lib/schemas.d.ts +1 -0
  115. package/dist/lib/schemas.d.ts.map +1 -1
  116. package/dist/lib/schemas.js +1 -0
  117. package/dist/lib/schemas.js.map +1 -1
  118. package/dist/lib/ui/auth-menu.d.ts +6 -1
  119. package/dist/lib/ui/auth-menu.d.ts.map +1 -1
  120. package/dist/lib/ui/auth-menu.js +22 -2
  121. package/dist/lib/ui/auth-menu.js.map +1 -1
  122. package/package.json +13 -11
  123. package/scripts/bench-format/codex-host.mjs +142 -73
  124. package/scripts/bench-format/models.mjs +23 -24
  125. package/scripts/benchmark-edit-formats.mjs +9 -7
  126. package/scripts/check-pack-budget-lib.js +49 -6
  127. package/scripts/codex-app-launcher.js +653 -0
  128. package/scripts/codex-app-router.js +322 -0
  129. package/scripts/codex-multi-auth.js +3 -1
  130. package/scripts/codex-routing.js +6 -0
  131. package/scripts/codex.js +2428 -445
  132. package/scripts/postinstall.js +343 -0
@@ -0,0 +1,343 @@
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
+ /**
149
+ * @param {{
150
+ * env?: NodeJS.ProcessEnv,
151
+ * rotationEnabled: boolean,
152
+ * }} options
153
+ */
154
+ export function shouldAutoInstallCodexAppLauncherOnInstall(options) {
155
+ const env = options.env ?? process.env;
156
+ if (isCiEnvironment(env)) return false;
157
+
158
+ const installOverride = readOptionalBoolean(
159
+ env.CODEX_MULTI_AUTH_APP_LAUNCHER_INSTALL,
160
+ );
161
+ if (installOverride !== null) return installOverride;
162
+
163
+ if (!isGlobalNpmInstall(env)) return false;
164
+ return options.rotationEnabled;
165
+ }
166
+
167
+ async function loadConfigModule() {
168
+ try {
169
+ return await import("../dist/lib/config.js");
170
+ } catch (error) {
171
+ if (
172
+ error &&
173
+ typeof error === "object" &&
174
+ "code" in error &&
175
+ error.code === "ERR_MODULE_NOT_FOUND"
176
+ ) {
177
+ return null;
178
+ }
179
+ throw error;
180
+ }
181
+ }
182
+
183
+ async function loadAppBindModule() {
184
+ try {
185
+ return await import("../dist/lib/runtime/app-bind.js");
186
+ } catch (error) {
187
+ if (
188
+ error &&
189
+ typeof error === "object" &&
190
+ "code" in error &&
191
+ error.code === "ERR_MODULE_NOT_FOUND"
192
+ ) {
193
+ return null;
194
+ }
195
+ throw error;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * @param {unknown} configModule
201
+ * @param {NodeJS.ProcessEnv} [env]
202
+ */
203
+ export function resolveRotationEnabled(configModule, env = process.env) {
204
+ const envOverride = readOptionalBoolean(
205
+ env.CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY,
206
+ );
207
+ if (envOverride !== null) return envOverride;
208
+ if (
209
+ !configModule ||
210
+ typeof configModule.loadPluginConfig !== "function" ||
211
+ typeof configModule.getCodexRuntimeRotationProxy !== "function"
212
+ ) {
213
+ return true;
214
+ }
215
+ return (
216
+ configModule.getCodexRuntimeRotationProxy(configModule.loadPluginConfig()) ===
217
+ true
218
+ );
219
+ }
220
+
221
+ function defaultPostinstallLog(message) {
222
+ console.error(`codex-multi-auth: ${message}`);
223
+ }
224
+
225
+ /**
226
+ * @param {boolean} rotationEnabled
227
+ */
228
+ async function maybeBindCodexAppOnInstall(rotationEnabled) {
229
+ const appBindModule = await loadAppBindModule();
230
+ if (!appBindModule || typeof appBindModule.bindCodexAppRuntimeRotation !== "function") {
231
+ return;
232
+ }
233
+
234
+ const currentStatus =
235
+ typeof appBindModule.getAppBindStatus === "function"
236
+ ? await appBindModule.getAppBindStatus().catch(() => null)
237
+ : null;
238
+ const appDetected = hasCodexDesktopApp() || currentStatus?.bound === true;
239
+ if (!shouldAutoBindCodexAppOnInstall({ rotationEnabled, appDetected })) {
240
+ return;
241
+ }
242
+
243
+ const result = await appBindModule.bindCodexAppRuntimeRotation();
244
+ if (result?.message) {
245
+ console.error(`codex-multi-auth: ${result.message}`);
246
+ }
247
+ }
248
+
249
+ /**
250
+ * @param {boolean} rotationEnabled
251
+ * @param {(message: string) => void} [log]
252
+ */
253
+ export async function maybeInstallCodexAppLauncherOnInstall(
254
+ rotationEnabled,
255
+ log = defaultPostinstallLog,
256
+ ) {
257
+ if (!shouldAutoInstallCodexAppLauncherOnInstall({ rotationEnabled })) {
258
+ return;
259
+ }
260
+
261
+ try {
262
+ const launcherModule = await import("./codex-app-launcher.js");
263
+ if (typeof launcherModule.installCodexAppLauncher !== "function") {
264
+ return;
265
+ }
266
+ await launcherModule.installCodexAppLauncher({
267
+ log,
268
+ });
269
+ } catch (error) {
270
+ log(
271
+ `app launcher postinstall skipped: ${error instanceof Error ? error.message : String(error)}`,
272
+ );
273
+ }
274
+ }
275
+
276
+ /**
277
+ * @param {{
278
+ * loadConfigModule?: () => Promise<unknown>,
279
+ * bindCodexApp?: (rotationEnabled: boolean) => Promise<void>,
280
+ * installLauncher?: (rotationEnabled: boolean) => Promise<void>,
281
+ * log?: (message: string) => void,
282
+ * env?: NodeJS.ProcessEnv,
283
+ * }} [deps]
284
+ */
285
+ export async function runPostinstallSelfHeal(deps = {}) {
286
+ const loadConfig = deps.loadConfigModule ?? loadConfigModule;
287
+ const bindCodexApp = deps.bindCodexApp ?? maybeBindCodexAppOnInstall;
288
+ const log = deps.log ?? defaultPostinstallLog;
289
+ const installLauncher =
290
+ deps.installLauncher ??
291
+ ((rotationEnabled) =>
292
+ maybeInstallCodexAppLauncherOnInstall(rotationEnabled, log));
293
+ const configModule = await loadConfig();
294
+ const rotationEnabled = resolveRotationEnabled(configModule, deps.env);
295
+
296
+ try {
297
+ await bindCodexApp(rotationEnabled);
298
+ } catch (error) {
299
+ log(
300
+ `app bind postinstall skipped: ${error instanceof Error ? error.message : String(error)}`,
301
+ );
302
+ }
303
+
304
+ try {
305
+ await installLauncher(rotationEnabled);
306
+ } catch (error) {
307
+ log(
308
+ `app launcher postinstall skipped: ${error instanceof Error ? error.message : String(error)}`,
309
+ );
310
+ }
311
+ return 0;
312
+ }
313
+
314
+ async function main() {
315
+ return runPostinstallSelfHeal();
316
+ }
317
+
318
+ function normalizePostinstallExitCode(exitCode) {
319
+ return Number.isInteger(exitCode) && exitCode >= 0 && exitCode <= 255
320
+ ? exitCode
321
+ : 0;
322
+ }
323
+
324
+ const isDirectRun = (() => {
325
+ try {
326
+ return resolve(process.argv[1] ?? "") === fileURLToPath(import.meta.url);
327
+ } catch {
328
+ return false;
329
+ }
330
+ })();
331
+
332
+ if (isDirectRun) {
333
+ main()
334
+ .then((exitCode) => {
335
+ process.exitCode = normalizePostinstallExitCode(exitCode);
336
+ })
337
+ .catch((error) => {
338
+ defaultPostinstallLog(
339
+ `postinstall self-heal skipped: ${error instanceof Error ? error.message : String(error)}`,
340
+ );
341
+ process.exitCode = 0;
342
+ });
343
+ }