oc-codex-multi-auth 6.24.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.
Files changed (80) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +795 -793
  3. package/assets/icon.svg +7 -7
  4. package/assets/opencode-logo-ornate-dark.svg +18 -18
  5. package/assets/readme-hero.svg +31 -31
  6. package/config/README.md +197 -197
  7. package/config/minimal-opencode.json +14 -14
  8. package/config/opencode-legacy.json +1346 -1346
  9. package/config/opencode-modern.json +466 -466
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +26 -42
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/accounts/persistence.d.ts +6 -6
  14. package/dist/lib/accounts/persistence.d.ts.map +1 -1
  15. package/dist/lib/accounts/persistence.js +60 -6
  16. package/dist/lib/accounts/persistence.js.map +1 -1
  17. package/dist/lib/accounts/recovery.d.ts +5 -1
  18. package/dist/lib/accounts/recovery.d.ts.map +1 -1
  19. package/dist/lib/accounts/recovery.js +26 -1
  20. package/dist/lib/accounts/recovery.js.map +1 -1
  21. package/dist/lib/accounts/state.d.ts +18 -0
  22. package/dist/lib/accounts/state.d.ts.map +1 -1
  23. package/dist/lib/accounts/state.js +26 -2
  24. package/dist/lib/accounts/state.js.map +1 -1
  25. package/dist/lib/accounts.d.ts +2 -0
  26. package/dist/lib/accounts.d.ts.map +1 -1
  27. package/dist/lib/accounts.js +7 -1
  28. package/dist/lib/accounts.js.map +1 -1
  29. package/dist/lib/auth/login-runner.d.ts.map +1 -1
  30. package/dist/lib/auth/login-runner.js +8 -0
  31. package/dist/lib/auth/login-runner.js.map +1 -1
  32. package/dist/lib/auth/plan-tier.d.ts.map +1 -1
  33. package/dist/lib/auth/plan-tier.js +2 -1
  34. package/dist/lib/auth/plan-tier.js.map +1 -1
  35. package/dist/lib/codex-usage.d.ts +49 -0
  36. package/dist/lib/codex-usage.d.ts.map +1 -1
  37. package/dist/lib/codex-usage.js +135 -5
  38. package/dist/lib/codex-usage.js.map +1 -1
  39. package/dist/lib/config.d.ts +11 -0
  40. package/dist/lib/config.d.ts.map +1 -1
  41. package/dist/lib/config.js +12 -0
  42. package/dist/lib/config.js.map +1 -1
  43. package/dist/lib/context-overflow.js +10 -10
  44. package/dist/lib/desktop-notifications.js +6 -6
  45. package/dist/lib/oauth-success.js +202 -202
  46. package/dist/lib/opencode-v2-rpc.d.ts +4 -0
  47. package/dist/lib/opencode-v2-rpc.d.ts.map +1 -1
  48. package/dist/lib/opencode-v2-rpc.js +1 -0
  49. package/dist/lib/opencode-v2-rpc.js.map +1 -1
  50. package/dist/lib/opencode-v2-status.d.ts +1 -0
  51. package/dist/lib/opencode-v2-status.d.ts.map +1 -1
  52. package/dist/lib/opencode-v2-status.js +8 -1
  53. package/dist/lib/opencode-v2-status.js.map +1 -1
  54. package/dist/lib/opencode-v2-tui.d.ts.map +1 -1
  55. package/dist/lib/opencode-v2-tui.js +8 -1
  56. package/dist/lib/opencode-v2-tui.js.map +1 -1
  57. package/dist/lib/prompts/codex-opencode-bridge.js +67 -67
  58. package/dist/lib/prompts/codex.js +75 -75
  59. package/dist/lib/schemas.d.ts +11 -0
  60. package/dist/lib/schemas.d.ts.map +1 -1
  61. package/dist/lib/schemas.js +4 -0
  62. package/dist/lib/schemas.js.map +1 -1
  63. package/dist/lib/storage/load-save.d.ts.map +1 -1
  64. package/dist/lib/storage/load-save.js +22 -20
  65. package/dist/lib/storage/load-save.js.map +1 -1
  66. package/dist/lib/tui-quota-cache.d.ts +7 -0
  67. package/dist/lib/tui-quota-cache.d.ts.map +1 -1
  68. package/dist/lib/tui-quota-cache.js +2 -1
  69. package/dist/lib/tui-quota-cache.js.map +1 -1
  70. package/dist/lib/tui-quota-overview.d.ts.map +1 -1
  71. package/dist/lib/tui-quota-overview.js +11 -2
  72. package/dist/lib/tui-quota-overview.js.map +1 -1
  73. package/package.json +157 -157
  74. package/scripts/audit-dev-allowlist.js +114 -114
  75. package/scripts/clean-dist.js +27 -27
  76. package/scripts/copy-oauth-success.js +47 -47
  77. package/scripts/install-oc-codex-multi-auth-core.js +2661 -2092
  78. package/scripts/install-oc-codex-multi-auth.js +37 -37
  79. package/scripts/test-all-models.sh +260 -260
  80. package/scripts/validate-model-map.sh +97 -97
@@ -1 +1 @@
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;AA+qJ5G,eAAO,MAAM,gBAAgB,QAAoB,CAAC;;;;IAKjD,6EAA6E;mBACxD,OAAO,kBAAkB,EAAE,MAAM,CAAC,OAAO;;AAJ/D,wBAQE"}
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
@@ -2214,7 +2214,7 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2214
2214
  accountManager = reloaded;
2215
2215
  }
2216
2216
  }
2217
- let accountCount = accountManager.getAccountCount();
2217
+ const accountCount = accountManager.getAccountCount();
2218
2218
  const attempted = new Set();
2219
2219
  // Diagnostics for the terminal error message below. The composite key keeps
2220
2220
  // legacy Business seats distinct and can also be compared with snapshots
@@ -2314,9 +2314,7 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2314
2314
  runtimeMetrics.lastError = err?.message ?? String(err);
2315
2315
  runtimeMetrics.lastErrorCategory = "auth-refresh";
2316
2316
  // Transient refresh failures (network blip / upstream 5xx) must NOT
2317
- // count toward permanent account removal — the credentials are still
2318
- // valid and a flaky network or outage would otherwise silently delete
2319
- // them. Cool the account down briefly and rotate instead.
2317
+ // count toward disabling an account. Cool it down and rotate instead.
2320
2318
  const isTransientRefreshFailure = err instanceof CodexAuthError && err.retryable === true;
2321
2319
  if (isTransientRefreshFailure) {
2322
2320
  const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
@@ -2324,7 +2322,7 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2324
2322
  accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
2325
2323
  }
2326
2324
  accountManager.saveToDiskDebounced();
2327
- logWarn(`[${PLUGIN_NAME}] Transient auth refresh failure for account ${account.index + 1} (${err.refreshFailureReason ?? "unknown"}${err.statusCode ? ` ${err.statusCode}` : ""}); cooling down without counting toward removal.`);
2325
+ logWarn(`[${PLUGIN_NAME}] Transient auth refresh failure for account ${account.index + 1} (${err.refreshFailureReason ?? "unknown"}${err.statusCode ? ` ${err.statusCode}` : ""}); cooling down without disabling.`);
2328
2326
  continue;
2329
2327
  }
2330
2328
  const failures = await accountManager.incrementAuthFailures(account);
@@ -2333,27 +2331,19 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2333
2331
  peerAccounts: accountManager.getAccountsSnapshot(),
2334
2332
  });
2335
2333
  if (failures >= ACCOUNT_LIMITS.MAX_AUTH_FAILURES_BEFORE_REMOVAL) {
2336
- const removedCount = accountManager.removeAccountsWithSameRefreshToken(account);
2337
- if (removedCount <= 0) {
2338
- logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after auth failures, but removed ${removedCount}.`);
2339
- const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
2340
- if (cooledCount <= 0) {
2341
- logWarn(`[${PLUGIN_NAME}] Unable to apply auth-failure cooldown; no live account found for refresh token.`);
2342
- }
2334
+ const disabledCount = accountManager.disableAccountsWithSameRefreshToken(account);
2335
+ if (disabledCount > 0) {
2343
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 });
2344
2340
  continue;
2345
2341
  }
2346
- accountManager.saveToDiskDebounced();
2347
- const removalMessage = removedCount > 1
2348
- ? `Removed ${removedCount} accounts (same refresh token) after ${failures} consecutive auth failures. Run 'opencode auth login' to re-add.`
2349
- : `Removed ${accountLabel} after ${failures} consecutive auth failures. Run 'opencode auth login' to re-add.`;
2350
- await showToast(removalMessage, "error", { duration: toastDurationMs * 2 });
2351
- // Restart traversal: clear attempted and refresh accountCount to avoid skipping healthy accounts
2352
- attempted.clear();
2353
- accountCount = accountManager.getAccountCount();
2354
- continue;
2355
2342
  }
2356
- accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
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
+ }
2357
2347
  accountManager.saveToDiskDebounced();
2358
2348
  continue;
2359
2349
  }
@@ -2616,23 +2606,22 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2616
2606
  catch (flagError) {
2617
2607
  logWarn(`Failed to persist deactivated workspace flag for ${accountLabel}: ${flagError instanceof Error ? flagError.message : String(flagError)}`);
2618
2608
  }
2619
- // Remove ONLY the deactivated workspace, scoped by workspace
2609
+ // Disable ONLY the deactivated workspace, scoped by workspace
2620
2610
  // identity (org/account id). A single multi-org OAuth login
2621
2611
  // produces sibling accounts that share one refresh token but are
2622
- // independently valid; removing all refresh-token siblings here
2612
+ // independently valid; disabling all refresh-token siblings here
2623
2613
  // would silently drop still-valid workspaces from rotation. The
2624
2614
  // refresh token itself is still good, so siblings must survive.
2625
- const removedCount = accountManager.removeAccountsByWorkspaceIdentity(account);
2626
- if (removedCount > 0) {
2615
+ const disabledCount = accountManager.disableAccountsByWorkspaceIdentity(account);
2616
+ if (disabledCount > 0) {
2627
2617
  accountManager.saveToDiskDebounced();
2628
2618
  restartAccountTraversalAfterWorkspaceDeactivation = true;
2629
- const removalMessage = removedCount > 1
2630
- ? `Workspace deactivated. Removed ${removedCount} related entries from rotation and switching accounts.`
2631
- : `Workspace deactivated. Removed ${accountLabel} from rotation and switching accounts.`;
2619
+ const removalMessage = disabledCount > 1
2620
+ ? `Workspace deactivated. Disabled ${disabledCount} related entries; credentials retained.`
2621
+ : `Workspace deactivated. Disabled ${accountLabel}; credentials retained.`;
2632
2622
  await showToast(removalMessage, "warning", { duration: toastDurationMs });
2633
2623
  break;
2634
2624
  }
2635
- logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after workspace deactivation, but removed ${removedCount}.`);
2636
2625
  accountManager.markAccountCoolingDown(account, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");
2637
2626
  accountManager.saveToDiskDebounced();
2638
2627
  break;
@@ -2793,7 +2782,7 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2793
2782
  // explicit handler the 401 fell straight through to `return errorResponse`
2794
2783
  // below, so persisted family routing kept pinning every request to the dead
2795
2784
  // account slot instead of failing over (issue #171). Treat it as an
2796
- // account-health failure: cool the refresh-token group down (or remove it
2785
+ // account-health failure: cool the refresh-token group down (or disable it
2797
2786
  // past the failure threshold) and rotate to the next healthy account.
2798
2787
  //
2799
2788
  // Note: 401s intentionally do NOT feed the circuit breaker — the breaker
@@ -2813,21 +2802,16 @@ async function createPluginRuntime({ client, directory = process.cwd() }) {
2813
2802
  runtimeMetrics.lastErrorCategory = "auth-invalidated";
2814
2803
  const failures = await accountManager.incrementAuthFailures(account);
2815
2804
  if (failures >= ACCOUNT_LIMITS.MAX_AUTH_FAILURES_BEFORE_REMOVAL) {
2816
- const removedCount = accountManager.removeAccountsWithSameRefreshToken(account);
2817
- if (removedCount > 0) {
2805
+ const disabledCount = accountManager.disableAccountsWithSameRefreshToken(account);
2806
+ if (disabledCount > 0) {
2818
2807
  accountManager.saveToDiskDebounced();
2819
- await showToast(removedCount > 1
2820
- ? `Removed ${removedCount} accounts (same refresh token) after ${failures} auth-token failures. Run 'opencode auth login' to re-add.`
2821
- : `Removed ${accountLabel} after ${failures} auth-token failures. Run 'opencode auth login' to re-add.`, "error", { duration: toastDurationMs * 2 });
2822
- // Indices shift after removal; restart traversal with a fresh
2823
- // attempted set so no healthy account is skipped.
2824
- attempted.clear();
2825
- 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 });
2826
2811
  break;
2827
2812
  }
2828
- logWarn(`[${PLUGIN_NAME}] Expected grouped account removal after auth-token invalidation, but removed ${removedCount}.`);
2829
2813
  }
2830
- // Below the removal threshold (or grouped removal was a no-op): cool the
2814
+ // Below the disable threshold (or the group was already disabled): cool the
2831
2815
  // account's whole refresh-token group down so selection skips it, then
2832
2816
  // rotate to the next healthy account instead of returning the 401.
2833
2817
  const cooledCount = accountManager.markAccountsWithRefreshTokenCoolingDown(account.refreshToken, ACCOUNT_LIMITS.AUTH_FAILURE_COOLDOWN_MS, "auth-failure");