codex-multi-auth 1.2.6 → 1.3.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.
Files changed (118) hide show
  1. package/README.md +30 -18
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +41 -21
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/accounts.d.ts +47 -0
  6. package/dist/lib/accounts.d.ts.map +1 -1
  7. package/dist/lib/accounts.js +219 -33
  8. package/dist/lib/accounts.js.map +1 -1
  9. package/dist/lib/auth/auth.d.ts +16 -0
  10. package/dist/lib/auth/auth.d.ts.map +1 -1
  11. package/dist/lib/auth/auth.js +52 -6
  12. package/dist/lib/auth/auth.js.map +1 -1
  13. package/dist/lib/auth/server.d.ts +1 -1
  14. package/dist/lib/auth/server.d.ts.map +1 -1
  15. package/dist/lib/auth/server.js +10 -8
  16. package/dist/lib/auth/server.js.map +1 -1
  17. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  18. package/dist/lib/codex-manager/commands/status.js +13 -5
  19. package/dist/lib/codex-manager/commands/status.js.map +1 -1
  20. package/dist/lib/codex-manager/commands/verify.d.ts +59 -0
  21. package/dist/lib/codex-manager/commands/verify.d.ts.map +1 -0
  22. package/dist/lib/codex-manager/commands/verify.js +332 -0
  23. package/dist/lib/codex-manager/commands/verify.js.map +1 -0
  24. package/dist/lib/codex-manager/commands/why-selected.d.ts +57 -0
  25. package/dist/lib/codex-manager/commands/why-selected.d.ts.map +1 -0
  26. package/dist/lib/codex-manager/commands/why-selected.js +198 -0
  27. package/dist/lib/codex-manager/commands/why-selected.js.map +1 -0
  28. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  29. package/dist/lib/codex-manager/help.js +4 -0
  30. package/dist/lib/codex-manager/help.js.map +1 -1
  31. package/dist/lib/codex-manager/settings-hub/backend.d.ts +9 -0
  32. package/dist/lib/codex-manager/settings-hub/backend.d.ts.map +1 -0
  33. package/dist/lib/codex-manager/settings-hub/backend.js +79 -0
  34. package/dist/lib/codex-manager/settings-hub/backend.js.map +1 -0
  35. package/dist/lib/codex-manager/settings-hub/dashboard.d.ts +24 -0
  36. package/dist/lib/codex-manager/settings-hub/dashboard.d.ts.map +1 -0
  37. package/dist/lib/codex-manager/settings-hub/dashboard.js +223 -0
  38. package/dist/lib/codex-manager/settings-hub/dashboard.js.map +1 -0
  39. package/dist/lib/codex-manager/settings-hub/experimental.d.ts +18 -0
  40. package/dist/lib/codex-manager/settings-hub/experimental.d.ts.map +1 -0
  41. package/dist/lib/codex-manager/settings-hub/experimental.js +78 -0
  42. package/dist/lib/codex-manager/settings-hub/experimental.js.map +1 -0
  43. package/dist/lib/codex-manager/settings-hub/index.d.ts +34 -0
  44. package/dist/lib/codex-manager/settings-hub/index.d.ts.map +1 -0
  45. package/dist/lib/codex-manager/settings-hub/index.js +81 -0
  46. package/dist/lib/codex-manager/settings-hub/index.js.map +1 -0
  47. package/dist/lib/codex-manager/settings-hub/shared.d.ts +40 -0
  48. package/dist/lib/codex-manager/settings-hub/shared.d.ts.map +1 -0
  49. package/dist/lib/codex-manager/settings-hub/shared.js +103 -0
  50. package/dist/lib/codex-manager/settings-hub/shared.js.map +1 -0
  51. package/dist/lib/codex-manager/settings-hub.d.ts +1 -64
  52. package/dist/lib/codex-manager/settings-hub.d.ts.map +1 -1
  53. package/dist/lib/codex-manager/settings-hub.js +4 -515
  54. package/dist/lib/codex-manager/settings-hub.js.map +1 -1
  55. package/dist/lib/codex-manager.d.ts.map +1 -1
  56. package/dist/lib/codex-manager.js +95 -13
  57. package/dist/lib/codex-manager.js.map +1 -1
  58. package/dist/lib/config.d.ts +14 -0
  59. package/dist/lib/config.d.ts.map +1 -1
  60. package/dist/lib/config.js +21 -9
  61. package/dist/lib/config.js.map +1 -1
  62. package/dist/lib/health.d.ts.map +1 -1
  63. package/dist/lib/health.js.map +1 -1
  64. package/dist/lib/recovery/storage.d.ts.map +1 -1
  65. package/dist/lib/recovery/storage.js +112 -8
  66. package/dist/lib/recovery/storage.js.map +1 -1
  67. package/dist/lib/request/response-handler.d.ts.map +1 -1
  68. package/dist/lib/request/response-handler.js +67 -23
  69. package/dist/lib/request/response-handler.js.map +1 -1
  70. package/dist/lib/rotation.d.ts +53 -1
  71. package/dist/lib/rotation.d.ts.map +1 -1
  72. package/dist/lib/rotation.js +135 -23
  73. package/dist/lib/rotation.js.map +1 -1
  74. package/dist/lib/routing-mutex.d.ts +107 -0
  75. package/dist/lib/routing-mutex.d.ts.map +1 -0
  76. package/dist/lib/routing-mutex.js +104 -0
  77. package/dist/lib/routing-mutex.js.map +1 -0
  78. package/dist/lib/runtime/storage-scope.d.ts.map +1 -1
  79. package/dist/lib/runtime/storage-scope.js +17 -1
  80. package/dist/lib/runtime/storage-scope.js.map +1 -1
  81. package/dist/lib/schemas.d.ts +125 -0
  82. package/dist/lib/schemas.d.ts.map +1 -1
  83. package/dist/lib/schemas.js +139 -5
  84. package/dist/lib/schemas.js.map +1 -1
  85. package/dist/lib/storage/account-clear.d.ts.map +1 -1
  86. package/dist/lib/storage/account-clear.js +7 -1
  87. package/dist/lib/storage/account-clear.js.map +1 -1
  88. package/dist/lib/storage/flagged-storage-file.d.ts.map +1 -1
  89. package/dist/lib/storage/flagged-storage-file.js +17 -1
  90. package/dist/lib/storage/flagged-storage-file.js.map +1 -1
  91. package/dist/lib/storage/flagged-storage-io.d.ts.map +1 -1
  92. package/dist/lib/storage/flagged-storage-io.js +24 -10
  93. package/dist/lib/storage/flagged-storage-io.js.map +1 -1
  94. package/dist/lib/storage/import-export.d.ts.map +1 -1
  95. package/dist/lib/storage/import-export.js +16 -4
  96. package/dist/lib/storage/import-export.js.map +1 -1
  97. package/dist/lib/storage/paths.d.ts.map +1 -1
  98. package/dist/lib/storage/paths.js +62 -7
  99. package/dist/lib/storage/paths.js.map +1 -1
  100. package/dist/lib/storage/snapshot-inspectors.d.ts.map +1 -1
  101. package/dist/lib/storage/snapshot-inspectors.js +23 -16
  102. package/dist/lib/storage/snapshot-inspectors.js.map +1 -1
  103. package/dist/lib/storage/storage-parser.d.ts +17 -0
  104. package/dist/lib/storage/storage-parser.d.ts.map +1 -1
  105. package/dist/lib/storage/storage-parser.js +30 -1
  106. package/dist/lib/storage/storage-parser.js.map +1 -1
  107. package/dist/lib/storage.d.ts +1 -1
  108. package/dist/lib/storage.d.ts.map +1 -1
  109. package/dist/lib/storage.js +45 -26
  110. package/dist/lib/storage.js.map +1 -1
  111. package/dist/lib/ui/copy.d.ts +1 -1
  112. package/dist/lib/ui/copy.d.ts.map +1 -1
  113. package/dist/lib/ui/copy.js +2 -1
  114. package/dist/lib/ui/copy.js.map +1 -1
  115. package/package.json +5 -5
  116. package/scripts/codex-bin-resolver.js +162 -7
  117. package/scripts/codex-multi-auth.js +1 -1
  118. package/scripts/codex.js +233 -226
package/scripts/codex.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { spawn } from "node:child_process";
4
4
  import {
@@ -18,7 +18,10 @@ import { homedir, tmpdir } from "node:os";
18
18
  import { basename, delimiter, dirname, join, resolve as resolvePath } from "node:path";
19
19
  import process from "node:process";
20
20
  import { fileURLToPath } from "node:url";
21
- import { resolveRealCodexBin as resolveRealCodexBinFromEnvironment } from "./codex-bin-resolver.js";
21
+ import {
22
+ resolveRealCodexBin as resolveRealCodexBinFromEnvironment,
23
+ splitPathEntries,
24
+ } from "./codex-bin-resolver.js";
22
25
  import { normalizeAuthAlias, shouldHandleMultiAuthAuth } from "./codex-routing.js";
23
26
 
24
27
  const RETRYABLE_SHADOW_HOME_CLEANUP_CODES = new Set(["EBUSY", "EPERM", "ENOTEMPTY"]);
@@ -124,11 +127,17 @@ async function autoSyncManagerActiveSelectionIfEnabled() {
124
127
  function resolveRealCodexBin() {
125
128
  const override = (process.env.CODEX_MULTI_AUTH_REAL_CODEX_BIN ?? "").trim();
126
129
  if (override.length > 0) {
127
- if (existsSync(override)) return override;
128
- console.error(
129
- `CODEX_MULTI_AUTH_REAL_CODEX_BIN is set but missing: ${override}`,
130
- );
131
- return null;
130
+ if (!existsSync(override)) {
131
+ console.error(
132
+ `CODEX_MULTI_AUTH_REAL_CODEX_BIN is set but missing: ${override}`,
133
+ );
134
+ return null;
135
+ }
136
+ return resolveRealCodexBinFromEnvironment({
137
+ moduleUrl: import.meta.url,
138
+ env: process.env,
139
+ existsSyncImpl: existsSync,
140
+ });
132
141
  }
133
142
 
134
143
  return resolveRealCodexBinFromEnvironment({ moduleUrl: import.meta.url });
@@ -145,7 +154,9 @@ function forwardToRealCodex(codexBin, args, env = process.env, cleanup) {
145
154
  resolve(exitCode);
146
155
  };
147
156
 
148
- const child = spawn(process.execPath, [codexBin, ...args], {
157
+ const command = codexBin.launchWithNode ? process.execPath : codexBin.path;
158
+ const commandArgs = codexBin.launchWithNode ? [codexBin.path, ...args] : args;
159
+ const child = spawn(command, commandArgs, {
149
160
  stdio: "inherit",
150
161
  env,
151
162
  });
@@ -653,201 +664,201 @@ function rewriteConfigTomlReasoningEffort(rawConfig, requestedModel) {
653
664
  return ensureTrailingNewline(nextLines.join(lineEnding));
654
665
  }
655
666
 
656
- function resolveOriginalMultiAuthDir(env) {
657
- const explicit = (env.CODEX_MULTI_AUTH_DIR ?? "").trim();
658
- if (explicit.length > 0) {
659
- return explicit;
660
- }
661
- return undefined;
662
- }
663
-
664
- async function loadRuntimeObservabilityModule() {
665
- try {
666
- const mod = await import("../dist/lib/runtime/runtime-observability.js");
667
- if (
668
- typeof mod.loadPersistedRuntimeObservabilitySnapshot !== "function" ||
669
- typeof mod.mutateRuntimeObservabilitySnapshot !== "function"
670
- ) {
671
- return null;
672
- }
673
- return mod;
674
- } catch (error) {
675
- if (
676
- error &&
677
- typeof error === "object" &&
678
- "code" in error &&
679
- error.code === "ERR_MODULE_NOT_FOUND"
680
- ) {
681
- return null;
682
- }
683
- throw error;
684
- }
685
- }
686
-
687
- function isPureHelpOrVersionArgs(rawArgs) {
688
- if (!Array.isArray(rawArgs) || rawArgs.length === 0) {
689
- return false;
690
- }
691
- return rawArgs.every((arg) =>
692
- typeof arg === "string" && ["--help", "-h", "--version", "-V"].includes(arg),
693
- );
694
- }
695
-
696
- function consumesNextArg(arg) {
697
- return new Set([
698
- "-c",
699
- "--config",
700
- "--enable",
701
- "--disable",
702
- "--remote",
703
- "--remote-auth-token-env",
704
- "-i",
705
- "--image",
706
- "-m",
707
- "--model",
708
- "--local-provider",
709
- "-p",
710
- "--profile",
711
- "-s",
712
- "--sandbox",
713
- "-a",
714
- "--ask-for-approval",
715
- "-C",
716
- "--cd",
717
- "--add-dir",
718
- "--output-schema",
719
- "--color",
720
- "-o",
721
- "--output-last-message",
722
- ]).has(arg);
723
- }
724
-
725
- function shouldTrackForwardedRuntimeObservability(rawArgs) {
726
- if (!Array.isArray(rawArgs) || rawArgs.length === 0) {
727
- return true;
728
- }
729
- if (isPureHelpOrVersionArgs(rawArgs)) {
730
- return false;
731
- }
732
-
733
- const requestCommands = new Set(["exec", "review", "resume", "fork"]);
734
- const nonRequestCommands = new Set([
735
- "help",
736
- "completion",
737
- "login",
738
- "logout",
739
- "mcp",
740
- "mcp-server",
741
- "app-server",
742
- "sandbox",
743
- "debug",
744
- "apply",
745
- "cloud",
746
- "features",
747
- "auth",
748
- ]);
749
-
750
- for (let i = 0; i < rawArgs.length; i += 1) {
751
- const arg = rawArgs[i];
752
- if (typeof arg !== "string" || arg.length === 0) continue;
753
- if (arg === "--") {
754
- return i + 1 < rawArgs.length;
755
- }
756
- if (arg.startsWith("--config=")) {
757
- continue;
758
- }
759
- if (arg.startsWith("--") || (arg.startsWith("-") && arg !== "-")) {
760
- if (consumesNextArg(arg)) {
761
- i += 1;
762
- }
763
- continue;
764
- }
765
- if (requestCommands.has(arg)) {
766
- return true;
767
- }
768
- if (nonRequestCommands.has(arg)) {
769
- return false;
770
- }
771
- return true;
772
- }
773
-
774
- return true;
775
- }
776
-
777
- function createRuntimeSnapshotChangeToken(snapshot) {
778
- return JSON.stringify({
779
- updatedAt: snapshot?.updatedAt ?? null,
780
- responsesRequests: snapshot?.responsesRequests ?? null,
781
- authRefreshRequests: snapshot?.authRefreshRequests ?? null,
782
- diagnosticProbeRequests: snapshot?.diagnosticProbeRequests ?? null,
783
- totalRequests: snapshot?.runtimeMetrics?.totalRequests ?? null,
784
- successfulRequests: snapshot?.runtimeMetrics?.successfulRequests ?? null,
785
- failedRequests: snapshot?.runtimeMetrics?.failedRequests ?? null,
786
- lastRequestAt: snapshot?.runtimeMetrics?.lastRequestAt ?? null,
787
- });
788
- }
789
-
790
- async function loadRuntimeSnapshotWithRetry(runtimeObservabilityModule) {
791
- let snapshot = null;
792
- for (let attempt = 0; attempt < 5; attempt += 1) {
793
- snapshot =
794
- (await runtimeObservabilityModule.loadPersistedRuntimeObservabilitySnapshot()) ??
795
- null;
796
- if (snapshot) {
797
- return snapshot;
798
- }
799
- if (attempt < 4) {
800
- await new Promise((resolve) => setTimeout(resolve, 20));
801
- }
802
- }
803
- return snapshot;
804
- }
805
-
806
- async function withForwardedRuntimeObservability(rawArgs, runForwardedCommand) {
807
- if (!shouldTrackForwardedRuntimeObservability(rawArgs)) {
808
- return runForwardedCommand();
809
- }
810
-
811
- const runtimeObservabilityModule = await loadRuntimeObservabilityModule();
812
- if (!runtimeObservabilityModule) {
813
- return runForwardedCommand();
814
- }
815
-
816
- const beforeSnapshot = await loadRuntimeSnapshotWithRetry(runtimeObservabilityModule);
817
- const beforeToken = createRuntimeSnapshotChangeToken(beforeSnapshot);
818
- const startedAt = Date.now();
819
- const exitCode = await runForwardedCommand();
820
- const afterSnapshot = await loadRuntimeSnapshotWithRetry(runtimeObservabilityModule);
821
- const afterToken = createRuntimeSnapshotChangeToken(afterSnapshot);
822
- if (afterToken !== beforeToken) {
823
- return exitCode;
824
- }
825
-
826
- runtimeObservabilityModule.mutateRuntimeObservabilitySnapshot((snapshot) => {
827
- snapshot.currentRequestId = null;
828
- snapshot.responsesRequests += 1;
829
- snapshot.runtimeMetrics.totalRequests += 1;
830
- snapshot.runtimeMetrics.responsesRequests += 1;
831
- snapshot.runtimeMetrics.cumulativeLatencyMs += Math.max(0, Date.now() - startedAt);
832
- snapshot.runtimeMetrics.lastRequestAt = Date.now();
833
- if (!snapshot.runtimeMetrics.startedAt) {
834
- snapshot.runtimeMetrics.startedAt = startedAt;
835
- }
836
- if (exitCode === 0) {
837
- snapshot.runtimeMetrics.successfulRequests += 1;
838
- snapshot.runtimeMetrics.lastError = null;
839
- } else {
840
- snapshot.runtimeMetrics.failedRequests += 1;
841
- snapshot.runtimeMetrics.lastError = `forwarded-codex-exit:${exitCode}`;
842
- }
843
- });
844
- return exitCode;
845
- }
846
-
847
- function createCompatibilityCodexHome(
848
- processedArgs,
849
- requestedModel,
850
- baseEnv = process.env,
667
+ function resolveOriginalMultiAuthDir(env) {
668
+ const explicit = (env.CODEX_MULTI_AUTH_DIR ?? "").trim();
669
+ if (explicit.length > 0) {
670
+ return explicit;
671
+ }
672
+ return undefined;
673
+ }
674
+
675
+ async function loadRuntimeObservabilityModule() {
676
+ try {
677
+ const mod = await import("../dist/lib/runtime/runtime-observability.js");
678
+ if (
679
+ typeof mod.loadPersistedRuntimeObservabilitySnapshot !== "function" ||
680
+ typeof mod.mutateRuntimeObservabilitySnapshot !== "function"
681
+ ) {
682
+ return null;
683
+ }
684
+ return mod;
685
+ } catch (error) {
686
+ if (
687
+ error &&
688
+ typeof error === "object" &&
689
+ "code" in error &&
690
+ error.code === "ERR_MODULE_NOT_FOUND"
691
+ ) {
692
+ return null;
693
+ }
694
+ throw error;
695
+ }
696
+ }
697
+
698
+ function isPureHelpOrVersionArgs(rawArgs) {
699
+ if (!Array.isArray(rawArgs) || rawArgs.length === 0) {
700
+ return false;
701
+ }
702
+ return rawArgs.every((arg) =>
703
+ typeof arg === "string" && ["--help", "-h", "--version", "-V"].includes(arg),
704
+ );
705
+ }
706
+
707
+ function consumesNextArg(arg) {
708
+ return new Set([
709
+ "-c",
710
+ "--config",
711
+ "--enable",
712
+ "--disable",
713
+ "--remote",
714
+ "--remote-auth-token-env",
715
+ "-i",
716
+ "--image",
717
+ "-m",
718
+ "--model",
719
+ "--local-provider",
720
+ "-p",
721
+ "--profile",
722
+ "-s",
723
+ "--sandbox",
724
+ "-a",
725
+ "--ask-for-approval",
726
+ "-C",
727
+ "--cd",
728
+ "--add-dir",
729
+ "--output-schema",
730
+ "--color",
731
+ "-o",
732
+ "--output-last-message",
733
+ ]).has(arg);
734
+ }
735
+
736
+ function shouldTrackForwardedRuntimeObservability(rawArgs) {
737
+ if (!Array.isArray(rawArgs) || rawArgs.length === 0) {
738
+ return true;
739
+ }
740
+ if (isPureHelpOrVersionArgs(rawArgs)) {
741
+ return false;
742
+ }
743
+
744
+ const requestCommands = new Set(["exec", "review", "resume", "fork"]);
745
+ const nonRequestCommands = new Set([
746
+ "help",
747
+ "completion",
748
+ "login",
749
+ "logout",
750
+ "mcp",
751
+ "mcp-server",
752
+ "app-server",
753
+ "sandbox",
754
+ "debug",
755
+ "apply",
756
+ "cloud",
757
+ "features",
758
+ "auth",
759
+ ]);
760
+
761
+ for (let i = 0; i < rawArgs.length; i += 1) {
762
+ const arg = rawArgs[i];
763
+ if (typeof arg !== "string" || arg.length === 0) continue;
764
+ if (arg === "--") {
765
+ return i + 1 < rawArgs.length;
766
+ }
767
+ if (arg.startsWith("--config=")) {
768
+ continue;
769
+ }
770
+ if (arg.startsWith("--") || (arg.startsWith("-") && arg !== "-")) {
771
+ if (consumesNextArg(arg)) {
772
+ i += 1;
773
+ }
774
+ continue;
775
+ }
776
+ if (requestCommands.has(arg)) {
777
+ return true;
778
+ }
779
+ if (nonRequestCommands.has(arg)) {
780
+ return false;
781
+ }
782
+ return true;
783
+ }
784
+
785
+ return true;
786
+ }
787
+
788
+ function createRuntimeSnapshotChangeToken(snapshot) {
789
+ return JSON.stringify({
790
+ updatedAt: snapshot?.updatedAt ?? null,
791
+ responsesRequests: snapshot?.responsesRequests ?? null,
792
+ authRefreshRequests: snapshot?.authRefreshRequests ?? null,
793
+ diagnosticProbeRequests: snapshot?.diagnosticProbeRequests ?? null,
794
+ totalRequests: snapshot?.runtimeMetrics?.totalRequests ?? null,
795
+ successfulRequests: snapshot?.runtimeMetrics?.successfulRequests ?? null,
796
+ failedRequests: snapshot?.runtimeMetrics?.failedRequests ?? null,
797
+ lastRequestAt: snapshot?.runtimeMetrics?.lastRequestAt ?? null,
798
+ });
799
+ }
800
+
801
+ async function loadRuntimeSnapshotWithRetry(runtimeObservabilityModule) {
802
+ let snapshot = null;
803
+ for (let attempt = 0; attempt < 5; attempt += 1) {
804
+ snapshot =
805
+ (await runtimeObservabilityModule.loadPersistedRuntimeObservabilitySnapshot()) ??
806
+ null;
807
+ if (snapshot) {
808
+ return snapshot;
809
+ }
810
+ if (attempt < 4) {
811
+ await new Promise((resolve) => setTimeout(resolve, 20));
812
+ }
813
+ }
814
+ return snapshot;
815
+ }
816
+
817
+ async function withForwardedRuntimeObservability(rawArgs, runForwardedCommand) {
818
+ if (!shouldTrackForwardedRuntimeObservability(rawArgs)) {
819
+ return runForwardedCommand();
820
+ }
821
+
822
+ const runtimeObservabilityModule = await loadRuntimeObservabilityModule();
823
+ if (!runtimeObservabilityModule) {
824
+ return runForwardedCommand();
825
+ }
826
+
827
+ const beforeSnapshot = await loadRuntimeSnapshotWithRetry(runtimeObservabilityModule);
828
+ const beforeToken = createRuntimeSnapshotChangeToken(beforeSnapshot);
829
+ const startedAt = Date.now();
830
+ const exitCode = await runForwardedCommand();
831
+ const afterSnapshot = await loadRuntimeSnapshotWithRetry(runtimeObservabilityModule);
832
+ const afterToken = createRuntimeSnapshotChangeToken(afterSnapshot);
833
+ if (afterToken !== beforeToken) {
834
+ return exitCode;
835
+ }
836
+
837
+ runtimeObservabilityModule.mutateRuntimeObservabilitySnapshot((snapshot) => {
838
+ snapshot.currentRequestId = null;
839
+ snapshot.responsesRequests += 1;
840
+ snapshot.runtimeMetrics.totalRequests += 1;
841
+ snapshot.runtimeMetrics.responsesRequests += 1;
842
+ snapshot.runtimeMetrics.cumulativeLatencyMs += Math.max(0, Date.now() - startedAt);
843
+ snapshot.runtimeMetrics.lastRequestAt = Date.now();
844
+ if (!snapshot.runtimeMetrics.startedAt) {
845
+ snapshot.runtimeMetrics.startedAt = startedAt;
846
+ }
847
+ if (exitCode === 0) {
848
+ snapshot.runtimeMetrics.successfulRequests += 1;
849
+ snapshot.runtimeMetrics.lastError = null;
850
+ } else {
851
+ snapshot.runtimeMetrics.failedRequests += 1;
852
+ snapshot.runtimeMetrics.lastError = `forwarded-codex-exit:${exitCode}`;
853
+ }
854
+ });
855
+ return exitCode;
856
+ }
857
+
858
+ function createCompatibilityCodexHome(
859
+ processedArgs,
860
+ requestedModel,
861
+ baseEnv = process.env,
851
862
  ) {
852
863
  if (!requestedModel) {
853
864
  return { args: processedArgs, env: baseEnv, cleanup: undefined };
@@ -993,16 +1004,6 @@ function shouldInstallWindowsBatchShimGuard() {
993
1004
  return override !== "0";
994
1005
  }
995
1006
 
996
- function splitPathEntries(pathValue) {
997
- if (typeof pathValue !== "string" || pathValue.trim().length === 0) {
998
- return [];
999
- }
1000
- return pathValue
1001
- .split(delimiter)
1002
- .map((entry) => entry.trim())
1003
- .filter((entry) => entry.length > 0);
1004
- }
1005
-
1006
1007
  function resolveWindowsShimDirectoryFromInvocation() {
1007
1008
  const invokedScript = (process.argv[1] ?? "").trim();
1008
1009
  if (invokedScript.length === 0) return null;
@@ -1138,7 +1139,13 @@ function ensureWindowsShellShim(filePath, desiredContent, options = {}) {
1138
1139
  }
1139
1140
  const looksLikeStockOpenAiShim =
1140
1141
  currentContent.includes("node_modules\\@openai\\codex\\bin\\codex.js") ||
1141
- currentContent.includes("node_modules/@openai/codex/bin/codex.js");
1142
+ currentContent.includes("node_modules/@openai/codex/bin/codex.js") ||
1143
+ currentContent.includes("@openai\\codex-win32-") ||
1144
+ currentContent.includes("@openai/codex-win32-") ||
1145
+ currentContent.includes("vendor\\x86_64-pc-windows-msvc\\codex\\codex.exe") ||
1146
+ currentContent.includes("vendor\\aarch64-pc-windows-msvc\\codex\\codex.exe") ||
1147
+ currentContent.includes("vendor/x86_64-pc-windows-msvc/codex/codex.exe") ||
1148
+ currentContent.includes("vendor/aarch64-pc-windows-msvc/codex/codex.exe");
1142
1149
  if (looksLikeStockOpenAiShim) {
1143
1150
  try {
1144
1151
  writeFileSync(filePath, desiredContent, { encoding: "utf8", mode: 0o755 });
@@ -1318,9 +1325,9 @@ async function main() {
1318
1325
  if (!realCodexBin) {
1319
1326
  console.error(
1320
1327
  [
1321
- "Could not locate the official Codex CLI binary (@openai/codex).",
1322
- "Install it globally: npm install -g @openai/codex",
1323
- "Or set CODEX_MULTI_AUTH_REAL_CODEX_BIN to a full bin/codex.js path.",
1328
+ "Could not locate the official Codex CLI.",
1329
+ "Install it with npm, Homebrew, or an official native release so `codex` is on PATH.",
1330
+ "Or set CODEX_MULTI_AUTH_REAL_CODEX_BIN to the full path of either codex or @openai/codex/bin/codex.js.",
1324
1331
  ].join("\n"),
1325
1332
  );
1326
1333
  return 1;
@@ -1332,15 +1339,15 @@ async function main() {
1332
1339
  forwardArgs,
1333
1340
  requestedModel,
1334
1341
  );
1335
- return withForwardedRuntimeObservability(rawArgs, () =>
1336
- forwardToRealCodex(
1337
- realCodexBin,
1338
- compatibility.args,
1339
- compatibility.env,
1340
- compatibility.cleanup,
1341
- ),
1342
- );
1343
- }
1342
+ return withForwardedRuntimeObservability(rawArgs, () =>
1343
+ forwardToRealCodex(
1344
+ realCodexBin,
1345
+ compatibility.args,
1346
+ compatibility.env,
1347
+ compatibility.cleanup,
1348
+ ),
1349
+ );
1350
+ }
1344
1351
 
1345
1352
  const exitCode = await main();
1346
1353
  process.exitCode = normalizeExitCode(exitCode);