codex-multi-auth 2.16.0 → 2.17.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.
- package/.codex-plugin/plugin.json +9 -9
- package/LICENSE +21 -21
- package/README.md +487 -463
- package/assets/codex-multi-auth-icon.svg +39 -39
- package/assets/readme-hero.svg +31 -31
- package/config/README.md +31 -31
- package/config/codex-legacy.json +1221 -1221
- package/config/codex-modern.json +423 -423
- package/config/minimal-codex.json +15 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/lib/account-policy.d.ts +4 -0
- package/dist/lib/account-policy.d.ts.map +1 -1
- package/dist/lib/account-policy.js +8 -0
- package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
- package/dist/lib/accounts/rate-limits.js +2 -0
- package/dist/lib/accounts.d.ts +15 -3
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +231 -30
- package/dist/lib/api-route-store.d.ts +24 -0
- package/dist/lib/api-route-store.d.ts.map +1 -0
- package/dist/lib/api-route-store.js +145 -0
- package/dist/lib/auth/account-access.d.ts +115 -0
- package/dist/lib/auth/account-access.d.ts.map +1 -0
- package/dist/lib/auth/account-access.js +214 -0
- package/dist/lib/auth/token-utils.d.ts +54 -1
- package/dist/lib/auth/token-utils.d.ts.map +1 -1
- package/dist/lib/auth/token-utils.js +92 -7
- package/dist/lib/cli.d.ts +1 -1
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +4 -0
- package/dist/lib/codex-cli/state.d.ts +7 -0
- package/dist/lib/codex-cli/state.d.ts.map +1 -1
- package/dist/lib/codex-cli/state.js +18 -0
- package/dist/lib/codex-cli/writer.d.ts.map +1 -1
- package/dist/lib/codex-cli/writer.js +60 -8
- package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-manager-commands.js +1 -0
- package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
- package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
- package/dist/lib/codex-manager/account-pool-write.js +4 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
- package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
- package/dist/lib/codex-manager/api-login-menu.js +224 -0
- package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/account.js +27 -0
- package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/best.js +6 -2
- package/dist/lib/codex-manager/commands/check.d.ts +7 -1
- package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/check.js +24 -3
- package/dist/lib/codex-manager/commands/forecast.d.ts +1 -1
- package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/forecast.js +7 -3
- package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/report.js +5 -1
- package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
- package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
- package/dist/lib/codex-manager/commands/resets.js +67 -0
- package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
- package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/rotation.js +63 -12
- package/dist/lib/codex-manager/commands/status.d.ts +12 -1
- package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
- package/dist/lib/codex-manager/commands/status.js +166 -22
- package/dist/lib/codex-manager/commands/uninstall.js +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
- package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
- package/dist/lib/codex-manager/health-check.d.ts +3 -0
- package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
- package/dist/lib/codex-manager/health-check.js +57 -7
- package/dist/lib/codex-manager/help.d.ts.map +1 -1
- package/dist/lib/codex-manager/help.js +4 -2
- package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-flow.js +69 -7
- package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-menu-data.js +21 -8
- package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
- package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
- package/dist/lib/codex-manager/login-oauth.js +6 -1
- package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
- package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
- package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
- package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
- package/dist/lib/codex-manager/persist-selected-account.js +2 -1
- package/dist/lib/codex-manager/quota-cache-helpers.d.ts +7 -1
- package/dist/lib/codex-manager/quota-cache-helpers.d.ts.map +1 -1
- package/dist/lib/codex-manager/quota-cache-helpers.js +34 -19
- package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
- package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
- package/dist/lib/codex-manager/repair-commands.js +144 -9
- package/dist/lib/codex-manager.d.ts.map +1 -1
- package/dist/lib/codex-manager.js +25 -6
- package/dist/lib/concurrency.d.ts +3 -0
- package/dist/lib/concurrency.d.ts.map +1 -0
- package/dist/lib/concurrency.js +31 -0
- package/dist/lib/context-budget-response.js +8 -8
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/model-route-policy.d.ts +52 -0
- package/dist/lib/model-route-policy.d.ts.map +1 -0
- package/dist/lib/model-route-policy.js +159 -0
- package/dist/lib/oauth-success.html +125 -125
- package/dist/lib/policy/runtime-policy.d.ts +1 -0
- package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
- package/dist/lib/policy/runtime-policy.js +3 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
- package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
- package/dist/lib/preemptive-quota-scheduler.js +4 -0
- package/dist/lib/prompts/codex-host-bridge.js +138 -138
- package/dist/lib/prompts/codex.js +79 -79
- package/dist/lib/quota-cache.d.ts +7 -3
- package/dist/lib/quota-cache.d.ts.map +1 -1
- package/dist/lib/quota-cache.js +91 -59
- package/dist/lib/quota-probe.d.ts +5 -0
- package/dist/lib/quota-probe.d.ts.map +1 -1
- package/dist/lib/quota-probe.js +26 -2
- package/dist/lib/quota-readiness.d.ts +7 -2
- package/dist/lib/quota-readiness.d.ts.map +1 -1
- package/dist/lib/quota-readiness.js +25 -4
- package/dist/lib/request/client-cancellation.d.ts +5 -0
- package/dist/lib/request/client-cancellation.d.ts.map +1 -0
- package/dist/lib/request/client-cancellation.js +7 -0
- package/dist/lib/request/response-outcome.d.ts +25 -0
- package/dist/lib/request/response-outcome.d.ts.map +1 -0
- package/dist/lib/request/response-outcome.js +49 -0
- package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
- package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
- package/dist/lib/request/stream-failover-runtime.js +29 -10
- package/dist/lib/runtime/account-check.d.ts.map +1 -1
- package/dist/lib/runtime/account-check.js +2 -8
- package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
- package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
- package/dist/lib/runtime/account-model-catalog.js +154 -0
- package/dist/lib/runtime/account-pool.d.ts +3 -1
- package/dist/lib/runtime/account-pool.d.ts.map +1 -1
- package/dist/lib/runtime/account-pool.js +4 -0
- package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
- package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/account-reset-credits.js +82 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
- package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-capabilities.js +434 -0
- package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
- package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
- package/dist/lib/runtime/api-model-runtime.js +358 -0
- package/dist/lib/runtime/app-bind.d.ts +19 -1
- package/dist/lib/runtime/app-bind.d.ts.map +1 -1
- package/dist/lib/runtime/app-bind.js +89 -11
- package/dist/lib/runtime/automatic-account-checks.d.ts +35 -0
- package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-account-checks.js +140 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
- package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
- package/dist/lib/runtime/automatic-subscription-checks.js +54 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
- package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
- package/dist/lib/runtime/catalog-capabilities.js +61 -0
- package/dist/lib/runtime/inference-activity.d.ts +15 -0
- package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
- package/dist/lib/runtime/inference-activity.js +95 -0
- package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
- package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
- package/dist/lib/runtime/model-discovery-status.js +387 -0
- package/dist/lib/runtime/native-account-storage.d.ts +11 -0
- package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-storage.js +50 -0
- package/dist/lib/runtime/native-account-sync.d.ts +19 -0
- package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
- package/dist/lib/runtime/native-account-sync.js +62 -0
- package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
- package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
- package/dist/lib/runtime/native-binding-lock.js +5 -0
- package/dist/lib/runtime/native-client-auth.d.ts +3 -0
- package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
- package/dist/lib/runtime/native-client-auth.js +42 -0
- package/dist/lib/runtime/native-provider-config.d.ts +4 -0
- package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
- package/dist/lib/runtime/native-provider-config.js +52 -0
- package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
- package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
- package/dist/lib/runtime/native-rate-limits.js +135 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
- package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credit-routing.js +66 -0
- package/dist/lib/runtime/reset-credits.d.ts +101 -0
- package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
- package/dist/lib/runtime/reset-credits.js +162 -0
- package/dist/lib/runtime/response-output-history.d.ts +17 -0
- package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
- package/dist/lib/runtime/response-output-history.js +85 -0
- package/dist/lib/runtime/responses-websocket.d.ts +31 -0
- package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
- package/dist/lib/runtime/responses-websocket.js +636 -0
- package/dist/lib/runtime/resume-picker.d.ts +41 -0
- package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
- package/dist/lib/runtime/resume-picker.js +169 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
- package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-account-selection.js +63 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
- package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
- package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
- package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
- package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
- package/dist/lib/runtime/runtime-capability-failures.js +76 -0
- package/dist/lib/runtime/runtime-observability.d.ts +7 -0
- package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
- package/dist/lib/runtime/runtime-observability.js +42 -2
- package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
- package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-first-use.js +64 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
- package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-event.js +31 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
- package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
- package/dist/lib/runtime/subscription-quota-order.js +31 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
- package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
- package/dist/lib/runtime/workspace-model-scopes.js +34 -0
- package/dist/lib/runtime-constants.d.ts +3 -0
- package/dist/lib/runtime-constants.d.ts.map +1 -1
- package/dist/lib/runtime-constants.js +5 -0
- package/dist/lib/runtime-paths.d.ts.map +1 -1
- package/dist/lib/runtime-paths.js +4 -1
- package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
- package/dist/lib/runtime-rotation-proxy.js +852 -42
- package/dist/lib/schemas.d.ts +20 -0
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +3 -0
- package/dist/lib/storage/credential-sidecars.d.ts +13 -0
- package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
- package/dist/lib/storage/credential-sidecars.js +52 -0
- package/dist/lib/storage/file-lock.d.ts +9 -0
- package/dist/lib/storage/file-lock.d.ts.map +1 -0
- package/dist/lib/storage/file-lock.js +186 -0
- package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
- package/dist/lib/storage/flagged-storage.js +12 -0
- package/dist/lib/storage/path-state.d.ts +2 -0
- package/dist/lib/storage/path-state.d.ts.map +1 -1
- package/dist/lib/storage/path-state.js +9 -0
- package/dist/lib/storage/paths.js +4 -4
- package/dist/lib/storage/pending-auth.d.ts +18 -0
- package/dist/lib/storage/pending-auth.d.ts.map +1 -0
- package/dist/lib/storage/pending-auth.js +155 -0
- package/dist/lib/storage/public-types.d.ts +13 -0
- package/dist/lib/storage/public-types.d.ts.map +1 -1
- package/dist/lib/storage/record-identity.d.ts +16 -0
- package/dist/lib/storage/record-identity.d.ts.map +1 -0
- package/dist/lib/storage/record-identity.js +16 -0
- package/dist/lib/storage/snapshot-merge.d.ts +16 -0
- package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
- package/dist/lib/storage/snapshot-merge.js +206 -0
- package/dist/lib/storage/transactions.d.ts.map +1 -1
- package/dist/lib/storage/transactions.js +5 -4
- package/dist/lib/storage.d.ts +6 -0
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/storage.js +77 -7
- package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
- package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu-builder.js +1 -0
- package/dist/lib/ui/auth-menu.d.ts.map +1 -1
- package/dist/lib/ui/auth-menu.js +1 -0
- package/dist/lib/ui/check-progress.d.ts +8 -0
- package/dist/lib/ui/check-progress.d.ts.map +1 -0
- package/dist/lib/ui/check-progress.js +30 -0
- package/dist/lib/ui/format.d.ts +3 -1
- package/dist/lib/ui/format.d.ts.map +1 -1
- package/dist/lib/ui/format.js +8 -0
- package/dist/lib/ui/ui-copy.d.ts +2 -2
- package/dist/lib/ui/ui-copy.js +2 -2
- package/dist/lib/usage/pricing.js +2 -2
- package/dist/lib/usage/usage-extraction.d.ts +3 -1
- package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
- package/dist/lib/usage/usage-extraction.js +46 -9
- package/node_modules/@codex-ai/plugin/dist/index.d.ts +2 -2
- package/node_modules/@codex-ai/plugin/dist/index.js +2 -2
- package/node_modules/@codex-ai/plugin/dist/tool.d.ts +42 -42
- package/node_modules/@codex-ai/plugin/dist/tool.js +29 -29
- package/node_modules/@codex-ai/plugin/package.json +9 -9
- package/node_modules/@codex-ai/sdk/dist/index.d.ts +4 -4
- package/node_modules/@codex-ai/sdk/dist/index.js +2 -2
- package/node_modules/@codex-ai/sdk/package.json +8 -8
- package/package.json +200 -197
- package/scripts/codex-app-launcher.js +653 -653
- package/scripts/codex-app-router.js +373 -366
- package/scripts/codex-bin-resolver.js +313 -281
- package/scripts/codex-multi-auth.js +59 -59
- package/scripts/codex-routing.js +62 -61
- package/scripts/codex.js +6642 -6564
- package/scripts/install-codex-auth-utils.js +213 -213
- package/scripts/mcodex.js +367 -367
- package/scripts/postinstall.js +114 -114
- package/scripts/preuninstall.js +265 -265
- package/vendor/codex-ai-plugin/dist/index.d.ts +2 -2
- package/vendor/codex-ai-plugin/dist/index.js +2 -2
- package/vendor/codex-ai-plugin/dist/tool.d.ts +42 -42
- package/vendor/codex-ai-plugin/dist/tool.js +29 -29
- package/vendor/codex-ai-plugin/package.json +9 -9
- package/vendor/codex-ai-sdk/dist/index.d.ts +4 -4
- package/vendor/codex-ai-sdk/dist/index.js +2 -2
- package/vendor/codex-ai-sdk/package.json +8 -8
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { withNativeBindingLock } from "../runtime/native-binding-lock.js";
|
|
2
|
+
import { hasNativeProviderConfig } from "../runtime-constants.js";
|
|
1
3
|
import { existsSync, promises as fs } from "node:fs";
|
|
2
4
|
import { dirname } from "node:path";
|
|
3
5
|
import { createLogger } from "../logger.js";
|
|
4
6
|
import { clearCodexCliStateCache, getCodexCliAccountsPath, getCodexCliAuthPath, getCodexCliConfigPath, isCodexCliSyncEnabled, } from "./state.js";
|
|
5
7
|
import { incrementCodexCliMetric, makeAccountFingerprint, } from "./observability.js";
|
|
6
8
|
import { tempPathFor } from "../temp-path.js";
|
|
9
|
+
import { decodeJWT } from "../auth/auth.js";
|
|
10
|
+
import { extractAccountId, getAccountIdCandidates, resolveCodexAuthAccountId, } from "../auth/token-utils.js";
|
|
7
11
|
const log = createLogger("codex-cli-writer");
|
|
8
12
|
let lastCodexCliSelectionWriteAt = 0;
|
|
9
13
|
let activeSelectionWriteQueue = Promise.resolve();
|
|
@@ -382,12 +386,44 @@ async function writeCodexAuthState(path, selection) {
|
|
|
382
386
|
}
|
|
383
387
|
nextTokens.access_token = accessToken;
|
|
384
388
|
nextTokens.refresh_token = refreshToken;
|
|
385
|
-
if (selection.accountId?.trim()) {
|
|
386
|
-
nextTokens.account_id = selection.accountId.trim();
|
|
387
|
-
}
|
|
388
389
|
const selectedIdToken = readTrimmedString(selection.idToken);
|
|
389
390
|
const existingIdToken = readTrimmedString(existingTokens.id_token);
|
|
390
|
-
|
|
391
|
+
// A stale "org-..." id already in auth.json is sanitised too, not only a
|
|
392
|
+
// selected one. With no chatgpt_account_id claim, drop the field so Codex
|
|
393
|
+
// derives it from the tokens.
|
|
394
|
+
const selectedAccountId = selection.accountId?.trim();
|
|
395
|
+
let rawAccountId = selectedAccountId || readTrimmedString(existingTokens.account_id);
|
|
396
|
+
if (!selectedAccountId && selectedTokenPair && rawAccountId) {
|
|
397
|
+
// New tokens without an accountId: the previous file's id may belong to
|
|
398
|
+
// another account. Keep it only when the new tokens still carry it as a
|
|
399
|
+
// workspace; otherwise follow the new token's claim.
|
|
400
|
+
const tokenClaim = extractAccountId(accessToken) ?? extractAccountId(selectedIdToken);
|
|
401
|
+
const tokenWorkspaces = getAccountIdCandidates(accessToken, selectedIdToken).map((candidate) => candidate.accountId);
|
|
402
|
+
if (tokenClaim && !tokenWorkspaces.includes(rawAccountId)) {
|
|
403
|
+
rawAccountId = tokenClaim;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (rawAccountId) {
|
|
407
|
+
const accountId = resolveCodexAuthAccountId(rawAccountId, accessToken, selectedIdToken);
|
|
408
|
+
if (accountId) {
|
|
409
|
+
nextTokens.account_id = accountId;
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
delete nextTokens.account_id;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Without a selected id_token, keep the existing one when it belongs to the
|
|
416
|
+
// same user and workspace as the new access token (a same-account resync);
|
|
417
|
+
// only another account's id_token is replaced by the access-token fallback.
|
|
418
|
+
const existingIdClaims = existingIdToken ? decodeJWT(existingIdToken) : null;
|
|
419
|
+
const accessClaims = decodeJWT(accessToken);
|
|
420
|
+
const existingIdTokenMatches = typeof existingIdClaims?.sub === "string" &&
|
|
421
|
+
existingIdClaims.sub === accessClaims?.sub &&
|
|
422
|
+
!!extractAccountId(existingIdToken) &&
|
|
423
|
+
extractAccountId(existingIdToken) === extractAccountId(accessToken);
|
|
424
|
+
const fallbackIdToken = selectedTokenPair && !existingIdTokenMatches
|
|
425
|
+
? accessToken
|
|
426
|
+
: (existingIdToken ?? accessToken);
|
|
391
427
|
if (selectedIdToken) {
|
|
392
428
|
nextTokens.id_token = selectedIdToken;
|
|
393
429
|
}
|
|
@@ -423,9 +459,18 @@ async function enqueueActiveSelectionWrite(task) {
|
|
|
423
459
|
}
|
|
424
460
|
}
|
|
425
461
|
export async function setCodexCliActiveSelection(selection) {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
462
|
+
if (!isCodexCliSyncEnabled())
|
|
463
|
+
return false;
|
|
464
|
+
return enqueueActiveSelectionWrite(() => withNativeBindingLock(getCodexCliConfigPath(), async () => {
|
|
465
|
+
// Native app binding deliberately separates desktop identity from inference selection.
|
|
466
|
+
try {
|
|
467
|
+
if (hasNativeProviderConfig(await fs.readFile(getCodexCliConfigPath(), "utf8")))
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
if (error.code !== "ENOENT")
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
429
474
|
incrementCodexCliMetric("writeAttempts");
|
|
430
475
|
const accountsPath = getCodexCliAccountsPath();
|
|
431
476
|
const authPath = getCodexCliAuthPath();
|
|
@@ -611,7 +656,14 @@ export async function setCodexCliActiveSelection(selection) {
|
|
|
611
656
|
});
|
|
612
657
|
return false;
|
|
613
658
|
}
|
|
614
|
-
})
|
|
659
|
+
}).catch((error) => {
|
|
660
|
+
incrementCodexCliMetric("writeFailures");
|
|
661
|
+
log.warn("Failed to persist Codex CLI active selection", {
|
|
662
|
+
operation: "write-active-selection", outcome: "native-bind-lock-unavailable",
|
|
663
|
+
code: error?.code ?? "unknown",
|
|
664
|
+
});
|
|
665
|
+
return false;
|
|
666
|
+
}));
|
|
615
667
|
}
|
|
616
668
|
export function getLastCodexCliSelectionWriteTimestamp() {
|
|
617
669
|
return lastCodexCliSelectionWriteAt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-manager-commands.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/account-manager-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"account-manager-commands.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/account-manager-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,aAgCnC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Workspace } from "../accounts.js";
|
|
2
|
-
import type { AccountMetadataV3 } from "../storage/public-types.js";
|
|
2
|
+
import type { AccountMetadataV3, CodexCliMirror } from "../storage/public-types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Outcome of folding a single login result into the saved account pool.
|
|
5
5
|
*
|
|
@@ -30,6 +30,8 @@ export interface ResolvedAccountWrite {
|
|
|
30
30
|
accessToken?: string;
|
|
31
31
|
expiresAt?: number;
|
|
32
32
|
workspaces?: Workspace[];
|
|
33
|
+
/** Set, keep (undefined) or clear (null) the saved CodexCliMirror. */
|
|
34
|
+
codexCliMirror?: CodexCliMirror | null;
|
|
33
35
|
/**
|
|
34
36
|
* Keep the saved row's `enabled` flag instead of re-enabling it. A targeted
|
|
35
37
|
* re-authentication only tops up credentials for a row the user named, so it
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-pool-write.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/account-pool-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"account-pool-write.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/account-pool-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EACX,iBAAiB,EACjB,cAAc,EACd,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,sEAAsE;IACtE,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,SAAS,EAAE,EACvB,SAAS,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,CAWR;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,EAC/C,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,GAC/B,SAAS,EAAE,GAAG,SAAS,CAYzB;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC3C,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,uBAAuB,CAAC,EACzE,gBAAgB,EAAE,SAAS,EAAE,GAAG,SAAS,GACvC,MAAM,GAAG,SAAS,CAwBpB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,oBAAoB,GACzB;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAyBrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,oBAAoB,GACzB;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAmDhE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC/C,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wBAAwB,EAAE,CACzB,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,QAAQ,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,YAAY,CAAC,EAAE,MAAM,CAAC;KACtB,EACD,OAAO,EAAE;QAAE,wCAAwC,EAAE,OAAO,CAAA;KAAE,KAC1D,MAAM,GAAG,SAAS,CAAC;CACxB,GAAG;IACH,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;CACxC,CA6CA"}
|
|
@@ -80,6 +80,7 @@ export function buildInsertedAccount(write) {
|
|
|
80
80
|
lastUsed: write.now,
|
|
81
81
|
workspaces: write.workspaces,
|
|
82
82
|
currentWorkspaceIndex: initialWorkspaceIndex,
|
|
83
|
+
...(write.codexCliMirror ? { codexCliMirror: write.codexCliMirror } : {}),
|
|
83
84
|
},
|
|
84
85
|
};
|
|
85
86
|
}
|
|
@@ -121,6 +122,9 @@ export function buildUpdatedAccount(existing, write) {
|
|
|
121
122
|
lastUsed: write.now,
|
|
122
123
|
workspaces: mergedWorkspaces,
|
|
123
124
|
currentWorkspaceIndex: nextCurrentWorkspaceIndex,
|
|
125
|
+
codexCliMirror: write.codexCliMirror === null
|
|
126
|
+
? undefined
|
|
127
|
+
: (write.codexCliMirror ?? existing.codexCliMirror),
|
|
124
128
|
},
|
|
125
129
|
};
|
|
126
130
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ApiRouteCredential } from "../api-route-store.js";
|
|
2
|
+
import { type MenuItem } from "../ui/select.js";
|
|
3
|
+
interface MenuDeps {
|
|
4
|
+
load: () => Promise<ApiRouteCredential[]>;
|
|
5
|
+
save: (routes: ApiRouteCredential[], expected: ApiRouteCredential[]) => Promise<void>;
|
|
6
|
+
select: (items: MenuItem<string>[], message: string) => Promise<string | null>;
|
|
7
|
+
text: (message: string) => Promise<string>;
|
|
8
|
+
secret: () => Promise<string>;
|
|
9
|
+
discover: (route: ApiRouteCredential) => Promise<string[]>;
|
|
10
|
+
log: (message: string) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function runApiLoginMenu(overrides?: Partial<MenuDeps>): Promise<number>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=api-login-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-login-menu.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/api-login-menu.ts"],"names":[],"mappings":"AAGA,OAAO,EAGN,KAAK,kBAAkB,EACvB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAExD,UAAU,QAAQ;IACjB,IAAI,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC1C,IAAI,EAAE,CACL,MAAM,EAAE,kBAAkB,EAAE,EAC5B,QAAQ,EAAE,kBAAkB,EAAE,KAC1B,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,MAAM,EAAE,CACP,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,EACzB,OAAO,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3D,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AA0FD,wBAAsB,eAAe,CACpC,SAAS,GAAE,OAAO,CAAC,QAAQ,CAAM,GAC/B,OAAO,CAAC,MAAM,CAAC,CAgIjB"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createInterface } from "node:readline/promises";
|
|
3
|
+
import { Writable } from "node:stream";
|
|
4
|
+
import { loadApiRoutes, saveApiRoutes, } from "../api-route-store.js";
|
|
5
|
+
import { ApiModelRuntime } from "../runtime/api-model-runtime.js";
|
|
6
|
+
import { select } from "../ui/select.js";
|
|
7
|
+
async function ask(message, secret = false) {
|
|
8
|
+
if (!process.stdin.isTTY)
|
|
9
|
+
throw Error("API setup requires an interactive terminal.");
|
|
10
|
+
// The secret never reaches the output stream, command arguments, or shell history.
|
|
11
|
+
const sink = new Writable({
|
|
12
|
+
write(_chunk, _encoding, done) {
|
|
13
|
+
done();
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
if (secret)
|
|
17
|
+
process.stdout.write(message);
|
|
18
|
+
const rl = createInterface({
|
|
19
|
+
input: process.stdin,
|
|
20
|
+
output: secret ? sink : process.stdout,
|
|
21
|
+
terminal: true,
|
|
22
|
+
});
|
|
23
|
+
const cancel = () => rl.close();
|
|
24
|
+
rl.on("SIGINT", cancel);
|
|
25
|
+
try {
|
|
26
|
+
return (await rl.question(secret ? "" : message)).trim();
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
rl.off("SIGINT", cancel);
|
|
30
|
+
rl.close();
|
|
31
|
+
sink.destroy();
|
|
32
|
+
if (secret)
|
|
33
|
+
process.stdout.write("\n");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const defaults = {
|
|
37
|
+
load: loadApiRoutes,
|
|
38
|
+
save: (routes, expected) => saveApiRoutes(routes, undefined, expected),
|
|
39
|
+
select: (items, message) => select(items, { message, allowEscape: true }),
|
|
40
|
+
text: (message) => ask(message),
|
|
41
|
+
secret: () => ask("API key (hidden): ", true),
|
|
42
|
+
discover: async (route) => {
|
|
43
|
+
const runtime = new ApiModelRuntime();
|
|
44
|
+
const catalogs = await runtime.catalogs([route], true);
|
|
45
|
+
if (runtime.statuses([route])[0]?.error)
|
|
46
|
+
throw Error("Model discovery failed. Check the credential and its API permissions.");
|
|
47
|
+
return catalogs[0]?.models.map((m) => m.slug) ?? [];
|
|
48
|
+
},
|
|
49
|
+
log: console.log,
|
|
50
|
+
};
|
|
51
|
+
async function chooseModels(route, d) {
|
|
52
|
+
const available = await d.discover(route);
|
|
53
|
+
const selected = new Set(route.visibleModels.filter((id) => available.includes(id)));
|
|
54
|
+
let query = "";
|
|
55
|
+
for (;;) {
|
|
56
|
+
const visible = available.filter((m) => m.toLowerCase().includes(query));
|
|
57
|
+
const choice = await d.select([
|
|
58
|
+
{ label: `Save ${selected.size} selected model(s)`, value: "save" },
|
|
59
|
+
{ label: "Search models", value: "search" },
|
|
60
|
+
{ label: "Clear selection", value: "clear" },
|
|
61
|
+
...visible.map((model) => ({
|
|
62
|
+
label: `${selected.has(model) ? "[x]" : "[ ]"} ${model}`,
|
|
63
|
+
value: `toggle:${model}`,
|
|
64
|
+
})),
|
|
65
|
+
{ label: "Cancel without saving", value: "cancel" },
|
|
66
|
+
], "Choose models visible in Codex (future GPT text models appear automatically)");
|
|
67
|
+
if (!choice || choice === "cancel")
|
|
68
|
+
return null;
|
|
69
|
+
if (choice === "save")
|
|
70
|
+
return {
|
|
71
|
+
visibleModels: [...selected].sort(),
|
|
72
|
+
knownModels: [...new Set([...(route.knownModels ?? []), ...available])],
|
|
73
|
+
};
|
|
74
|
+
if (choice === "search") {
|
|
75
|
+
query = (await d.text("Search: ")).toLowerCase();
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (choice === "clear") {
|
|
79
|
+
selected.clear();
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (choice.startsWith("toggle:")) {
|
|
83
|
+
const id = choice.slice(7);
|
|
84
|
+
if (!available.includes(id))
|
|
85
|
+
continue;
|
|
86
|
+
if (selected.has(id))
|
|
87
|
+
selected.delete(id);
|
|
88
|
+
else
|
|
89
|
+
selected.add(id);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export async function runApiLoginMenu(overrides = {}) {
|
|
94
|
+
const merged = { ...defaults, ...overrides };
|
|
95
|
+
// Treat any value the menu did not offer (e.g. a reserved tier 0) as a cancel.
|
|
96
|
+
const d = {
|
|
97
|
+
...merged,
|
|
98
|
+
select: async (items, message) => {
|
|
99
|
+
const choice = await merged.select(items, message);
|
|
100
|
+
return choice !== null && items.some((item) => item.value === choice) ? choice : null;
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
if (!overrides.select && !process.stdin.isTTY) {
|
|
104
|
+
d.log("Run login --api in an interactive terminal.");
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
let routes;
|
|
108
|
+
try {
|
|
109
|
+
routes = await d.load();
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
d.log("API route configuration could not be read. Check api-routes.json and retry.");
|
|
113
|
+
return 1;
|
|
114
|
+
}
|
|
115
|
+
for (;;) {
|
|
116
|
+
const choice = await d.select([
|
|
117
|
+
{ label: "Add API credential", value: "add" },
|
|
118
|
+
...routes.map((r) => ({
|
|
119
|
+
label: `${r.label} · ${r.kind.toUpperCase()} · priority ${r.priority} · ${r.visibleModels.length} models${r.enabled ? "" : " · disabled"}`,
|
|
120
|
+
value: r.id,
|
|
121
|
+
})),
|
|
122
|
+
{ label: "Back", value: "back" },
|
|
123
|
+
], "API credentials and model routes");
|
|
124
|
+
if (!choice || choice === "back")
|
|
125
|
+
return 0;
|
|
126
|
+
try {
|
|
127
|
+
let route = routes.find((r) => r.id === choice);
|
|
128
|
+
if (choice === "add") {
|
|
129
|
+
const label = (await d.text("Credential label: ")).trim();
|
|
130
|
+
if (!label)
|
|
131
|
+
continue;
|
|
132
|
+
// Match the stored schema here, so a bad label is not reported as a key problem after discovery.
|
|
133
|
+
if (label.length > 80 || /[\x00-\x1f\x7f]/.test(label)) {
|
|
134
|
+
d.log("Credential label must be 1-80 printable characters. Nothing was saved.");
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const kind = await d.select([
|
|
138
|
+
{ label: "API", value: "api" },
|
|
139
|
+
{ label: "ZDR (operator-confirmed approval; not detected from the key)", value: "zdr" },
|
|
140
|
+
], "Choose the routing pool (ZDR is operator-declared)");
|
|
141
|
+
if (kind !== "api" && kind !== "zdr")
|
|
142
|
+
continue;
|
|
143
|
+
const apiKey = await d.secret();
|
|
144
|
+
if (!apiKey)
|
|
145
|
+
continue;
|
|
146
|
+
const priority = await d.select(Array.from({ length: 9 }, (_, offset) => {
|
|
147
|
+
const tier = 9 - offset;
|
|
148
|
+
return { label: `Priority ${tier}${tier === 9 ? " (recommended; late tier)" : ""}`, value: String(tier) };
|
|
149
|
+
}), "Failover priority");
|
|
150
|
+
if (priority === null)
|
|
151
|
+
continue;
|
|
152
|
+
route = {
|
|
153
|
+
id: randomUUID(),
|
|
154
|
+
label,
|
|
155
|
+
kind,
|
|
156
|
+
apiKey,
|
|
157
|
+
priority: Number(priority),
|
|
158
|
+
enabled: true,
|
|
159
|
+
visibleModels: [],
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
else if (route) {
|
|
163
|
+
const action = await d.select([
|
|
164
|
+
{ label: "Choose visible models", value: "models" },
|
|
165
|
+
{ label: "Change priority", value: "priority" },
|
|
166
|
+
{
|
|
167
|
+
label: route.probeCapabilities
|
|
168
|
+
? "Disable billable capability probes"
|
|
169
|
+
: "Enable small billable capability probes (15-minute cache)",
|
|
170
|
+
value: "probes",
|
|
171
|
+
},
|
|
172
|
+
{ label: route.enabled ? "Disable" : "Enable", value: "toggle" },
|
|
173
|
+
{ label: "Back", value: "back" },
|
|
174
|
+
], route.label);
|
|
175
|
+
if (!action || action === "back")
|
|
176
|
+
continue;
|
|
177
|
+
if (action === "probes")
|
|
178
|
+
route = { ...route, probeCapabilities: !route.probeCapabilities };
|
|
179
|
+
if (action === "toggle")
|
|
180
|
+
route = { ...route, enabled: !route.enabled };
|
|
181
|
+
if (action === "priority") {
|
|
182
|
+
const value = await d.select(Array.from({ length: 9 }, (_, offset) => {
|
|
183
|
+
const tier = 9 - offset;
|
|
184
|
+
return { label: `Priority ${tier}${tier === 9 ? " (recommended; late tier)" : ""}`, value: String(tier) };
|
|
185
|
+
}), "Failover priority");
|
|
186
|
+
if (value === null)
|
|
187
|
+
continue;
|
|
188
|
+
route = { ...route, priority: Number(value) };
|
|
189
|
+
}
|
|
190
|
+
if (action !== "models") {
|
|
191
|
+
const next = routes.map((r) => (r.id === route?.id ? route : r));
|
|
192
|
+
await d.save(next, routes);
|
|
193
|
+
routes = next;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (!route)
|
|
198
|
+
continue;
|
|
199
|
+
const selection = await chooseModels({ ...route, enabled: true }, d);
|
|
200
|
+
if (selection === null)
|
|
201
|
+
continue;
|
|
202
|
+
const edited = { ...route, ...selection };
|
|
203
|
+
const next = routes.some((r) => r.id === edited.id)
|
|
204
|
+
? routes.map((r) => (r.id === edited.id ? edited : r))
|
|
205
|
+
: [...routes, edited];
|
|
206
|
+
await d.save(next, routes);
|
|
207
|
+
routes = next;
|
|
208
|
+
d.log("Saved. Choose an API or ZDR model explicitly in Codex. Desktop login is unchanged.");
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
const changed = error instanceof Error && error.message.startsWith("API route configuration changed");
|
|
212
|
+
let reloaded = false;
|
|
213
|
+
try {
|
|
214
|
+
routes = await d.load();
|
|
215
|
+
reloaded = true;
|
|
216
|
+
}
|
|
217
|
+
catch { /* Keep the last readable configuration. */ }
|
|
218
|
+
d.log(changed ? (reloaded
|
|
219
|
+
? "API routes changed in another process; the latest configuration was reloaded. Repeat the edit."
|
|
220
|
+
: "API routes changed in another process and could not be reloaded. Reopen the menu before editing.") :
|
|
221
|
+
"API setup did not complete. No partial credential was saved; check the key, permissions, and configuration.");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,sBAAsB,EAEtB,sBAAsB,EAGtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IAClC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,eAAe,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAChD,eAAe,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,sBAAsB,EAEtB,sBAAsB,EAGtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE5E,MAAM,WAAW,kBAAkB;IAClC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrD,eAAe,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAChD,eAAe,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAsDD,wBAAsB,iBAAiB,CACtC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,kBAAkB,GACtB,OAAO,CAAC,MAAM,CAAC,CAkJjB"}
|
|
@@ -5,6 +5,8 @@ function printAccountUsage(logInfo) {
|
|
|
5
5
|
" codex-multi-auth account tag <index> <tag>",
|
|
6
6
|
" codex-multi-auth account untag <index> <tag>",
|
|
7
7
|
" codex-multi-auth account weight <index> <0..10>",
|
|
8
|
+
" codex-multi-auth account priority <index> <0..9>",
|
|
9
|
+
" codex-multi-auth account auto-prime <index> on|off",
|
|
8
10
|
" codex-multi-auth account pause|unpause|drain|undrain <index>",
|
|
9
11
|
" codex-multi-auth account note <index> <text>",
|
|
10
12
|
" codex-multi-auth account policy list [--json]",
|
|
@@ -33,6 +35,8 @@ function policySummary(store, storage) {
|
|
|
33
35
|
accountKey,
|
|
34
36
|
tags: policy?.tags ?? [],
|
|
35
37
|
weight: policy?.weight ?? 1,
|
|
38
|
+
priority: policy?.priority ?? 1,
|
|
39
|
+
autoPrime: policy?.autoPrime ?? false,
|
|
36
40
|
paused: policy?.paused ?? false,
|
|
37
41
|
drained: policy?.drained ?? false,
|
|
38
42
|
note: policy?.note ?? null,
|
|
@@ -78,6 +82,8 @@ export async function runAccountCommand(args, deps) {
|
|
|
78
82
|
for (const entry of payload.accounts) {
|
|
79
83
|
const markers = [
|
|
80
84
|
`weight=${entry.weight}`,
|
|
85
|
+
`priority=${entry.priority}`,
|
|
86
|
+
`auto-prime=${entry.autoPrime ? "on" : "off"}`,
|
|
81
87
|
entry.paused ? "paused" : null,
|
|
82
88
|
entry.drained ? "drained" : null,
|
|
83
89
|
entry.tags.length > 0 ? `tags=${entry.tags.join(",")}` : null,
|
|
@@ -112,6 +118,27 @@ export async function runAccountCommand(args, deps) {
|
|
|
112
118
|
logInfo(`${command === "tag" ? "Tagged" : "Removed tag from"} account ${resolved.index + 1}: ${policy.tags.join(",") || "none"}`);
|
|
113
119
|
return 0;
|
|
114
120
|
}
|
|
121
|
+
if (command === "auto-prime") {
|
|
122
|
+
if (rest.length !== 2 || !["on", "off"].includes(rest[1] ?? "")) {
|
|
123
|
+
logError("auto-prime requires on or off.");
|
|
124
|
+
return 1;
|
|
125
|
+
}
|
|
126
|
+
upsertAccountPolicy(store, accountKey, next => { next.autoPrime = rest[1] === "on"; }, now);
|
|
127
|
+
await saveStore(store);
|
|
128
|
+
logInfo(`Automatic priming ${rest[1]} for account ${resolved.index + 1}. ${rest[1] === "on" ? "The running router checks every 15 minutes; first-use completion consumes subscription quota." : "Future automatic checks are disabled."}`);
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
if (command === "priority") {
|
|
132
|
+
if (!/^[0-9]$/.test(rest[1] ?? "") || rest.length !== 2) {
|
|
133
|
+
logError("priority requires an integer from 0 to 9 (0 first).");
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
const priority = Number(rest[1]);
|
|
137
|
+
upsertAccountPolicy(store, accountKey, next => { next.priority = priority; }, now);
|
|
138
|
+
await saveStore(store);
|
|
139
|
+
logInfo(`Set account ${resolved.index + 1} priority to ${priority}.`);
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
115
142
|
if (command === "weight") {
|
|
116
143
|
const weight = rest[1] === undefined ? Number.NaN : Number.parseFloat(rest[1]);
|
|
117
144
|
if (!Number.isFinite(weight) || weight < 0 || weight > 10) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"best.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/best.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"best.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/best.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { codexCliAccountIdFor, shouldUpdateAccountIdFromToken, } from "../../auth/token-utils.js";
|
|
1
2
|
import { describeCodexProbeFailure } from "../../quota-probe.js";
|
|
2
3
|
import { getModelProfile, resolveNormalizedModel, } from "../../request/helpers/model-map.js";
|
|
3
4
|
import { DEFAULT_LIVE_PROBE_MODEL } from "../quota-cache-helpers.js";
|
|
@@ -138,7 +139,10 @@ export async function runBestCommand(args, deps) {
|
|
|
138
139
|
account.expiresAt = refreshResult.expires;
|
|
139
140
|
if (refreshedEmail)
|
|
140
141
|
account.email = refreshedEmail;
|
|
141
|
-
|
|
142
|
+
// Same rule as every other refresh path: only a token-derived id
|
|
143
|
+
// follows the new token; an explicit (manual) or org binding stays.
|
|
144
|
+
if (refreshedAccountId &&
|
|
145
|
+
shouldUpdateAccountIdFromToken(account.accountIdSource, account.accountId)) {
|
|
142
146
|
account.accountId = refreshedAccountId;
|
|
143
147
|
account.accountIdSource = "token";
|
|
144
148
|
}
|
|
@@ -235,7 +239,7 @@ export async function runBestCommand(args, deps) {
|
|
|
235
239
|
});
|
|
236
240
|
if (shouldSyncCurrentBest) {
|
|
237
241
|
alreadyBestSynced = await deps.setCodexCliActiveSelection({
|
|
238
|
-
accountId: bestAccount.
|
|
242
|
+
accountId: codexCliAccountIdFor(bestAccount, bestAccount.accessToken, probeIdTokenByIndex.get(bestIndex)),
|
|
239
243
|
email: bestAccount.email,
|
|
240
244
|
accessToken: bestAccount.accessToken,
|
|
241
245
|
refreshToken: bestAccount.refreshToken,
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export interface CheckCommandDeps {
|
|
2
2
|
runHealthCheck: (options: {
|
|
3
3
|
liveProbe: boolean;
|
|
4
|
+
discoverModels: boolean;
|
|
5
|
+
primeUnusedSubscription: boolean;
|
|
4
6
|
}) => Promise<void>;
|
|
7
|
+
runResetCheck: () => Promise<number>;
|
|
8
|
+
runCapabilityCheck: () => Promise<boolean>;
|
|
9
|
+
logInfo?: (message: string) => void;
|
|
10
|
+
logError?: (message: string) => void;
|
|
5
11
|
}
|
|
6
|
-
export declare function runCheckCommand(deps: CheckCommandDeps): Promise<number>;
|
|
12
|
+
export declare function runCheckCommand(deps: CheckCommandDeps, args?: string[]): Promise<number>;
|
|
7
13
|
//# sourceMappingURL=check.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/check.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,cAAc,EAAE,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,uBAAuB,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9H,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,kBAAkB,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlG"}
|
|
@@ -1,4 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { runWithGlobalStoragePath } from "../../storage/path-state.js";
|
|
2
|
+
const usage = "Usage: codex-multi-auth check [accounts|resets|capabilities] [--prime]";
|
|
3
|
+
export async function runCheckCommand(deps, args = []) {
|
|
4
|
+
if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
|
|
5
|
+
(deps.logInfo ?? console.log)(usage);
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
// Priming starts an unused subscription's 5h/weekly windows, so it is never implicit.
|
|
9
|
+
const prime = args.includes("--prime");
|
|
10
|
+
const rest = args.filter((arg) => arg !== "--prime");
|
|
11
|
+
const [scope] = rest;
|
|
12
|
+
if (rest.length > 1 || args.length - rest.length > 1 || (scope !== undefined && !["accounts", "resets", "capabilities"].includes(scope)) || (prime && scope !== undefined && scope !== "accounts")) {
|
|
13
|
+
(deps.logError ?? console.error)(usage);
|
|
14
|
+
return 1;
|
|
15
|
+
}
|
|
16
|
+
return runWithGlobalStoragePath(async () => {
|
|
17
|
+
if (scope === "resets")
|
|
18
|
+
return await deps.runResetCheck();
|
|
19
|
+
if (scope === "capabilities")
|
|
20
|
+
return await deps.runCapabilityCheck() ? 0 : 1;
|
|
21
|
+
else
|
|
22
|
+
await deps.runHealthCheck({ liveProbe: true, discoverModels: scope === undefined, primeUnusedSubscription: prime });
|
|
23
|
+
return 0;
|
|
24
|
+
});
|
|
4
25
|
}
|
|
@@ -17,7 +17,7 @@ export interface ForecastCommandDeps {
|
|
|
17
17
|
loadDashboardDisplaySettings?: () => Promise<DashboardDisplaySettings>;
|
|
18
18
|
resolveActiveIndex: (storage: AccountStorageV3, family?: "codex") => number;
|
|
19
19
|
loadQuotaCache: () => Promise<QuotaCacheData | null>;
|
|
20
|
-
saveQuotaCache: (cache: QuotaCacheData) => Promise<void>;
|
|
20
|
+
saveQuotaCache: (cache: QuotaCacheData, baseline?: QuotaCacheData) => Promise<void>;
|
|
21
21
|
cloneQuotaCacheData: (cache: QuotaCacheData) => QuotaCacheData;
|
|
22
22
|
buildQuotaEmailFallbackState: (accounts: readonly Pick<AccountMetadataV3, "accountId" | "email">[]) => QuotaEmailFallbackState;
|
|
23
23
|
updateQuotaCacheForAccount: (cache: QuotaCacheData, account: Pick<AccountMetadataV3, "accountId" | "email">, snapshot: CodexQuotaSnapshot, accounts: readonly Pick<AccountMetadataV3, "accountId" | "email">[], emailFallbackState?: QuotaEmailFallbackState) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/forecast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"forecast.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/forecast.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { extractAccountEmail, sanitizeEmail } from "../../accounts.js";
|
|
2
|
+
import { shouldUpdateAccountIdFromToken } from "../../auth/token-utils.js";
|
|
2
3
|
import { buildForecastExplanation, } from "../../forecast.js";
|
|
3
4
|
import { applyRefreshedAccountPatch, persistRefreshedAccountPatch, serializeForecastResults, } from "../forecast-report-shared.js";
|
|
4
5
|
import { describeCodexProbeFailure } from "../../quota-probe.js";
|
|
@@ -147,7 +148,10 @@ export async function runForecastCommand(args, deps) {
|
|
|
147
148
|
if (refreshedEmail) {
|
|
148
149
|
refreshPatch.email = refreshedEmail;
|
|
149
150
|
}
|
|
150
|
-
|
|
151
|
+
// Only a token-derived id follows the new token (as on every other
|
|
152
|
+
// refresh path); an explicit (manual) or org binding stays.
|
|
153
|
+
if (refreshedAccountId &&
|
|
154
|
+
shouldUpdateAccountIdFromToken(account.accountIdSource, account.accountId)) {
|
|
151
155
|
refreshPatch.accountId = refreshedAccountId;
|
|
152
156
|
refreshPatch.accountIdSource = "token";
|
|
153
157
|
}
|
|
@@ -230,7 +234,7 @@ export async function runForecastCommand(args, deps) {
|
|
|
230
234
|
if (options.json) {
|
|
231
235
|
if (workingQuotaCache && quotaCacheChanged) {
|
|
232
236
|
try {
|
|
233
|
-
await deps.saveQuotaCache(workingQuotaCache);
|
|
237
|
+
await deps.saveQuotaCache(workingQuotaCache, quotaCache ?? undefined);
|
|
234
238
|
}
|
|
235
239
|
catch (error) {
|
|
236
240
|
// Quota cache is a derived artifact; a transient Windows EBUSY/
|
|
@@ -330,7 +334,7 @@ export async function runForecastCommand(args, deps) {
|
|
|
330
334
|
}
|
|
331
335
|
if (workingQuotaCache && quotaCacheChanged) {
|
|
332
336
|
try {
|
|
333
|
-
await deps.saveQuotaCache(workingQuotaCache);
|
|
337
|
+
await deps.saveQuotaCache(workingQuotaCache, quotaCache ?? undefined);
|
|
334
338
|
}
|
|
335
339
|
catch (error) {
|
|
336
340
|
// Quota cache is a derived artifact; tolerate transient Windows
|