oc-codex-multi-auth 6.23.0 → 6.25.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.
- package/LICENSE +21 -21
- package/README.md +795 -729
- package/assets/icon.svg +7 -7
- package/assets/opencode-logo-ornate-dark.svg +18 -18
- package/assets/readme-hero.svg +31 -31
- package/config/README.md +197 -197
- package/config/minimal-opencode.json +14 -14
- package/config/opencode-legacy.json +1346 -1346
- package/config/opencode-modern.json +466 -466
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -57
- package/dist/index.js.map +1 -1
- package/dist/lib/accounts/persistence.d.ts +6 -6
- package/dist/lib/accounts/persistence.d.ts.map +1 -1
- package/dist/lib/accounts/persistence.js +60 -6
- package/dist/lib/accounts/persistence.js.map +1 -1
- package/dist/lib/accounts/recovery.d.ts +5 -1
- package/dist/lib/accounts/recovery.d.ts.map +1 -1
- package/dist/lib/accounts/recovery.js +26 -1
- package/dist/lib/accounts/recovery.js.map +1 -1
- package/dist/lib/accounts/state.d.ts +18 -0
- package/dist/lib/accounts/state.d.ts.map +1 -1
- package/dist/lib/accounts/state.js +26 -2
- package/dist/lib/accounts/state.js.map +1 -1
- package/dist/lib/accounts.d.ts +2 -0
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/accounts.js +7 -1
- package/dist/lib/accounts.js.map +1 -1
- package/dist/lib/auth/login-runner.d.ts.map +1 -1
- package/dist/lib/auth/login-runner.js +8 -0
- package/dist/lib/auth/login-runner.js.map +1 -1
- package/dist/lib/auth/plan-tier.d.ts.map +1 -1
- package/dist/lib/auth/plan-tier.js +2 -1
- package/dist/lib/auth/plan-tier.js.map +1 -1
- package/dist/lib/codex-usage.d.ts +84 -0
- package/dist/lib/codex-usage.d.ts.map +1 -1
- package/dist/lib/codex-usage.js +186 -5
- package/dist/lib/codex-usage.js.map +1 -1
- package/dist/lib/config.d.ts +16 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +14 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/context-overflow.js +10 -10
- package/dist/lib/desktop-notifications.js +6 -6
- package/dist/lib/oauth-success.js +202 -202
- package/dist/lib/opencode-v2-provider.d.ts +2 -0
- package/dist/lib/opencode-v2-provider.d.ts.map +1 -0
- package/dist/lib/opencode-v2-provider.js +4 -0
- package/dist/lib/opencode-v2-provider.js.map +1 -0
- package/dist/lib/opencode-v2-rpc.d.ts +31 -0
- package/dist/lib/opencode-v2-rpc.d.ts.map +1 -0
- package/dist/lib/opencode-v2-rpc.js +17 -0
- package/dist/lib/opencode-v2-rpc.js.map +1 -0
- package/dist/lib/opencode-v2-status.d.ts +18 -0
- package/dist/lib/opencode-v2-status.d.ts.map +1 -0
- package/dist/lib/opencode-v2-status.js +98 -0
- package/dist/lib/opencode-v2-status.js.map +1 -0
- package/dist/lib/opencode-v2-tui.d.ts +4 -0
- package/dist/lib/opencode-v2-tui.d.ts.map +1 -0
- package/dist/lib/opencode-v2-tui.js +112 -0
- package/dist/lib/opencode-v2-tui.js.map +1 -0
- package/dist/lib/opencode-v2.d.ts +11 -0
- package/dist/lib/opencode-v2.d.ts.map +1 -0
- package/dist/lib/opencode-v2.js +235 -0
- package/dist/lib/opencode-v2.js.map +1 -0
- package/dist/lib/prompts/codex-opencode-bridge.js +67 -67
- package/dist/lib/prompts/codex.d.ts.map +1 -1
- package/dist/lib/prompts/codex.js +79 -75
- package/dist/lib/prompts/codex.js.map +1 -1
- package/dist/lib/quota-capacity.d.ts +4 -0
- package/dist/lib/quota-capacity.d.ts.map +1 -0
- package/dist/lib/quota-capacity.js +45 -0
- package/dist/lib/quota-capacity.js.map +1 -0
- package/dist/lib/quota-overview.d.ts +13 -27
- package/dist/lib/quota-overview.d.ts.map +1 -1
- package/dist/lib/quota-overview.js +59 -99
- package/dist/lib/quota-overview.js.map +1 -1
- package/dist/lib/quota-recovery.d.ts +5 -0
- package/dist/lib/quota-recovery.d.ts.map +1 -0
- package/dist/lib/quota-recovery.js +66 -0
- package/dist/lib/quota-recovery.js.map +1 -0
- package/dist/lib/request/fetch-helpers.d.ts +1 -1
- package/dist/lib/request/fetch-helpers.d.ts.map +1 -1
- package/dist/lib/request/fetch-helpers.js +1 -1
- package/dist/lib/request/fetch-helpers.js.map +1 -1
- package/dist/lib/schemas.d.ts +14 -1
- package/dist/lib/schemas.d.ts.map +1 -1
- package/dist/lib/schemas.js +7 -2
- package/dist/lib/schemas.js.map +1 -1
- package/dist/lib/storage/load-save.d.ts.map +1 -1
- package/dist/lib/storage/load-save.js +22 -20
- package/dist/lib/storage/load-save.js.map +1 -1
- package/dist/lib/storage/state.d.ts +8 -0
- package/dist/lib/storage/state.d.ts.map +1 -1
- package/dist/lib/storage/state.js +47 -20
- package/dist/lib/storage/state.js.map +1 -1
- package/dist/lib/tools/codex-limits.d.ts.map +1 -1
- package/dist/lib/tools/codex-limits.js +49 -3
- package/dist/lib/tools/codex-limits.js.map +1 -1
- package/dist/lib/tui-quota-cache.d.ts +8 -0
- package/dist/lib/tui-quota-cache.d.ts.map +1 -1
- package/dist/lib/tui-quota-cache.js +4 -1
- package/dist/lib/tui-quota-cache.js.map +1 -1
- package/dist/lib/tui-quota-overview.d.ts.map +1 -1
- package/dist/lib/tui-quota-overview.js +15 -2
- package/dist/lib/tui-quota-overview.js.map +1 -1
- package/dist/lib/tui-status-slot.d.ts +3 -0
- package/dist/lib/tui-status-slot.d.ts.map +1 -0
- package/dist/lib/tui-status-slot.js +27 -0
- package/dist/lib/tui-status-slot.js.map +1 -0
- package/dist/lib/tui-status.d.ts +1 -0
- package/dist/lib/tui-status.d.ts.map +1 -1
- package/dist/lib/tui-status.js +1 -0
- package/dist/lib/tui-status.js.map +1 -1
- package/dist/tui.d.ts +10 -3
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +22 -1
- package/dist/tui.js.map +1 -1
- package/package.json +157 -155
- package/scripts/audit-dev-allowlist.js +114 -114
- package/scripts/clean-dist.js +27 -27
- package/scripts/copy-oauth-success.js +47 -47
- package/scripts/install-oc-codex-multi-auth-core.js +2661 -2016
- package/scripts/install-oc-codex-multi-auth.js +37 -37
- package/scripts/test-all-models.sh +260 -260
- package/scripts/validate-model-map.sh +97 -97
package/dist/index.d.ts
CHANGED
|
@@ -41,5 +41,11 @@ import type { Plugin } from "@opencode-ai/plugin";
|
|
|
41
41
|
*/
|
|
42
42
|
export declare const OpenAIOAuthPlugin: Plugin;
|
|
43
43
|
export declare const OpenAIAuthPlugin: Plugin;
|
|
44
|
-
|
|
44
|
+
declare const _default: {
|
|
45
|
+
id: string;
|
|
46
|
+
server: Plugin;
|
|
47
|
+
/** V2 loads the same package through setup instead of the V1 server hook. */
|
|
48
|
+
setup(context: import("@opencode/plugin").Plugin.Context): Promise<() => Promise<void>>;
|
|
49
|
+
};
|
|
50
|
+
export default _default;
|
|
45
51
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAYH,OAAO,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAYH,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AAsVtE;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAA2E,CAAC;AAupJ5G,eAAO,MAAM,gBAAgB,QAAoB,CAAC;;;;IAKjD,6EAA6E;mBACxD,OAAO,kBAAkB,EAAE,MAAM,CAAC,OAAO;;AAJ/D,wBAQE"}
|
package/dist/index.js
CHANGED
|
@@ -179,8 +179,16 @@ function resolveOpenAIBaseURL() {
|
|
|
179
179
|
* }
|
|
180
180
|
* ```
|
|
181
181
|
*/
|
|
182
|
-
export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
183
|
-
|
|
182
|
+
export const OpenAIOAuthPlugin = async ({ client }) => createPluginRuntime({ client });
|
|
183
|
+
/**
|
|
184
|
+
* Shared request/account runtime; V2 has no V1 client or host auth.json.
|
|
185
|
+
*
|
|
186
|
+
* Not exported: V1 hosts call every function this module exports as a plugin,
|
|
187
|
+
* so an exported factory would boot a second runtime beside the real one. The
|
|
188
|
+
* V2 entry receives it through `setup` instead.
|
|
189
|
+
*/
|
|
190
|
+
async function createPluginRuntime({ client, directory = process.cwd() }) {
|
|
191
|
+
initLogger(client ?? {});
|
|
184
192
|
let customBaseURLWarningShown = false;
|
|
185
193
|
let customBaseURLErrorShown = false;
|
|
186
194
|
let cachedAccountManager = null;
|
|
@@ -456,7 +464,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
456
464
|
};
|
|
457
465
|
const showToast = async (message, variant = "success", options) => {
|
|
458
466
|
try {
|
|
459
|
-
await client
|
|
467
|
+
await client?.tui.showToast({
|
|
460
468
|
body: {
|
|
461
469
|
message,
|
|
462
470
|
variant,
|
|
@@ -1478,6 +1486,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1478
1486
|
if (event.type === "server.instance.disposed") {
|
|
1479
1487
|
quotaMonitor.dispose();
|
|
1480
1488
|
disposeAccountsWatcher();
|
|
1489
|
+
await cachedAccountManager?.flushPendingSave();
|
|
1490
|
+
cachedAccountManager?.disposeShutdownHandler();
|
|
1481
1491
|
return;
|
|
1482
1492
|
}
|
|
1483
1493
|
// Handle TUI account selection events
|
|
@@ -1585,8 +1595,9 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1585
1595
|
};
|
|
1586
1596
|
const startupPluginConfig = loadPluginConfig();
|
|
1587
1597
|
const startupPerProjectAccounts = getPerProjectAccounts(startupPluginConfig);
|
|
1588
|
-
setStoragePath(startupPerProjectAccounts ?
|
|
1589
|
-
|
|
1598
|
+
setStoragePath(startupPerProjectAccounts ? directory : null);
|
|
1599
|
+
if (client)
|
|
1600
|
+
await backfillHostOpenAIAuthFromPool();
|
|
1590
1601
|
quotaMonitor.start();
|
|
1591
1602
|
return {
|
|
1592
1603
|
event: eventHandler,
|
|
@@ -1635,7 +1646,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1635
1646
|
let perProjectAccounts = getPerProjectAccounts(pluginConfig);
|
|
1636
1647
|
let storageTransition;
|
|
1637
1648
|
const activeFetches = new Set();
|
|
1638
|
-
setStoragePath(perProjectAccounts ?
|
|
1649
|
+
setStoragePath(perProjectAccounts ? directory : null);
|
|
1639
1650
|
const authFallback = auth.type === "oauth" ? auth : undefined;
|
|
1640
1651
|
// Prefer multi-account auth metadata when available, but still handle
|
|
1641
1652
|
// plain OAuth credentials (for OpenCode versions that inject internal
|
|
@@ -1744,8 +1755,8 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1744
1755
|
prewarmOpenCodeCodexPrompt();
|
|
1745
1756
|
}
|
|
1746
1757
|
}
|
|
1747
|
-
const recoveryHook = sessionRecoveryEnabled
|
|
1748
|
-
? createSessionRecoveryHook({ client, directory
|
|
1758
|
+
const recoveryHook = sessionRecoveryEnabled && client
|
|
1759
|
+
? createSessionRecoveryHook({ client, directory }, { sessionRecovery: true, autoResume: autoResumeEnabled })
|
|
1749
1760
|
: null;
|
|
1750
1761
|
const pluginOrigin = getPluginOrigin();
|
|
1751
1762
|
if (pluginOrigin && !startupOriginRecorded) {
|
|
@@ -1800,7 +1811,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
1800
1811
|
await Promise.all(activeFetches);
|
|
1801
1812
|
// Drain the old pool's pending write before changing the global path.
|
|
1802
1813
|
await cachedAccountManager?.flushPendingSave();
|
|
1803
|
-
setStoragePath(currentPerProjectAccounts ?
|
|
1814
|
+
setStoragePath(currentPerProjectAccounts ? directory : null);
|
|
1804
1815
|
invalidateAccountManagerCache();
|
|
1805
1816
|
perProjectAccounts = currentPerProjectAccounts;
|
|
1806
1817
|
})().finally(() => { storageTransition = undefined; });
|
|
@@ -2203,7 +2214,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2203
2214
|
accountManager = reloaded;
|
|
2204
2215
|
}
|
|
2205
2216
|
}
|
|
2206
|
-
|
|
2217
|
+
const accountCount = accountManager.getAccountCount();
|
|
2207
2218
|
const attempted = new Set();
|
|
2208
2219
|
// Diagnostics for the terminal error message below. The composite key keeps
|
|
2209
2220
|
// legacy Business seats distinct and can also be compared with snapshots
|
|
@@ -2303,9 +2314,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2303
2314
|
runtimeMetrics.lastError = err?.message ?? String(err);
|
|
2304
2315
|
runtimeMetrics.lastErrorCategory = "auth-refresh";
|
|
2305
2316
|
// Transient refresh failures (network blip / upstream 5xx) must NOT
|
|
2306
|
-
// count toward
|
|
2307
|
-
// valid and a flaky network or outage would otherwise silently delete
|
|
2308
|
-
// them. Cool the account down briefly and rotate instead.
|
|
2317
|
+
// count toward disabling an account. Cool it down and rotate instead.
|
|
2309
2318
|
const isTransientRefreshFailure = err instanceof CodexAuthError && err.retryable === true;
|
|
2310
2319
|
if (isTransientRefreshFailure) {
|
|
2311
2320
|
const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
@@ -2313,7 +2322,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2313
2322
|
accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
2314
2323
|
}
|
|
2315
2324
|
accountManager.saveToDiskDebounced();
|
|
2316
|
-
logWarn(`[${PLUGIN_NAME}] Transient auth refresh failure for account ${account.index + 1} (${err.refreshFailureReason ?? "unknown"}${err.statusCode ? ` ${err.statusCode}` : ""}); cooling down without
|
|
2325
|
+
logWarn(`[${PLUGIN_NAME}] Transient auth refresh failure for account ${account.index + 1} (${err.refreshFailureReason ?? "unknown"}${err.statusCode ? ` ${err.statusCode}` : ""}); cooling down without disabling.`);
|
|
2317
2326
|
continue;
|
|
2318
2327
|
}
|
|
2319
2328
|
const failures = await accountManager.incrementAuthFailures(account);
|
|
@@ -2322,27 +2331,19 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2322
2331
|
peerAccounts: accountManager.getAccountsSnapshot(),
|
|
2323
2332
|
});
|
|
2324
2333
|
if (failures >= ACCOUNT_LIMITS.MAX_AUTH_FAILURES_BEFORE_REMOVAL) {
|
|
2325
|
-
const
|
|
2326
|
-
if (
|
|
2327
|
-
logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after auth failures, but removed ${removedCount}.`);
|
|
2328
|
-
const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
2329
|
-
if (cooledCount <= 0) {
|
|
2330
|
-
logWarn(`[${PLUGIN_NAME}] Unable to apply auth-failure cooldown; no live account found for refresh token.`);
|
|
2331
|
-
}
|
|
2334
|
+
const disabledCount = accountManager.disableAccountsWithSameRefreshToken(account);
|
|
2335
|
+
if (disabledCount > 0) {
|
|
2332
2336
|
accountManager.saveToDiskDebounced();
|
|
2337
|
+
await showToast(disabledCount > 1
|
|
2338
|
+
? `Disabled ${disabledCount} accounts after ${failures} auth failures; credentials retained. Run 'opencode auth login' to repair.`
|
|
2339
|
+
: `Disabled ${accountLabel} after ${failures} auth failures; credentials retained. Run 'opencode auth login' to repair.`, "error", { duration: toastDurationMs * 2 });
|
|
2333
2340
|
continue;
|
|
2334
2341
|
}
|
|
2335
|
-
accountManager.saveToDiskDebounced();
|
|
2336
|
-
const removalMessage = removedCount > 1
|
|
2337
|
-
? `Removed ${removedCount} accounts (same refresh token) after ${failures} consecutive auth failures. Run 'opencode auth login' to re-add.`
|
|
2338
|
-
: `Removed ${accountLabel} after ${failures} consecutive auth failures. Run 'opencode auth login' to re-add.`;
|
|
2339
|
-
await showToast(removalMessage, "error", { duration: toastDurationMs * 2 });
|
|
2340
|
-
// Restart traversal: clear attempted and refresh accountCount to avoid skipping healthy accounts
|
|
2341
|
-
attempted.clear();
|
|
2342
|
-
accountCount = accountManager.getAccountCount();
|
|
2343
|
-
continue;
|
|
2344
2342
|
}
|
|
2345
|
-
accountManager.
|
|
2343
|
+
const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
2344
|
+
if (cooledCount <= 0) {
|
|
2345
|
+
accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
2346
|
+
}
|
|
2346
2347
|
accountManager.saveToDiskDebounced();
|
|
2347
2348
|
continue;
|
|
2348
2349
|
}
|
|
@@ -2605,23 +2606,22 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2605
2606
|
catch (flagError) {
|
|
2606
2607
|
logWarn(`Failed to persist deactivated workspace flag for ${accountLabel}: ${flagError instanceof Error ? flagError.message : String(flagError)}`);
|
|
2607
2608
|
}
|
|
2608
|
-
//
|
|
2609
|
+
// Disable ONLY the deactivated workspace, scoped by workspace
|
|
2609
2610
|
// identity (org/account id). A single multi-org OAuth login
|
|
2610
2611
|
// produces sibling accounts that share one refresh token but are
|
|
2611
|
-
// independently valid;
|
|
2612
|
+
// independently valid; disabling all refresh-token siblings here
|
|
2612
2613
|
// would silently drop still-valid workspaces from rotation. The
|
|
2613
2614
|
// refresh token itself is still good, so siblings must survive.
|
|
2614
|
-
const
|
|
2615
|
-
if (
|
|
2615
|
+
const disabledCount = accountManager.disableAccountsByWorkspaceIdentity(account);
|
|
2616
|
+
if (disabledCount > 0) {
|
|
2616
2617
|
accountManager.saveToDiskDebounced();
|
|
2617
2618
|
restartAccountTraversalAfterWorkspaceDeactivation = true;
|
|
2618
|
-
const removalMessage =
|
|
2619
|
-
? `Workspace deactivated.
|
|
2620
|
-
: `Workspace deactivated.
|
|
2619
|
+
const removalMessage = disabledCount > 1
|
|
2620
|
+
? `Workspace deactivated. Disabled ${disabledCount} related entries; credentials retained.`
|
|
2621
|
+
: `Workspace deactivated. Disabled ${accountLabel}; credentials retained.`;
|
|
2621
2622
|
await showToast(removalMessage, "warning", { duration: toastDurationMs });
|
|
2622
2623
|
break;
|
|
2623
2624
|
}
|
|
2624
|
-
logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after workspace deactivation, but removed ${removedCount}.`);
|
|
2625
2625
|
accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
2626
2626
|
accountManager.saveToDiskDebounced();
|
|
2627
2627
|
break;
|
|
@@ -2782,7 +2782,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2782
2782
|
// explicit handler the 401 fell straight through to `return errorResponse`
|
|
2783
2783
|
// below, so persisted family routing kept pinning every request to the dead
|
|
2784
2784
|
// account slot instead of failing over (issue #171). Treat it as an
|
|
2785
|
-
// account-health failure: cool the refresh-token group down (or
|
|
2785
|
+
// account-health failure: cool the refresh-token group down (or disable it
|
|
2786
2786
|
// past the failure threshold) and rotate to the next healthy account.
|
|
2787
2787
|
//
|
|
2788
2788
|
// Note: 401s intentionally do NOT feed the circuit breaker — the breaker
|
|
@@ -2802,21 +2802,16 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
2802
2802
|
runtimeMetrics.lastErrorCategory = "auth-invalidated";
|
|
2803
2803
|
const failures = await accountManager.incrementAuthFailures(account);
|
|
2804
2804
|
if (failures >= ACCOUNT_LIMITS.MAX_AUTH_FAILURES_BEFORE_REMOVAL) {
|
|
2805
|
-
const
|
|
2806
|
-
if (
|
|
2805
|
+
const disabledCount = accountManager.disableAccountsWithSameRefreshToken(account);
|
|
2806
|
+
if (disabledCount > 0) {
|
|
2807
2807
|
accountManager.saveToDiskDebounced();
|
|
2808
|
-
await showToast(
|
|
2809
|
-
? `
|
|
2810
|
-
: `
|
|
2811
|
-
// Indices shift after removal; restart traversal with a fresh
|
|
2812
|
-
// attempted set so no healthy account is skipped.
|
|
2813
|
-
attempted.clear();
|
|
2814
|
-
accountCount = accountManager.getAccountCount();
|
|
2808
|
+
await showToast(disabledCount > 1
|
|
2809
|
+
? `Disabled ${disabledCount} accounts after ${failures} auth-token failures; credentials retained. Run 'opencode auth login' to repair.`
|
|
2810
|
+
: `Disabled ${accountLabel} after ${failures} auth-token failures; credentials retained. Run 'opencode auth login' to repair.`, "error", { duration: toastDurationMs * 2 });
|
|
2815
2811
|
break;
|
|
2816
2812
|
}
|
|
2817
|
-
logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after auth-token invalidation, but removed ${removedCount}.`);
|
|
2818
2813
|
}
|
|
2819
|
-
// Below the
|
|
2814
|
+
// Below the disable threshold (or the group was already disabled): cool the
|
|
2820
2815
|
// account's whole refresh-token group down so selection skips it, then
|
|
2821
2816
|
// rotate to the next healthy account instead of returning the 401.
|
|
2822
2817
|
const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
|
|
@@ -3127,7 +3122,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
3127
3122
|
const authPluginConfig = loadPluginConfig();
|
|
3128
3123
|
applyUiRuntimeFromConfig(authPluginConfig);
|
|
3129
3124
|
const authPerProjectAccounts = getPerProjectAccounts(authPluginConfig);
|
|
3130
|
-
setStoragePath(authPerProjectAccounts ?
|
|
3125
|
+
setStoragePath(authPerProjectAccounts ? directory : null);
|
|
3131
3126
|
const accounts = [];
|
|
3132
3127
|
// Programmatic input, not a menu choice: a headless caller or
|
|
3133
3128
|
// script passes it to say "never launch a browser". Ignoring it
|
|
@@ -3886,7 +3881,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
3886
3881
|
const manualBrowserPluginConfig = loadPluginConfig();
|
|
3887
3882
|
applyUiRuntimeFromConfig(manualBrowserPluginConfig);
|
|
3888
3883
|
const manualBrowserPerProjectAccounts = getPerProjectAccounts(manualBrowserPluginConfig);
|
|
3889
|
-
setStoragePath(manualBrowserPerProjectAccounts ?
|
|
3884
|
+
setStoragePath(manualBrowserPerProjectAccounts ? directory : null);
|
|
3890
3885
|
const session = await startLoopbackFlow({ openBrowser: false });
|
|
3891
3886
|
if (session.type === "unavailable") {
|
|
3892
3887
|
const message = unavailableMessage(session.lifecycle);
|
|
@@ -3934,7 +3929,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
3934
3929
|
const devicePluginConfig = loadPluginConfig();
|
|
3935
3930
|
applyUiRuntimeFromConfig(devicePluginConfig);
|
|
3936
3931
|
const devicePerProjectAccounts = getPerProjectAccounts(devicePluginConfig);
|
|
3937
|
-
setStoragePath(devicePerProjectAccounts ?
|
|
3932
|
+
setStoragePath(devicePerProjectAccounts ? directory : null);
|
|
3938
3933
|
const started = await createDeviceCodeSession();
|
|
3939
3934
|
if (started.type === "failed") {
|
|
3940
3935
|
return {
|
|
@@ -3972,7 +3967,7 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
3972
3967
|
const manualPluginConfig = loadPluginConfig();
|
|
3973
3968
|
applyUiRuntimeFromConfig(manualPluginConfig);
|
|
3974
3969
|
const manualPerProjectAccounts = getPerProjectAccounts(manualPluginConfig);
|
|
3975
|
-
setStoragePath(manualPerProjectAccounts ?
|
|
3970
|
+
setStoragePath(manualPerProjectAccounts ? directory : null);
|
|
3976
3971
|
const { pkce, state, url } = await createAuthorizationFlow();
|
|
3977
3972
|
return buildManualOAuthFlow(pkce, url, state, false);
|
|
3978
3973
|
},
|
|
@@ -3981,7 +3976,16 @@ export const OpenAIOAuthPlugin = async ({ client }) => {
|
|
|
3981
3976
|
},
|
|
3982
3977
|
tool: createToolRegistry(ctx),
|
|
3983
3978
|
};
|
|
3984
|
-
}
|
|
3979
|
+
}
|
|
3980
|
+
;
|
|
3985
3981
|
export const OpenAIAuthPlugin = OpenAIOAuthPlugin;
|
|
3986
|
-
export default
|
|
3982
|
+
export default {
|
|
3983
|
+
id: "oc-codex-multi-auth",
|
|
3984
|
+
server: OpenAIOAuthPlugin,
|
|
3985
|
+
/** V2 loads the same package through setup instead of the V1 server hook. */
|
|
3986
|
+
async setup(context) {
|
|
3987
|
+
const { setupV2 } = await import("./lib/opencode-v2.js");
|
|
3988
|
+
return setupV2(context, createPluginRuntime);
|
|
3989
|
+
},
|
|
3990
|
+
};
|
|
3987
3991
|
//# sourceMappingURL=index.js.map
|