codex-multi-auth 2.19.1 → 2.21.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 (79) hide show
  1. package/.codex-plugin/plugin.json +9 -9
  2. package/LICENSE +21 -21
  3. package/README.md +149 -148
  4. package/assets/codex-multi-auth-icon.svg +39 -39
  5. package/assets/readme-hero.svg +31 -31
  6. package/config/README.md +31 -31
  7. package/config/codex-legacy.json +1021 -1021
  8. package/config/codex-modern.json +347 -347
  9. package/config/minimal-codex.json +15 -15
  10. package/dist/index.js +1 -1
  11. package/dist/lib/accounts/rate-limits.js +5 -0
  12. package/dist/lib/accounts.js +5 -4
  13. package/dist/lib/auth/account-access.js +2 -2
  14. package/dist/lib/codex-cli/version.d.ts +22 -0
  15. package/dist/lib/codex-cli/version.js +78 -0
  16. package/dist/lib/codex-manager/commands/limits.d.ts +2 -0
  17. package/dist/lib/codex-manager/commands/limits.js +31 -0
  18. package/dist/lib/codex-manager/commands/status.js +1 -1
  19. package/dist/lib/codex-manager.js +2 -0
  20. package/dist/lib/constants.d.ts +2 -0
  21. package/dist/lib/constants.js +2 -0
  22. package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
  23. package/dist/lib/context-budget/model-context-windows.js +4 -0
  24. package/dist/lib/context-budget-response.js +8 -8
  25. package/dist/lib/context-overflow.js +10 -10
  26. package/dist/lib/luna-reserve.d.ts +26 -0
  27. package/dist/lib/luna-reserve.js +68 -0
  28. package/dist/lib/oauth-success.html +125 -125
  29. package/dist/lib/policy/runtime-policy.js +14 -0
  30. package/dist/lib/prompts/codex-host-bridge.js +138 -138
  31. package/dist/lib/prompts/codex.js +79 -79
  32. package/dist/lib/request/helpers/model-map.d.ts +1 -1
  33. package/dist/lib/request/helpers/model-map.js +12 -0
  34. package/dist/lib/request/response-outcome.d.ts +1 -1
  35. package/dist/lib/request/response-outcome.js +4 -1
  36. package/dist/lib/runtime/account-status.js +2 -1
  37. package/dist/lib/runtime/luna-reserve-usage.d.ts +9 -0
  38. package/dist/lib/runtime/luna-reserve-usage.js +68 -0
  39. package/dist/lib/runtime/model-discovery-status.d.ts +6 -2
  40. package/dist/lib/runtime/model-discovery-status.js +13 -5
  41. package/dist/lib/runtime/reset-credit-routing.js +4 -1
  42. package/dist/lib/runtime/rotation-server-types.d.ts +2 -0
  43. package/dist/lib/runtime/runtime-observability.d.ts +2 -0
  44. package/dist/lib/runtime/runtime-observability.js +1 -0
  45. package/dist/lib/runtime-rotation-proxy.js +200 -32
  46. package/dist/lib/usage/pricing.d.ts +1 -1
  47. package/dist/lib/usage/pricing.js +4 -0
  48. package/dist/lib/usage/usage-extraction.d.ts +2 -0
  49. package/dist/lib/usage/usage-extraction.js +25 -1
  50. package/dist/lib/utils.d.ts +1 -1
  51. package/dist/lib/utils.js +1 -1
  52. package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -2
  53. package/node_modules/@codex-ai/plugin/dist/index.js +2 -2
  54. package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -42
  55. package/node_modules/@codex-ai/plugin/dist/tool.js +29 -29
  56. package/node_modules/@codex-ai/plugin/package.json +9 -9
  57. package/node_modules/@codex-ai/sdk/dist/index.d.ts +4 -4
  58. package/node_modules/@codex-ai/sdk/dist/index.js +2 -2
  59. package/node_modules/@codex-ai/sdk/package.json +8 -8
  60. package/package.json +207 -207
  61. package/scripts/codex-app-launcher.js +653 -653
  62. package/scripts/codex-app-router.js +374 -373
  63. package/scripts/codex-bin-resolver.js +332 -332
  64. package/scripts/codex-multi-auth.js +65 -65
  65. package/scripts/codex-routing.js +62 -62
  66. package/scripts/codex.js +7006 -7005
  67. package/scripts/install-codex-auth-utils.js +213 -213
  68. package/scripts/mcodex.js +367 -367
  69. package/scripts/postinstall.js +114 -114
  70. package/scripts/preuninstall.js +265 -265
  71. package/skills/codex-auth-setup/SKILL.md +73 -73
  72. package/vendor/codex-ai-plugin/dist/index.d.ts +2 -2
  73. package/vendor/codex-ai-plugin/dist/index.js +2 -2
  74. package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -42
  75. package/vendor/codex-ai-plugin/dist/tool.js +29 -29
  76. package/vendor/codex-ai-plugin/package.json +9 -9
  77. package/vendor/codex-ai-sdk/dist/index.d.ts +4 -4
  78. package/vendor/codex-ai-sdk/dist/index.js +2 -2
  79. package/vendor/codex-ai-sdk/package.json +8 -8
@@ -1,213 +1,213 @@
1
- // @ts-check
2
-
3
- import { rename as fsRename } from "node:fs/promises";
4
- import { homedir } from "node:os";
5
- import { join } from "node:path";
6
- import process from "node:process";
7
-
8
- const PLUGIN_NAME = "codex-multi-auth";
9
- const LEGACY_PLUGIN_NAME = "@ndycode/codex-multi-auth";
10
- const PLUGIN_NAMES = [PLUGIN_NAME, LEGACY_PLUGIN_NAME];
11
-
12
- const TRUE_VALUES = new Set(["1", "true", "yes"]);
13
- const FALSE_VALUES = new Set(["0", "false", "no"]);
14
- const CI_ENV_KEYS = [
15
- "CI",
16
- "GITHUB_ACTIONS",
17
- "GITLAB_CI",
18
- "CIRCLECI",
19
- "BUILDKITE",
20
- "TF_BUILD",
21
- "TEAMCITY_VERSION",
22
- "JENKINS_URL",
23
- "TRAVIS",
24
- "APPVEYOR",
25
- "BITBUCKET_BUILD_NUMBER",
26
- ];
27
-
28
- /** @param {string | undefined} value */
29
- function readOptionalBooleanValue(value) {
30
- if (value === undefined || value.trim().length === 0) return null;
31
- const normalized = value.trim().toLowerCase();
32
- if (TRUE_VALUES.has(normalized)) return true;
33
- if (FALSE_VALUES.has(normalized)) return false;
34
- return null;
35
- }
36
-
37
- /** @param {NodeJS.ProcessEnv} env @param {string} key */
38
- function isEnabledEnvFlag(env, key) {
39
- const value = env[key];
40
- if (value === undefined || value.trim().length === 0) return false;
41
- return readOptionalBooleanValue(value) !== false;
42
- }
43
-
44
- /** @param {NodeJS.ProcessEnv} [env] */
45
- export function isCiEnvironment(env = process.env) {
46
- if (readOptionalBooleanValue(env.npm_config_ignore_scripts) === true) return true;
47
- return CI_ENV_KEYS.some((key) => isEnabledEnvFlag(env, key));
48
- }
49
- export const FILE_RETRY_CODES = new Set([
50
- "EBUSY",
51
- "EPERM",
52
- "EAGAIN",
53
- "ENOTEMPTY",
54
- "EACCES",
55
- ]);
56
- export const FILE_RETRY_MAX_ATTEMPTS = 6;
57
- export const FILE_RETRY_BASE_DELAY_MS = 25;
58
- export const FILE_RETRY_JITTER_MS = 20;
59
-
60
- /**
61
- * @param {NodeJS.Platform} [platform]
62
- * @param {NodeJS.ProcessEnv} [env]
63
- * @param {string} [home]
64
- */
65
- export function resolveInstallPaths(
66
- platform = process.platform,
67
- env = process.env,
68
- home = homedir(),
69
- ) {
70
- const isWindows = platform === "win32";
71
- const appData = (env.APPDATA ?? "").trim();
72
- const localAppData = (env.LOCALAPPDATA ?? appData).trim();
73
- const configBase = isWindows
74
- ? appData || join(home, "AppData", "Roaming")
75
- : join(home, ".config");
76
- const cacheBase = isWindows
77
- ? localAppData || join(home, "AppData", "Local")
78
- : join(home, ".cache");
79
- const configDir = join(configBase, "Codex");
80
- const configPath = join(configDir, "Codex.json");
81
- const cacheDir = join(cacheBase, "Codex");
82
- return {
83
- configDir,
84
- configPath,
85
- cacheDir,
86
- cacheNodeModules: join(cacheDir, "node_modules", PLUGIN_NAME),
87
- cacheLegacyNodeModules: join(cacheDir, "node_modules", "@ndycode", "codex-multi-auth"),
88
- cacheBunLock: join(cacheDir, "bun.lock"),
89
- cachePackageJson: join(cacheDir, "package.json"),
90
- };
91
- }
92
-
93
- /** @param {unknown} list */
94
- export function removePluginFromList(list) {
95
- const entries = Array.isArray(list) ? list.filter(Boolean) : [];
96
- return entries.filter((entry) => {
97
- if (typeof entry !== "string") return true;
98
- return !PLUGIN_NAMES.some(
99
- (pluginName) => entry === pluginName || entry.startsWith(`${pluginName}@`),
100
- );
101
- });
102
- }
103
-
104
- /** @param {unknown} list */
105
- export function normalizePluginList(list) {
106
- const entries = Array.isArray(list) ? list.filter(Boolean) : [];
107
- const filtered = entries.filter((entry) => {
108
- if (typeof entry !== "string") return true;
109
- return !PLUGIN_NAMES.some(
110
- (pluginName) => entry === pluginName || entry.startsWith(`${pluginName}@`),
111
- );
112
- });
113
- const deduped = [];
114
- const seen = new Set();
115
- for (const entry of filtered) {
116
- const key =
117
- typeof entry === "string" ? `s:${entry}` : `j:${JSON.stringify(entry)}`;
118
- if (seen.has(key)) continue;
119
- seen.add(key);
120
- deduped.push(entry);
121
- }
122
- return [...deduped, PLUGIN_NAME];
123
- }
124
-
125
- /** @param {number} ms */
126
- function sleep(ms) {
127
- // Keep this helper local so installer scripts remain standalone and do not depend on lib/.
128
- return new Promise((resolve) => {
129
- setTimeout(resolve, ms);
130
- });
131
- }
132
-
133
- /** @param {unknown} error */
134
- function shouldRetryFileOperation(error) {
135
- const fileError = /** @type {NodeJS.ErrnoException | undefined} */ (error);
136
- return (
137
- fileError instanceof Error &&
138
- typeof fileError.code === "string" &&
139
- FILE_RETRY_CODES.has(fileError.code)
140
- );
141
- }
142
-
143
- /** @template T @param {() => Promise<T>} operation */
144
- export async function withFileOperationRetry(operation) {
145
- for (let attempt = 1; ; attempt += 1) {
146
- try {
147
- return await operation();
148
- } catch (error) {
149
- if (
150
- !shouldRetryFileOperation(error) ||
151
- attempt >= FILE_RETRY_MAX_ATTEMPTS
152
- ) {
153
- throw error;
154
- }
155
-
156
- const jitter = Math.floor(Math.random() * FILE_RETRY_JITTER_MS);
157
- const delayMs = FILE_RETRY_BASE_DELAY_MS * 2 ** (attempt - 1) + jitter;
158
- await sleep(delayMs);
159
- }
160
- }
161
- }
162
-
163
- /**
164
- * @param {string} sourcePath
165
- * @param {string} targetPath
166
- * @param {{
167
- * rename?: (sourcePath: string, targetPath: string) => Promise<void>,
168
- * log?: (message: string) => void,
169
- * maxRetries?: number,
170
- * baseDelayMs?: number,
171
- * jitterMs?: number,
172
- * random?: () => number,
173
- * sleep?: (ms: number) => Promise<void>,
174
- * }} [options]
175
- */
176
- export async function renameWithRetry(sourcePath, targetPath, options = {}) {
177
- const {
178
- rename = fsRename,
179
- log = () => {},
180
- maxRetries = FILE_RETRY_MAX_ATTEMPTS,
181
- baseDelayMs = FILE_RETRY_BASE_DELAY_MS,
182
- jitterMs = FILE_RETRY_JITTER_MS,
183
- random = Math.random,
184
- sleep: sleepImpl = sleep,
185
- } = options;
186
-
187
- if (!Number.isInteger(maxRetries) || maxRetries < 1) {
188
- throw new RangeError("maxRetries must be an integer >= 1");
189
- }
190
-
191
- for (let attempt = 0; attempt < maxRetries; attempt += 1) {
192
- try {
193
- await rename(sourcePath, targetPath);
194
- return;
195
- } catch (error) {
196
- const code =
197
- error && typeof error === "object" && "code" in error
198
- ? error.code
199
- : undefined;
200
- const isRetryable =
201
- typeof code === "string" && FILE_RETRY_CODES.has(code);
202
- if (!isRetryable || attempt === maxRetries - 1) {
203
- throw error;
204
- }
205
- const delayMs =
206
- baseDelayMs * 2 ** attempt + Math.floor(random() * jitterMs);
207
- log(
208
- `Retrying atomic rename (${attempt + 1}/${maxRetries}) code=${code ?? "unknown"} source=${sourcePath} target=${targetPath} delayMs=${delayMs}`,
209
- );
210
- await sleepImpl(delayMs);
211
- }
212
- }
213
- }
1
+ // @ts-check
2
+
3
+ import { rename as fsRename } from "node:fs/promises";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ import process from "node:process";
7
+
8
+ const PLUGIN_NAME = "codex-multi-auth";
9
+ const LEGACY_PLUGIN_NAME = "@ndycode/codex-multi-auth";
10
+ const PLUGIN_NAMES = [PLUGIN_NAME, LEGACY_PLUGIN_NAME];
11
+
12
+ const TRUE_VALUES = new Set(["1", "true", "yes"]);
13
+ const FALSE_VALUES = new Set(["0", "false", "no"]);
14
+ const CI_ENV_KEYS = [
15
+ "CI",
16
+ "GITHUB_ACTIONS",
17
+ "GITLAB_CI",
18
+ "CIRCLECI",
19
+ "BUILDKITE",
20
+ "TF_BUILD",
21
+ "TEAMCITY_VERSION",
22
+ "JENKINS_URL",
23
+ "TRAVIS",
24
+ "APPVEYOR",
25
+ "BITBUCKET_BUILD_NUMBER",
26
+ ];
27
+
28
+ /** @param {string | undefined} value */
29
+ function readOptionalBooleanValue(value) {
30
+ if (value === undefined || value.trim().length === 0) return null;
31
+ const normalized = value.trim().toLowerCase();
32
+ if (TRUE_VALUES.has(normalized)) return true;
33
+ if (FALSE_VALUES.has(normalized)) return false;
34
+ return null;
35
+ }
36
+
37
+ /** @param {NodeJS.ProcessEnv} env @param {string} key */
38
+ function isEnabledEnvFlag(env, key) {
39
+ const value = env[key];
40
+ if (value === undefined || value.trim().length === 0) return false;
41
+ return readOptionalBooleanValue(value) !== false;
42
+ }
43
+
44
+ /** @param {NodeJS.ProcessEnv} [env] */
45
+ export function isCiEnvironment(env = process.env) {
46
+ if (readOptionalBooleanValue(env.npm_config_ignore_scripts) === true) return true;
47
+ return CI_ENV_KEYS.some((key) => isEnabledEnvFlag(env, key));
48
+ }
49
+ export const FILE_RETRY_CODES = new Set([
50
+ "EBUSY",
51
+ "EPERM",
52
+ "EAGAIN",
53
+ "ENOTEMPTY",
54
+ "EACCES",
55
+ ]);
56
+ export const FILE_RETRY_MAX_ATTEMPTS = 6;
57
+ export const FILE_RETRY_BASE_DELAY_MS = 25;
58
+ export const FILE_RETRY_JITTER_MS = 20;
59
+
60
+ /**
61
+ * @param {NodeJS.Platform} [platform]
62
+ * @param {NodeJS.ProcessEnv} [env]
63
+ * @param {string} [home]
64
+ */
65
+ export function resolveInstallPaths(
66
+ platform = process.platform,
67
+ env = process.env,
68
+ home = homedir(),
69
+ ) {
70
+ const isWindows = platform === "win32";
71
+ const appData = (env.APPDATA ?? "").trim();
72
+ const localAppData = (env.LOCALAPPDATA ?? appData).trim();
73
+ const configBase = isWindows
74
+ ? appData || join(home, "AppData", "Roaming")
75
+ : join(home, ".config");
76
+ const cacheBase = isWindows
77
+ ? localAppData || join(home, "AppData", "Local")
78
+ : join(home, ".cache");
79
+ const configDir = join(configBase, "Codex");
80
+ const configPath = join(configDir, "Codex.json");
81
+ const cacheDir = join(cacheBase, "Codex");
82
+ return {
83
+ configDir,
84
+ configPath,
85
+ cacheDir,
86
+ cacheNodeModules: join(cacheDir, "node_modules", PLUGIN_NAME),
87
+ cacheLegacyNodeModules: join(cacheDir, "node_modules", "@ndycode", "codex-multi-auth"),
88
+ cacheBunLock: join(cacheDir, "bun.lock"),
89
+ cachePackageJson: join(cacheDir, "package.json"),
90
+ };
91
+ }
92
+
93
+ /** @param {unknown} list */
94
+ export function removePluginFromList(list) {
95
+ const entries = Array.isArray(list) ? list.filter(Boolean) : [];
96
+ return entries.filter((entry) => {
97
+ if (typeof entry !== "string") return true;
98
+ return !PLUGIN_NAMES.some(
99
+ (pluginName) => entry === pluginName || entry.startsWith(`${pluginName}@`),
100
+ );
101
+ });
102
+ }
103
+
104
+ /** @param {unknown} list */
105
+ export function normalizePluginList(list) {
106
+ const entries = Array.isArray(list) ? list.filter(Boolean) : [];
107
+ const filtered = entries.filter((entry) => {
108
+ if (typeof entry !== "string") return true;
109
+ return !PLUGIN_NAMES.some(
110
+ (pluginName) => entry === pluginName || entry.startsWith(`${pluginName}@`),
111
+ );
112
+ });
113
+ const deduped = [];
114
+ const seen = new Set();
115
+ for (const entry of filtered) {
116
+ const key =
117
+ typeof entry === "string" ? `s:${entry}` : `j:${JSON.stringify(entry)}`;
118
+ if (seen.has(key)) continue;
119
+ seen.add(key);
120
+ deduped.push(entry);
121
+ }
122
+ return [...deduped, PLUGIN_NAME];
123
+ }
124
+
125
+ /** @param {number} ms */
126
+ function sleep(ms) {
127
+ // Keep this helper local so installer scripts remain standalone and do not depend on lib/.
128
+ return new Promise((resolve) => {
129
+ setTimeout(resolve, ms);
130
+ });
131
+ }
132
+
133
+ /** @param {unknown} error */
134
+ function shouldRetryFileOperation(error) {
135
+ const fileError = /** @type {NodeJS.ErrnoException | undefined} */ (error);
136
+ return (
137
+ fileError instanceof Error &&
138
+ typeof fileError.code === "string" &&
139
+ FILE_RETRY_CODES.has(fileError.code)
140
+ );
141
+ }
142
+
143
+ /** @template T @param {() => Promise<T>} operation */
144
+ export async function withFileOperationRetry(operation) {
145
+ for (let attempt = 1; ; attempt += 1) {
146
+ try {
147
+ return await operation();
148
+ } catch (error) {
149
+ if (
150
+ !shouldRetryFileOperation(error) ||
151
+ attempt >= FILE_RETRY_MAX_ATTEMPTS
152
+ ) {
153
+ throw error;
154
+ }
155
+
156
+ const jitter = Math.floor(Math.random() * FILE_RETRY_JITTER_MS);
157
+ const delayMs = FILE_RETRY_BASE_DELAY_MS * 2 ** (attempt - 1) + jitter;
158
+ await sleep(delayMs);
159
+ }
160
+ }
161
+ }
162
+
163
+ /**
164
+ * @param {string} sourcePath
165
+ * @param {string} targetPath
166
+ * @param {{
167
+ * rename?: (sourcePath: string, targetPath: string) => Promise<void>,
168
+ * log?: (message: string) => void,
169
+ * maxRetries?: number,
170
+ * baseDelayMs?: number,
171
+ * jitterMs?: number,
172
+ * random?: () => number,
173
+ * sleep?: (ms: number) => Promise<void>,
174
+ * }} [options]
175
+ */
176
+ export async function renameWithRetry(sourcePath, targetPath, options = {}) {
177
+ const {
178
+ rename = fsRename,
179
+ log = () => {},
180
+ maxRetries = FILE_RETRY_MAX_ATTEMPTS,
181
+ baseDelayMs = FILE_RETRY_BASE_DELAY_MS,
182
+ jitterMs = FILE_RETRY_JITTER_MS,
183
+ random = Math.random,
184
+ sleep: sleepImpl = sleep,
185
+ } = options;
186
+
187
+ if (!Number.isInteger(maxRetries) || maxRetries < 1) {
188
+ throw new RangeError("maxRetries must be an integer >= 1");
189
+ }
190
+
191
+ for (let attempt = 0; attempt < maxRetries; attempt += 1) {
192
+ try {
193
+ await rename(sourcePath, targetPath);
194
+ return;
195
+ } catch (error) {
196
+ const code =
197
+ error && typeof error === "object" && "code" in error
198
+ ? error.code
199
+ : undefined;
200
+ const isRetryable =
201
+ typeof code === "string" && FILE_RETRY_CODES.has(code);
202
+ if (!isRetryable || attempt === maxRetries - 1) {
203
+ throw error;
204
+ }
205
+ const delayMs =
206
+ baseDelayMs * 2 ** attempt + Math.floor(random() * jitterMs);
207
+ log(
208
+ `Retrying atomic rename (${attempt + 1}/${maxRetries}) code=${code ?? "unknown"} source=${sourcePath} target=${targetPath} delayMs=${delayMs}`,
209
+ );
210
+ await sleepImpl(delayMs);
211
+ }
212
+ }
213
+ }