codex-multi-auth 1.3.0 → 1.3.2

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 (75) hide show
  1. package/README.md +3 -3
  2. package/config/codex-legacy.json +85 -10
  3. package/config/codex-modern.json +35 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +8 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/accounts.d.ts.map +1 -1
  8. package/dist/lib/accounts.js +60 -2
  9. package/dist/lib/accounts.js.map +1 -1
  10. package/dist/lib/auth/auth.d.ts +19 -0
  11. package/dist/lib/auth/auth.d.ts.map +1 -1
  12. package/dist/lib/auth/auth.js +90 -4
  13. package/dist/lib/auth/auth.js.map +1 -1
  14. package/dist/lib/auth/server.d.ts.map +1 -1
  15. package/dist/lib/auth/server.js +11 -5
  16. package/dist/lib/auth/server.js.map +1 -1
  17. package/dist/lib/capability-policy.d.ts.map +1 -1
  18. package/dist/lib/capability-policy.js +7 -2
  19. package/dist/lib/capability-policy.js.map +1 -1
  20. package/dist/lib/codex-manager.js +2 -2
  21. package/dist/lib/codex-manager.js.map +1 -1
  22. package/dist/lib/prompts/codex.d.ts +2 -2
  23. package/dist/lib/prompts/codex.js +2 -2
  24. package/dist/lib/recovery/storage.d.ts +13 -0
  25. package/dist/lib/recovery/storage.d.ts.map +1 -1
  26. package/dist/lib/recovery/storage.js +32 -1
  27. package/dist/lib/recovery/storage.js.map +1 -1
  28. package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
  29. package/dist/lib/request/fetch-helpers.js +15 -2
  30. package/dist/lib/request/fetch-helpers.js.map +1 -1
  31. package/dist/lib/request/helpers/model-map.d.ts +3 -3
  32. package/dist/lib/request/helpers/model-map.d.ts.map +1 -1
  33. package/dist/lib/request/helpers/model-map.js +146 -70
  34. package/dist/lib/request/helpers/model-map.js.map +1 -1
  35. package/dist/lib/request/rate-limit-backoff.d.ts +14 -1
  36. package/dist/lib/request/rate-limit-backoff.d.ts.map +1 -1
  37. package/dist/lib/request/rate-limit-backoff.js +26 -5
  38. package/dist/lib/request/rate-limit-backoff.js.map +1 -1
  39. package/dist/lib/request/response-handler.d.ts.map +1 -1
  40. package/dist/lib/request/response-handler.js +16 -3
  41. package/dist/lib/request/response-handler.js.map +1 -1
  42. package/dist/lib/rotation.d.ts +2 -0
  43. package/dist/lib/rotation.d.ts.map +1 -1
  44. package/dist/lib/rotation.js +26 -0
  45. package/dist/lib/rotation.js.map +1 -1
  46. package/dist/lib/shutdown.d.ts.map +1 -1
  47. package/dist/lib/shutdown.js +19 -10
  48. package/dist/lib/shutdown.js.map +1 -1
  49. package/dist/lib/storage/import-export.d.ts.map +1 -1
  50. package/dist/lib/storage/import-export.js +15 -1
  51. package/dist/lib/storage/import-export.js.map +1 -1
  52. package/dist/lib/ui/select.d.ts.map +1 -1
  53. package/dist/lib/ui/select.js +5 -1
  54. package/dist/lib/ui/select.js.map +1 -1
  55. package/dist/lib/unified-settings.d.ts.map +1 -1
  56. package/dist/lib/unified-settings.js +69 -14
  57. package/dist/lib/unified-settings.js.map +1 -1
  58. package/package.json +1 -1
  59. package/scripts/codex.js +380 -80
  60. package/dist/lib/codex-manager/auth-commands.d.ts +0 -72
  61. package/dist/lib/codex-manager/auth-commands.d.ts.map +0 -1
  62. package/dist/lib/codex-manager/auth-commands.js +0 -643
  63. package/dist/lib/codex-manager/auth-commands.js.map +0 -1
  64. package/dist/lib/codex-manager/commands/doctor.d.ts +0 -85
  65. package/dist/lib/codex-manager/commands/doctor.d.ts.map +0 -1
  66. package/dist/lib/codex-manager/commands/doctor.js +0 -424
  67. package/dist/lib/codex-manager/commands/doctor.js.map +0 -1
  68. package/dist/lib/codex-manager/commands/fix.d.ts +0 -92
  69. package/dist/lib/codex-manager/commands/fix.d.ts.map +0 -1
  70. package/dist/lib/codex-manager/commands/fix.js +0 -347
  71. package/dist/lib/codex-manager/commands/fix.js.map +0 -1
  72. package/dist/lib/codex-manager/commands/verify-flagged.d.ts +0 -69
  73. package/dist/lib/codex-manager/commands/verify-flagged.d.ts.map +0 -1
  74. package/dist/lib/codex-manager/commands/verify-flagged.js +0 -251
  75. package/dist/lib/codex-manager/commands/verify-flagged.js.map +0 -1
package/scripts/codex.js CHANGED
@@ -143,30 +143,195 @@ function resolveRealCodexBin() {
143
143
  return resolveRealCodexBinFromEnvironment({ moduleUrl: import.meta.url });
144
144
  }
145
145
 
146
- function forwardToRealCodex(codexBin, args, env = process.env, cleanup) {
147
- return new Promise((resolve) => {
148
- const finalize = (exitCode) => {
146
+ const CHATGPT_CODEX_UNSUPPORTED_MODEL_PATTERN =
147
+ /model is not supported when using codex with a chatgpt account/i;
148
+ const NORMALIZED_UNSUPPORTED_MODEL_PATTERN =
149
+ /model ['"]([^'"]+)['"] is not currently available for this chatgpt account when using codex oauth/i;
150
+ const MODEL_ACCESS_DENIED_PATTERN =
151
+ /the model [`'"]([^`'"]+)[`'"] does not exist or you do not have access to it/i;
152
+ const DIRECT_UNSUPPORTED_MODEL_PATTERN =
153
+ /['"]([^'"]+)['"]\s+model is not supported when using codex with a chatgpt account/i;
154
+ const WRAPPER_UNSUPPORTED_MODEL_FALLBACK_CHAIN = {
155
+ "gpt-5.5": ["gpt-5.4"],
156
+ "gpt-5.5-pro": ["gpt-5.4"],
157
+ };
158
+
159
+ function canonicalizeRequestedModelName(model) {
160
+ if (typeof model !== "string") return "";
161
+ const normalizedModel = normalizeRequestedModel(model);
162
+ if (normalizedModel) {
163
+ return normalizedModel;
164
+ }
165
+
166
+ const stripped = stripProviderPrefix(model).trim().toLowerCase();
167
+ if (!stripped) {
168
+ return "";
169
+ }
170
+
171
+ return stripped.replace(/-(none|minimal|low|medium|high|xhigh)$/i, "");
172
+ }
173
+
174
+ function extractUnsupportedModelFromOutput(output) {
175
+ if (typeof output !== "string" || output.length === 0) {
176
+ return undefined;
177
+ }
178
+
179
+ const directMatch = output.match(DIRECT_UNSUPPORTED_MODEL_PATTERN);
180
+ if (directMatch?.[1]) {
181
+ return canonicalizeRequestedModelName(directMatch[1]);
182
+ }
183
+
184
+ const normalizedMatch = output.match(NORMALIZED_UNSUPPORTED_MODEL_PATTERN);
185
+ if (normalizedMatch?.[1]) {
186
+ return canonicalizeRequestedModelName(normalizedMatch[1]);
187
+ }
188
+ const accessDeniedMatch = output.match(MODEL_ACCESS_DENIED_PATTERN);
189
+ if (accessDeniedMatch?.[1]) {
190
+ return canonicalizeRequestedModelName(accessDeniedMatch[1]);
191
+ }
192
+
193
+ return undefined;
194
+ }
195
+
196
+ function resolveUnsupportedModelRetryTarget(
197
+ requestedModel,
198
+ output,
199
+ attemptedModels = [],
200
+ ) {
201
+ if (
202
+ typeof output !== "string" ||
203
+ output.length === 0 ||
204
+ (!CHATGPT_CODEX_UNSUPPORTED_MODEL_PATTERN.test(output) &&
205
+ !NORMALIZED_UNSUPPORTED_MODEL_PATTERN.test(output) &&
206
+ !MODEL_ACCESS_DENIED_PATTERN.test(output))
207
+ ) {
208
+ return undefined;
209
+ }
210
+
211
+ const attempted = new Set(
212
+ attemptedModels
213
+ .map((model) => canonicalizeRequestedModelName(model))
214
+ .filter(Boolean),
215
+ );
216
+ const normalizedRequestedModel = canonicalizeRequestedModelName(requestedModel);
217
+ const blockedModel =
218
+ extractUnsupportedModelFromOutput(output) ?? normalizedRequestedModel;
219
+ const fallbackChain =
220
+ WRAPPER_UNSUPPORTED_MODEL_FALLBACK_CHAIN[blockedModel] ??
221
+ (normalizedRequestedModel
222
+ ? WRAPPER_UNSUPPORTED_MODEL_FALLBACK_CHAIN[normalizedRequestedModel]
223
+ : undefined) ??
224
+ [];
225
+
226
+ for (const fallbackModel of fallbackChain) {
227
+ if (fallbackModel !== blockedModel && !attempted.has(fallbackModel)) {
228
+ return fallbackModel;
229
+ }
230
+ }
231
+
232
+ return undefined;
233
+ }
234
+
235
+ function replaceRequestedModel(args, nextModel) {
236
+ if (!nextModel) {
237
+ return [...args];
238
+ }
239
+
240
+ const nextArgs = [...args];
241
+ for (let i = 0; i < nextArgs.length; i += 1) {
242
+ const arg = nextArgs[i];
243
+ if (arg === "--model" && typeof nextArgs[i + 1] === "string") {
244
+ nextArgs[i + 1] = nextModel;
245
+ return nextArgs;
246
+ }
247
+ if (typeof arg === "string" && arg.startsWith("--model=")) {
248
+ nextArgs[i] = `--model=${nextModel}`;
249
+ return nextArgs;
250
+ }
251
+ }
252
+
253
+ return nextArgs;
254
+ }
255
+
256
+ function shouldCaptureForwardedCodexOutput(env = process.env) {
257
+ const override = (env.CODEX_MULTI_AUTH_CAPTURE_FORWARD_OUTPUT ?? "").trim();
258
+ if (override === "1") {
259
+ return true;
260
+ }
261
+ if (override === "0") {
262
+ return false;
263
+ }
264
+ // Windows child processes can report undefined isTTY; treat that as non-TTY so retry capture remains available.
265
+ return process.stdout.isTTY !== true || process.stderr.isTTY !== true;
266
+ }
267
+
268
+ function forwardToRealCodexOnce(
269
+ codexBin,
270
+ args,
271
+ env = process.env,
272
+ cleanup,
273
+ options = {},
274
+ ) {
275
+ return new Promise((resolve) => {
276
+ let settled = false;
277
+ let stdout = "";
278
+ let stderr = "";
279
+ const captureOutput = options.captureOutput === true;
280
+ const finalize = (exitCode) => {
281
+ if (settled) {
282
+ return;
283
+ }
284
+ settled = true;
149
285
  try {
150
286
  cleanup?.();
151
287
  } catch {
152
288
  // Best-effort cleanup only.
153
- }
154
- resolve(exitCode);
155
- };
156
-
157
- const command = codexBin.launchWithNode ? process.execPath : codexBin.path;
158
- const commandArgs = codexBin.launchWithNode ? [codexBin.path, ...args] : args;
159
- const child = spawn(command, commandArgs, {
160
- stdio: "inherit",
161
- env,
162
- });
163
-
164
- child.once("error", (error) => {
165
- console.error(`Failed to launch real Codex CLI: ${String(error)}`);
166
- finalize(1);
167
- });
168
-
169
- child.once("exit", (code, signal) => {
289
+ }
290
+ resolve({
291
+ exitCode,
292
+ // No-capture output stays empty by design so retry parsing cannot
293
+ // reintroduce pipes that break terminal passthrough.
294
+ output: `${stdout}\n${stderr}`.trim(),
295
+ });
296
+ };
297
+
298
+ const command = codexBin.launchWithNode ? process.execPath : codexBin.path;
299
+ const commandArgs = codexBin.launchWithNode ? [codexBin.path, ...args] : args;
300
+ let child;
301
+ const failLaunch = (error) => {
302
+ const message = `Failed to launch real Codex CLI: ${String(error)}`;
303
+ stderr += `${stderr ? "\n" : ""}${message}`;
304
+ console.error(message);
305
+ finalize(1);
306
+ };
307
+ try {
308
+ child = spawn(command, commandArgs, {
309
+ stdio: captureOutput ? ["inherit", "pipe", "pipe"] : "inherit",
310
+ env,
311
+ });
312
+ } catch (error) {
313
+ failLaunch(error);
314
+ return;
315
+ }
316
+
317
+ if (captureOutput) {
318
+ child.stdout?.on("data", (chunk) => {
319
+ const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
320
+ stdout += text;
321
+ process.stdout.write(chunk);
322
+ });
323
+ child.stderr?.on("data", (chunk) => {
324
+ const text = typeof chunk === "string" ? chunk : chunk.toString("utf8");
325
+ stderr += text;
326
+ process.stderr.write(chunk);
327
+ });
328
+ }
329
+
330
+ child.once("error", (error) => {
331
+ failLaunch(error);
332
+ });
333
+
334
+ child.once("close", (code, signal) => {
170
335
  if (signal) {
171
336
  const signalNumber = signal === "SIGINT" ? 130 : 1;
172
337
  finalize(signalNumber);
@@ -177,6 +342,61 @@ function forwardToRealCodex(codexBin, args, env = process.env, cleanup) {
177
342
  });
178
343
  }
179
344
 
345
+ async function forwardToRealCodex(codexBin, rawArgs, baseEnv = process.env) {
346
+ let currentArgs = [...rawArgs];
347
+ let lastExitCode = 1;
348
+ const attemptedModels = new Set();
349
+
350
+ for (let attempt = 0; attempt < 4; attempt += 1) {
351
+ const requestedModel = extractRequestedModel(currentArgs);
352
+ if (requestedModel) {
353
+ attemptedModels.add(requestedModel);
354
+ }
355
+
356
+ const { args: forwardArgs, requestedModel: compatibilityRequestedModel } =
357
+ buildForwardArgs(currentArgs);
358
+ const compatibility = createCompatibilityCodexHome(
359
+ forwardArgs,
360
+ compatibilityRequestedModel,
361
+ baseEnv,
362
+ );
363
+ const result = await forwardToRealCodexOnce(
364
+ codexBin,
365
+ compatibility.args,
366
+ compatibility.env,
367
+ compatibility.cleanup,
368
+ {
369
+ captureOutput: shouldCaptureForwardedCodexOutput(compatibility.env),
370
+ },
371
+ );
372
+ lastExitCode = result.exitCode;
373
+ if (result.exitCode === 0) {
374
+ return result.exitCode;
375
+ }
376
+
377
+ const fallbackModel = resolveUnsupportedModelRetryTarget(
378
+ requestedModel,
379
+ result.output,
380
+ [...attemptedModels],
381
+ );
382
+ if (!fallbackModel) {
383
+ return result.exitCode;
384
+ }
385
+
386
+ console.error(
387
+ `codex-multi-auth: model ${requestedModel ?? "requested model"} is unsupported on this ChatGPT Codex surface. Retrying with ${fallbackModel}.`,
388
+ );
389
+ attemptedModels.add(fallbackModel);
390
+ const nextArgs = replaceRequestedModel(currentArgs, fallbackModel);
391
+ if (JSON.stringify(nextArgs) === JSON.stringify(currentArgs)) {
392
+ return result.exitCode;
393
+ }
394
+ currentArgs = nextArgs;
395
+ }
396
+
397
+ return lastExitCode;
398
+ }
399
+
180
400
  function hasCliAuthCredentialsStoreOverride(args) {
181
401
  for (let i = 0; i < args.length; i += 1) {
182
402
  const arg = args[i];
@@ -201,12 +421,15 @@ function hasCliAuthCredentialsStoreOverride(args) {
201
421
  }
202
422
 
203
423
  // IMPORTANT: Keep this mapping in sync with
204
- // `lib/request/helpers/model-map.ts` `MODEL_PROFILES`.
424
+ // `lib/request/helpers/model-map.ts` `MODEL_PROFILES`
425
+ // and its GPT-5 normalization helpers.
205
426
  // This wrapper runs before the TypeScript build, so it cannot import that source.
206
427
  const SUPPORTED_REASONING_EFFORTS_BY_MODEL = {
207
428
  "gpt-5-codex": ["low", "medium", "high", "xhigh"],
208
429
  "gpt-5.1-codex-max": ["medium", "high", "xhigh"],
209
430
  "gpt-5.1-codex-mini": ["medium", "high"],
431
+ "gpt-5.5": ["none", "low", "medium", "high", "xhigh"],
432
+ "gpt-5.5-pro": ["medium", "high", "xhigh"],
210
433
  "gpt-5.4": ["none", "low", "medium", "high", "xhigh"],
211
434
  "gpt-5.4-pro": ["medium", "high", "xhigh"],
212
435
  "gpt-5.2-pro": ["medium", "high", "xhigh"],
@@ -229,6 +452,39 @@ const REASONING_FALLBACKS = {
229
452
 
230
453
  const KNOWN_REASONING_EFFORTS = new Set(Object.keys(REASONING_FALLBACKS));
231
454
  const REQUESTED_MODEL_ALIASES = new Map();
455
+ const DEFAULT_GENERAL_GPT5_MODEL = "gpt-5.4";
456
+ const GPT_5_5_CANONICAL_MODEL = "gpt-5.5";
457
+ const GPT_5_5_PRO_CANONICAL_MODEL = "gpt-5.5-pro";
458
+ const GPT_5_5_RELEASE_MODEL = "gpt-5.5-20260423";
459
+ const GPT_5_5_PRO_RELEASE_MODEL = "gpt-5.5-pro-20260423";
460
+ const GENERAL_GPT5_VERSION_CATALOG = {
461
+ 1: {
462
+ base: "gpt-5.1",
463
+ },
464
+ 2: {
465
+ base: "gpt-5.2",
466
+ pro: "gpt-5.2-pro",
467
+ },
468
+ 4: {
469
+ base: DEFAULT_GENERAL_GPT5_MODEL,
470
+ pro: "gpt-5.4-pro",
471
+ mini: "gpt-5-mini",
472
+ nano: "gpt-5-nano",
473
+ },
474
+ 5: {
475
+ base: GPT_5_5_CANONICAL_MODEL,
476
+ pro: GPT_5_5_PRO_CANONICAL_MODEL,
477
+ mini: "gpt-5-mini",
478
+ nano: "gpt-5-nano",
479
+ },
480
+ };
481
+ const GENERAL_GPT5_STABLE_VARIANTS = GENERAL_GPT5_VERSION_CATALOG[4];
482
+ const GENERAL_GPT5_GENERIC_VARIANTS = {
483
+ base: DEFAULT_GENERAL_GPT5_MODEL,
484
+ pro: "gpt-5-pro",
485
+ mini: "gpt-5-mini",
486
+ nano: "gpt-5-nano",
487
+ };
232
488
 
233
489
  function addRequestedModelAlias(alias, normalizedModel) {
234
490
  REQUESTED_MODEL_ALIASES.set(alias, normalizedModel);
@@ -316,6 +572,22 @@ function renameFileWithRetry(sourcePath, destinationPath, expectedDestinationSta
316
572
  }
317
573
 
318
574
  function seedRequestedModelAliases() {
575
+ addRequestedModelReasoningAliases(
576
+ GPT_5_5_CANONICAL_MODEL,
577
+ GPT_5_5_CANONICAL_MODEL,
578
+ );
579
+ addRequestedModelReasoningAliases(
580
+ GPT_5_5_RELEASE_MODEL,
581
+ GPT_5_5_CANONICAL_MODEL,
582
+ );
583
+ addRequestedModelReasoningAliases(
584
+ GPT_5_5_PRO_CANONICAL_MODEL,
585
+ GPT_5_5_PRO_CANONICAL_MODEL,
586
+ );
587
+ addRequestedModelReasoningAliases(
588
+ GPT_5_5_PRO_RELEASE_MODEL,
589
+ GPT_5_5_PRO_CANONICAL_MODEL,
590
+ );
319
591
  addRequestedModelReasoningAliases("gpt-5.4", "gpt-5.4");
320
592
  addRequestedModelReasoningAliases("gpt-5.4-pro", "gpt-5.4-pro");
321
593
  addRequestedModelReasoningAliases("gpt-5.2-pro", "gpt-5.2-pro");
@@ -350,15 +622,41 @@ function stripProviderPrefix(model) {
350
622
  : model;
351
623
  }
352
624
 
353
- function normalizeRequestedModel(model) {
354
- const stripped = stripProviderPrefix(model ?? "");
355
- const normalized = stripped.trim().toLowerCase();
356
- if (normalized.length === 0) return "";
357
- const exactMatch = REQUESTED_MODEL_ALIASES.get(normalized);
358
- if (exactMatch) {
359
- return exactMatch;
625
+ function tokenizeRequestedModel(model) {
626
+ return String(model ?? "")
627
+ .toLowerCase()
628
+ .split(/[^a-z0-9]+/)
629
+ .filter(Boolean);
630
+ }
631
+
632
+ function getGeneralGpt5CatalogForMinor(minor) {
633
+ switch (minor) {
634
+ case 1:
635
+ case 2:
636
+ case 4:
637
+ case 5:
638
+ return GENERAL_GPT5_VERSION_CATALOG[minor];
639
+ default:
640
+ return undefined;
360
641
  }
642
+ }
643
+
644
+ function resolveGeneralGpt5CatalogVariant(catalog, variant) {
645
+ return catalog?.[variant] ?? catalog?.base;
646
+ }
361
647
 
648
+ function resolveStableGeneralGpt5Variant(variant) {
649
+ const fallback = (
650
+ GENERAL_GPT5_STABLE_VARIANTS[variant] ??
651
+ GENERAL_GPT5_STABLE_VARIANTS.base
652
+ );
653
+ if (!fallback) {
654
+ throw new Error(`Stable GPT-5 fallback is missing for variant ${variant}`);
655
+ }
656
+ return fallback;
657
+ }
658
+
659
+ function resolveCodexRequestedModel(normalized) {
362
660
  if (
363
661
  normalized.includes("gpt-5.1-codex-max") ||
364
662
  normalized.includes("gpt 5.1 codex max") ||
@@ -390,51 +688,63 @@ function normalizeRequestedModel(model) {
390
688
  ) {
391
689
  return "gpt-5-codex";
392
690
  }
393
- if (normalized.includes("gpt-5.4-pro") || normalized.includes("gpt 5.4 pro")) {
394
- return "gpt-5.4-pro";
395
- }
396
- if (normalized.includes("gpt-5.2-pro") || normalized.includes("gpt 5.2 pro")) {
397
- return "gpt-5.2-pro";
398
- }
399
- if (normalized.includes("gpt-5-pro") || normalized.includes("gpt 5 pro")) {
400
- return "gpt-5-pro";
401
- }
402
- if (
403
- normalized.includes("gpt-5.4-mini") ||
404
- normalized.includes("gpt 5.4 mini") ||
405
- normalized.includes("gpt-5-mini") ||
406
- normalized.includes("gpt 5 mini")
407
- ) {
408
- return "gpt-5-mini";
409
- }
410
- if (
411
- normalized.includes("gpt-5.4-nano") ||
412
- normalized.includes("gpt 5.4 nano") ||
413
- normalized.includes("gpt-5-nano") ||
414
- normalized.includes("gpt 5 nano")
415
- ) {
416
- return "gpt-5-nano";
417
- }
418
- if (normalized.includes("gpt-5.4") || normalized.includes("gpt 5.4")) {
419
- return "gpt-5.4";
691
+
692
+ return "";
693
+ }
694
+
695
+ function resolveGeneralGpt5RequestedModel(stripped) {
696
+ const tokens = tokenizeRequestedModel(stripped);
697
+ const gptIndex = tokens.indexOf("gpt");
698
+ const isGpt5 = gptIndex !== -1 && tokens[gptIndex + 1] === "5";
699
+ if (!isGpt5 || tokens.includes("codex")) {
700
+ return "";
701
+ }
702
+
703
+ const rawMinor = tokens[gptIndex + 2];
704
+ const minor =
705
+ typeof rawMinor === "string" && /^\d+$/.test(rawMinor)
706
+ ? Number(rawMinor)
707
+ : undefined;
708
+ const variant = tokens.includes("mini")
709
+ ? "mini"
710
+ : tokens.includes("nano")
711
+ ? "nano"
712
+ : tokens.includes("pro")
713
+ ? "pro"
714
+ : "base";
715
+
716
+ if (minor === undefined) {
717
+ return GENERAL_GPT5_GENERIC_VARIANTS[variant];
718
+ }
719
+
720
+ const exactCatalog = getGeneralGpt5CatalogForMinor(minor);
721
+ const exactMatch = resolveGeneralGpt5CatalogVariant(exactCatalog, variant);
722
+ if (exactMatch) {
723
+ return exactMatch;
420
724
  }
421
- if (normalized.includes("gpt-5.2") || normalized.includes("gpt 5.2")) {
422
- return "gpt-5.2";
725
+
726
+ return resolveStableGeneralGpt5Variant(variant);
727
+ }
728
+
729
+ function normalizeRequestedModel(model) {
730
+ const stripped = stripProviderPrefix(model ?? "");
731
+ const normalized = stripped.trim().toLowerCase();
732
+ if (normalized.length === 0) return "";
733
+ const exactMatch = REQUESTED_MODEL_ALIASES.get(normalized);
734
+ if (exactMatch) {
735
+ return exactMatch;
423
736
  }
424
- if (
425
- normalized.includes("gpt-5.1-chat-latest") ||
426
- normalized.includes("gpt-5.1") ||
427
- normalized.includes("gpt 5.1")
428
- ) {
429
- return "gpt-5.1";
737
+
738
+ const codexModel = resolveCodexRequestedModel(normalized);
739
+ if (codexModel) {
740
+ return codexModel;
430
741
  }
431
- if (
432
- normalized === "gpt-5-chat-latest" ||
433
- normalized === "gpt-5" ||
434
- normalized.includes("gpt 5")
435
- ) {
436
- return "gpt-5";
742
+
743
+ const generalModel = resolveGeneralGpt5RequestedModel(stripped);
744
+ if (generalModel) {
745
+ return generalModel;
437
746
  }
747
+
438
748
  return "";
439
749
  }
440
750
 
@@ -1334,18 +1644,8 @@ async function main() {
1334
1644
  }
1335
1645
 
1336
1646
  await autoSyncManagerActiveSelectionIfEnabled();
1337
- const { args: forwardArgs, requestedModel } = buildForwardArgs(rawArgs);
1338
- const compatibility = createCompatibilityCodexHome(
1339
- forwardArgs,
1340
- requestedModel,
1341
- );
1342
1647
  return withForwardedRuntimeObservability(rawArgs, () =>
1343
- forwardToRealCodex(
1344
- realCodexBin,
1345
- compatibility.args,
1346
- compatibility.env,
1347
- compatibility.cleanup,
1348
- ),
1648
+ forwardToRealCodex(realCodexBin, rawArgs),
1349
1649
  );
1350
1650
  }
1351
1651
 
@@ -1,72 +0,0 @@
1
- import { promptLoginMode, type ExistingAccountInfo } from "../cli.js";
2
- import { type DashboardDisplaySettings } from "../dashboard-settings.js";
3
- import { type QuotaCacheData } from "../quota-cache.js";
4
- import { type AccountMetadataV3, type AccountStorageV3, type NamedBackupSummary } from "../storage.js";
5
- import type { AccountIdSource, TokenResult } from "../types.js";
6
- import { type ModelFamily } from "../prompts/codex.js";
7
- type PromptTone = "accent" | "success" | "warning" | "danger" | "muted";
8
- type TokenSuccess = Extract<TokenResult, {
9
- type: "success";
10
- }>;
11
- type TokenSuccessWithAccount = TokenSuccess & {
12
- accountIdOverride?: string;
13
- accountIdSource?: AccountIdSource;
14
- accountLabel?: string;
15
- };
16
- type OAuthSignInMode = "browser" | "manual" | "restore-backup" | "cancel";
17
- type BackupRestoreMode = "latest" | "manual" | "back";
18
- type LoginMenuResult = Awaited<ReturnType<typeof promptLoginMode>>;
19
- type HealthCheckOptions = {
20
- forceRefresh?: boolean;
21
- liveProbe?: boolean;
22
- };
23
- export interface AuthCommandHelpers {
24
- resolveActiveIndex: (storage: AccountStorageV3, family?: ModelFamily) => number;
25
- hasUsableAccessToken: (account: AccountMetadataV3, now: number) => boolean;
26
- applyTokenAccountIdentity: (account: {
27
- accountId?: string;
28
- accountIdSource?: AccountIdSource;
29
- }, tokenAccountId: string | undefined) => boolean;
30
- normalizeFailureDetail: (message: string | undefined, reason: string | undefined) => string;
31
- }
32
- export interface AuthLoginCommandDeps extends AuthCommandHelpers {
33
- stylePromptText: (text: string, tone: PromptTone) => string;
34
- runActionPanel: (title: string, stage: string, action: () => Promise<void> | void, settings?: DashboardDisplaySettings) => Promise<void>;
35
- toExistingAccountInfo: (storage: AccountStorageV3, cache: QuotaCacheData, settings: DashboardDisplaySettings) => ExistingAccountInfo[];
36
- countMenuQuotaRefreshTargets: (storage: AccountStorageV3, cache: QuotaCacheData, maxAgeMs: number) => number;
37
- defaultMenuQuotaRefreshTtlMs: number;
38
- refreshQuotaCacheForMenu: (storage: AccountStorageV3, cache: QuotaCacheData, maxAgeMs: number, onProgress?: (current: number, total: number) => void) => Promise<QuotaCacheData>;
39
- clearAccountsAndReset: () => Promise<void>;
40
- handleManageAction: (storage: AccountStorageV3, menuResult: LoginMenuResult) => Promise<void>;
41
- promptOAuthSignInMode: (backupOption: NamedBackupSummary | null, backupDiscoveryWarning?: string | null) => Promise<OAuthSignInMode>;
42
- promptBackupRestoreMode: (latestBackup: NamedBackupSummary) => Promise<BackupRestoreMode>;
43
- promptManualBackupSelection: (namedBackups: NamedBackupSummary[]) => Promise<NamedBackupSummary | null>;
44
- runOAuthFlow: (forceNewLogin: boolean, signInMode: Extract<OAuthSignInMode, "browser" | "manual">) => Promise<TokenResult>;
45
- resolveAccountSelection: (tokens: TokenSuccess) => TokenSuccessWithAccount;
46
- persistAccountPool: (tokens: TokenSuccessWithAccount[], preserveActiveIndexByFamily: boolean) => Promise<void>;
47
- syncSelectionToCodex: (tokens: TokenSuccessWithAccount) => Promise<void>;
48
- runHealthCheck: (options: HealthCheckOptions) => Promise<void>;
49
- runForecast: (args: string[]) => Promise<number>;
50
- runFix: (args: string[]) => Promise<number>;
51
- runVerifyFlagged: (args: string[]) => Promise<number>;
52
- log: {
53
- debug: (message: string, meta?: unknown) => void;
54
- };
55
- }
56
- export declare function persistAndSyncSelectedAccount({ storage, targetIndex, parsed, switchReason, initialSyncIdToken, preserveActiveIndexByFamily, helpers, }: {
57
- storage: AccountStorageV3;
58
- targetIndex: number;
59
- parsed: number;
60
- switchReason: "rotation" | "best" | "restore";
61
- initialSyncIdToken?: string;
62
- preserveActiveIndexByFamily?: boolean;
63
- helpers: AuthCommandHelpers;
64
- }): Promise<{
65
- synced: boolean;
66
- wasDisabled: boolean;
67
- }>;
68
- export declare function runSwitch(args: string[], helpers: AuthCommandHelpers): Promise<number>;
69
- export declare function runBest(args: string[], helpers: AuthCommandHelpers): Promise<number>;
70
- export declare function runAuthLogin(args: string[], deps: AuthLoginCommandDeps): Promise<number>;
71
- export {};
72
- //# sourceMappingURL=auth-commands.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-commands.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/auth-commands.ts"],"names":[],"mappings":"AAOA,OAAO,EAA2B,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAE/F,OAAO,EAEN,KAAK,wBAAwB,EAC7B,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxE,OAAO,EAUN,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,eAAe,EAAgB,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAevE,KAAK,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACxE,KAAK,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAC9D,KAAK,uBAAuB,GAAG,YAAY,GAAG;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AACF,KAAK,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAC1E,KAAK,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACtD,KAAK,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC;AACnE,KAAK,kBAAkB,GAAG;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAM1E,MAAM,WAAW,kBAAkB;IAClC,kBAAkB,EAAE,CACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,WAAW,KAChB,MAAM,CAAC;IACZ,oBAAoB,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3E,yBAAyB,EAAE,CAC1B,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,eAAe,CAAA;KAAE,EAClE,cAAc,EAAE,MAAM,GAAG,SAAS,KAC9B,OAAO,CAAC;IACb,sBAAsB,EAAE,CACvB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,KACtB,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,oBAAqB,SAAQ,kBAAkB;IAC/D,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC;IAC5D,cAAc,EAAE,CACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAClC,QAAQ,CAAC,EAAE,wBAAwB,KAC/B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,qBAAqB,EAAE,CACtB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,wBAAwB,KAC9B,mBAAmB,EAAE,CAAC;IAC3B,4BAA4B,EAAE,CAC7B,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,KACZ,MAAM,CAAC;IACZ,4BAA4B,EAAE,MAAM,CAAC;IACrC,wBAAwB,EAAE,CACzB,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,KACjD,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,kBAAkB,EAAE,CACnB,OAAO,EAAE,gBAAgB,EACzB,UAAU,EAAE,eAAe,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,qBAAqB,EAAE,CACtB,YAAY,EAAE,kBAAkB,GAAG,IAAI,EACvC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,KAClC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,uBAAuB,EAAE,CACxB,YAAY,EAAE,kBAAkB,KAC5B,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChC,2BAA2B,EAAE,CAC5B,YAAY,EAAE,kBAAkB,EAAE,KAC9B,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACxC,YAAY,EAAE,CACb,aAAa,EAAE,OAAO,EACtB,UAAU,EAAE,OAAO,CAAC,eAAe,EAAE,SAAS,GAAG,QAAQ,CAAC,KACtD,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,uBAAuB,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,uBAAuB,CAAC;IAC3E,kBAAkB,EAAE,CACnB,MAAM,EAAE,uBAAuB,EAAE,EACjC,2BAA2B,EAAE,OAAO,KAChC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,oBAAoB,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE,cAAc,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtD,GAAG,EAAE;QACJ,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KACjD,CAAC;CACF;AA6DD,wBAAsB,6BAA6B,CAAC,EACnD,OAAO,EACP,WAAW,EACX,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,2BAAmC,EACnC,OAAO,GACP,EAAE;IACF,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,OAAO,EAAE,kBAAkB,CAAC;CAC5B,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,OAAO,CAAA;CAAE,CAAC,CA8DrD;AAED,wBAAsB,SAAS,CAC9B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,wBAAsB,OAAO,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,kBAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAiPjB;AAED,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,oBAAoB,GACxB,OAAO,CAAC,MAAM,CAAC,CA8SjB"}