opencode-multi-account-core 0.2.11 → 0.2.13

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/dist/index.d.ts CHANGED
@@ -200,6 +200,9 @@ interface DiskCredentials {
200
200
  accountId?: string;
201
201
  }
202
202
  declare class AccountStore {
203
+ private readonly storagePath;
204
+ constructor(filename?: string);
205
+ private withLock;
203
206
  load(): Promise<AccountStorage>;
204
207
  readCredentials(uuid: string): Promise<DiskCredentials | null>;
205
208
  mutateAccount(uuid: string, fn: (account: StoredAccount) => void): Promise<StoredAccount | null>;
@@ -273,7 +276,16 @@ declare function resetConfigCache(): void;
273
276
  declare function setConfigGetter(getter: () => PluginConfig): void;
274
277
  declare function updateConfigField<K extends keyof PluginConfig>(key: K, value: PluginConfig[K]): Promise<void>;
275
278
 
279
+ /**
280
+ * @deprecated Use `new AccountStore(filename)` instead.
281
+ * This global is kept only for backward-compatible test helpers.
282
+ * When two plugins share the same core module instance, mutating
283
+ * this global causes one plugin to read the other's account file.
284
+ */
276
285
  declare let ACCOUNTS_FILENAME: string;
286
+ /**
287
+ * @deprecated Use `new AccountStore(filename)` instead.
288
+ */
277
289
  declare function setAccountsFilename(filename: string): void;
278
290
 
279
291
  interface ExecutorAccountManager {
@@ -352,7 +364,7 @@ declare function createRateLimitHandlers(dependencies: RateLimitDependencies): {
352
364
 
353
365
  declare function readStorageFromDisk(targetPath: string, backupOnCorrupt: boolean): Promise<AccountStorage | null>;
354
366
  declare function deduplicateAccounts(accounts: StoredAccount[]): StoredAccount[];
355
- declare function loadAccounts(): Promise<AccountStorage | null>;
367
+ declare function loadAccounts(storagePath?: string): Promise<AccountStorage | null>;
356
368
 
357
369
  declare function getConfigDir(): string;
358
370
  declare function getErrorCode(error: unknown): string | undefined;
package/dist/index.js CHANGED
@@ -951,7 +951,7 @@ function setAccountsFilename(filename) {
951
951
  }
952
952
 
953
953
  // src/storage.ts
954
- function getStoragePath() {
954
+ function getDefaultStoragePath() {
955
955
  return join4(getConfigDir2(), ACCOUNTS_FILENAME);
956
956
  }
957
957
  async function backupCorruptFile(targetPath, content) {
@@ -1014,9 +1014,9 @@ function deduplicateAccounts(accounts) {
1014
1014
  }
1015
1015
  return deduplicated;
1016
1016
  }
1017
- async function loadAccounts() {
1018
- const storagePath = getStoragePath();
1019
- const storage = await readStorageFromDisk(storagePath, true);
1017
+ async function loadAccounts(storagePath) {
1018
+ const effectivePath = storagePath ?? getDefaultStoragePath();
1019
+ const storage = await readStorageFromDisk(effectivePath, true);
1020
1020
  if (!storage) {
1021
1021
  return null;
1022
1022
  }
@@ -1076,8 +1076,8 @@ async function withDirectoryLock(targetPath, fn, options) {
1076
1076
 
1077
1077
  // src/account-store.ts
1078
1078
  var FILE_MODE = 384;
1079
- function getStoragePath2() {
1080
- return join5(getConfigDir2(), ACCOUNTS_FILENAME);
1079
+ function resolveStoragePath(filename) {
1080
+ return join5(getConfigDir2(), filename);
1081
1081
  }
1082
1082
  function createEmptyStorage() {
1083
1083
  return { version: 1, accounts: [] };
@@ -1119,19 +1119,21 @@ async function ensureStorageFileExists(targetPath) {
1119
1119
  if (getErrorCode(error) !== "EEXIST") throw error;
1120
1120
  }
1121
1121
  }
1122
- async function withFileLock(fn) {
1123
- const storagePath = getStoragePath2();
1124
- await ensureStorageFileExists(storagePath);
1125
- return await withDirectoryLock(storagePath, () => fn(storagePath));
1126
- }
1127
1122
  var AccountStore = class {
1123
+ storagePath;
1124
+ constructor(filename) {
1125
+ this.storagePath = resolveStoragePath(filename ?? ACCOUNTS_FILENAME);
1126
+ }
1127
+ async withLock(fn) {
1128
+ await ensureStorageFileExists(this.storagePath);
1129
+ return await withDirectoryLock(this.storagePath, () => fn(this.storagePath));
1130
+ }
1128
1131
  async load() {
1129
- const storage = await loadAccounts();
1132
+ const storage = await loadAccounts(this.storagePath);
1130
1133
  return storage ?? createEmptyStorage();
1131
1134
  }
1132
1135
  async readCredentials(uuid) {
1133
- const storagePath = getStoragePath2();
1134
- const storage = await readStorageFromDisk(storagePath, false);
1136
+ const storage = await readStorageFromDisk(this.storagePath, false);
1135
1137
  if (!storage) return null;
1136
1138
  const account = storage.accounts.find((a) => a.uuid === uuid);
1137
1139
  if (!account) return null;
@@ -1143,7 +1145,7 @@ var AccountStore = class {
1143
1145
  };
1144
1146
  }
1145
1147
  async mutateAccount(uuid, fn) {
1146
- return await withFileLock(async (storagePath) => {
1148
+ return await this.withLock(async (storagePath) => {
1147
1149
  const current = await readStorageFromDisk(storagePath, false);
1148
1150
  if (!current) return null;
1149
1151
  const account = current.accounts.find((a) => a.uuid === uuid);
@@ -1154,14 +1156,14 @@ var AccountStore = class {
1154
1156
  });
1155
1157
  }
1156
1158
  async mutateStorage(fn) {
1157
- await withFileLock(async (storagePath) => {
1159
+ await this.withLock(async (storagePath) => {
1158
1160
  const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();
1159
1161
  fn(current);
1160
1162
  await writeStorageAtomic(storagePath, current);
1161
1163
  });
1162
1164
  }
1163
1165
  async addAccount(account) {
1164
- await withFileLock(async (storagePath) => {
1166
+ await this.withLock(async (storagePath) => {
1165
1167
  const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();
1166
1168
  const exists = current.accounts.some(
1167
1169
  (a) => a.uuid === account.uuid || a.refreshToken === account.refreshToken
@@ -1172,7 +1174,7 @@ var AccountStore = class {
1172
1174
  });
1173
1175
  }
1174
1176
  async removeAccount(uuid) {
1175
- return await withFileLock(async (storagePath) => {
1177
+ return await this.withLock(async (storagePath) => {
1176
1178
  const current = await readStorageFromDisk(storagePath, false);
1177
1179
  if (!current) return false;
1178
1180
  const initialLength = current.accounts.length;
@@ -1191,7 +1193,7 @@ var AccountStore = class {
1191
1193
  });
1192
1194
  }
1193
1195
  async clear() {
1194
- await withFileLock(async (storagePath) => {
1196
+ await this.withLock(async (storagePath) => {
1195
1197
  await writeStorageAtomic(storagePath, createEmptyStorage());
1196
1198
  });
1197
1199
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/account-manager.ts","../src/claims.ts","../src/utils.ts","../src/config.ts","../src/types.ts","../src/account-store.ts","../src/storage.ts","../src/constants.ts","../src/file-lock.ts","../src/executor.ts","../src/proactive-refresh.ts","../src/rate-limit.ts","../src/auth-migration.ts","../src/ui/ansi.ts","../src/ui/select.ts","../src/ui/confirm.ts","../src/adapters/anthropic.ts","../src/adapters/openai.ts","../src/pool-types.ts","../src/pool-config-store.ts","../src/pool-manager.ts","../src/cascade-state.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { readClaims, writeClaim, isClaimedByOther, type ClaimsMap } from \"./claims\";\nimport { getConfig } from \"./config\";\nimport { getClearedOAuthBody } from \"./utils\";\nimport type { AccountStore } from \"./account-store\";\nimport type {\n ManagedAccount,\n OAuthCredentials,\n PluginClient,\n StoredAccount,\n TokenRefreshResult,\n UsageLimits,\n} from \"./types\";\n\nconst STARTUP_REFRESH_CONCURRENCY = 3;\nconst RECENT_429_COOLDOWN_MS = 30_000;\nconst HYBRID_SWITCH_MARGIN = 40;\n\nexport interface ProfileData {\n email?: string;\n planTier: string;\n}\n\nexport interface RuntimeFactoryLike {\n invalidate(uuid: string): void;\n}\n\nexport interface AccountManagerDependencies {\n providerAuthId: string;\n isTokenExpired: (account: Pick<ManagedAccount, \"accessToken\" | \"expiresAt\">) => boolean;\n refreshToken: (\n currentRefreshToken: string,\n accountId: string,\n client: PluginClient,\n ) => Promise<TokenRefreshResult>;\n}\n\nexport interface AccountManagerInstance {\n initialize(currentAuth: OAuthCredentials, client?: PluginClient): Promise<void>;\n refresh(): Promise<void>;\n getAccountCount(): number;\n getAccounts(): ManagedAccount[];\n getActiveAccount(): ManagedAccount | null;\n setClient(client: PluginClient): void;\n setRuntimeFactory(factory: RuntimeFactoryLike): void;\n hasAnyUsableAccount(): boolean;\n isRateLimited(account: ManagedAccount): boolean;\n clearExpiredRateLimits(): void;\n getMinWaitTime(): number;\n selectAccount(): Promise<ManagedAccount | null>;\n markRateLimited(uuid: string, backoffMs?: number): Promise<void>;\n markRevoked(uuid: string): Promise<void>;\n markSuccess(uuid: string): Promise<void>;\n markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void>;\n applyUsageCache(uuid: string, usage: UsageLimits): Promise<void>;\n applyProfileCache(uuid: string, profile: ProfileData): Promise<void>;\n ensureValidToken(uuid: string, client: PluginClient): Promise<TokenRefreshResult>;\n validateNonActiveTokens(client: PluginClient): Promise<void>;\n removeAccount(index: number): Promise<boolean>;\n clearAllAccounts(): Promise<void>;\n addAccount(auth: OAuthCredentials, email?: string): Promise<void>;\n toggleEnabled(uuid: string): Promise<void>;\n replaceAccountCredentials(uuid: string, auth: OAuthCredentials): Promise<void>;\n retryAuth(uuid: string, client: PluginClient): Promise<TokenRefreshResult>;\n}\n\nexport interface AccountManagerClass {\n new (store: AccountStore): AccountManagerInstance;\n create(store: AccountStore, currentAuth: OAuthCredentials, client?: PluginClient): Promise<AccountManagerInstance>;\n}\n\nexport function createAccountManagerForProvider(dependencies: AccountManagerDependencies): AccountManagerClass {\n const {\n providerAuthId,\n isTokenExpired,\n refreshToken,\n } = dependencies;\n\n return class AccountManager {\n private cached: ManagedAccount[] = [];\n private activeAccountUuid?: string;\n private client: PluginClient | null = null;\n private runtimeFactory: RuntimeFactoryLike | null = null;\n private roundRobinCursor = 0;\n private last429Map = new Map<string, number>();\n\n constructor(private store: AccountStore) {}\n\n static async create(\n store: AccountStore,\n currentAuth: OAuthCredentials,\n client?: PluginClient,\n ): Promise<AccountManager> {\n const manager = new AccountManager(store);\n await manager.initialize(currentAuth, client);\n return manager;\n }\n\n async initialize(currentAuth: OAuthCredentials, client?: PluginClient): Promise<void> {\n if (client) this.client = client;\n\n const storage = await this.store.load();\n if (storage.accounts.length > 0) {\n this.cached = storage.accounts.map((account, index) => this.toManagedAccount(account, index));\n this.activeAccountUuid = storage.activeAccountUuid;\n if (!this.getActiveAccount() && this.cached.length > 0) {\n this.activeAccountUuid = this.cached[0]!.uuid;\n }\n return;\n }\n\n if (currentAuth.refresh) {\n const newAccount = this.createNewAccount(currentAuth, Date.now());\n await this.store.addAccount(newAccount);\n await this.store.setActiveUuid(newAccount.uuid);\n this.cached = [this.toManagedAccount(newAccount, 0)];\n this.activeAccountUuid = newAccount.uuid;\n }\n }\n\n async refresh(): Promise<void> {\n const storage = await this.store.load();\n this.cached = storage.accounts.map((account, index) => this.toManagedAccount(account, index));\n if (storage.activeAccountUuid) {\n this.activeAccountUuid = storage.activeAccountUuid;\n }\n }\n\n private toManagedAccount(storedAccount: StoredAccount, index: number): ManagedAccount {\n return {\n index,\n uuid: storedAccount.uuid,\n accountId: storedAccount.accountId,\n label: storedAccount.label,\n email: storedAccount.email,\n planTier: storedAccount.planTier,\n refreshToken: storedAccount.refreshToken,\n accessToken: storedAccount.accessToken,\n expiresAt: storedAccount.expiresAt,\n addedAt: storedAccount.addedAt,\n lastUsed: storedAccount.lastUsed,\n enabled: storedAccount.enabled,\n rateLimitResetAt: storedAccount.rateLimitResetAt,\n cachedUsage: storedAccount.cachedUsage,\n cachedUsageAt: storedAccount.cachedUsageAt,\n consecutiveAuthFailures: storedAccount.consecutiveAuthFailures,\n isAuthDisabled: storedAccount.isAuthDisabled,\n authDisabledReason: storedAccount.authDisabledReason,\n last429At: storedAccount.uuid ? this.last429Map.get(storedAccount.uuid) : undefined,\n };\n }\n\n private createNewAccount(auth: OAuthCredentials, now: number): StoredAccount {\n return {\n uuid: randomUUID(),\n refreshToken: auth.refresh,\n accessToken: auth.access,\n expiresAt: auth.expires,\n addedAt: now,\n lastUsed: now,\n enabled: true,\n planTier: \"\",\n consecutiveAuthFailures: 0,\n isAuthDisabled: false,\n };\n }\n\n getAccountCount(): number {\n return this.getEligibleAccounts().length;\n }\n\n getAccounts(): ManagedAccount[] {\n return [...this.cached];\n }\n\n getActiveAccount(): ManagedAccount | null {\n if (this.activeAccountUuid) {\n return this.cached.find((account) => account.uuid === this.activeAccountUuid) ?? null;\n }\n return this.cached[0] ?? null;\n }\n\n setClient(client: PluginClient): void {\n this.client = client;\n }\n\n setRuntimeFactory(factory: RuntimeFactoryLike): void {\n this.runtimeFactory = factory;\n }\n\n private getEligibleAccounts(): ManagedAccount[] {\n return this.cached.filter((account) => account.uuid && account.enabled && !account.isAuthDisabled);\n }\n\n private exceedsSoftQuota(account: ManagedAccount): boolean {\n const threshold = getConfig().soft_quota_threshold_percent;\n if (threshold >= 100) return false;\n\n const usage = account.cachedUsage;\n if (!usage) return false;\n\n const tiers = [usage.five_hour, usage.seven_day];\n return tiers.some((tier) => tier != null && tier.utilization >= threshold);\n }\n\n hasAnyUsableAccount(): boolean {\n return this.getEligibleAccounts().length > 0;\n }\n\n isRateLimited(account: ManagedAccount): boolean {\n if (account.rateLimitResetAt && Date.now() < account.rateLimitResetAt) {\n return true;\n }\n return this.isUsageExhausted(account);\n }\n\n private isUsageExhausted(account: ManagedAccount): boolean {\n const usage = account.cachedUsage;\n if (!usage) return false;\n\n const now = Date.now();\n const tiers = [usage.five_hour, usage.seven_day];\n return tiers.some((tier) =>\n tier != null\n && tier.utilization >= 100\n && tier.resets_at != null\n && Date.parse(tier.resets_at) > now,\n );\n }\n\n clearExpiredRateLimits(): void {\n const now = Date.now();\n for (const account of this.cached) {\n if (account.rateLimitResetAt && now >= account.rateLimitResetAt) {\n account.rateLimitResetAt = undefined;\n }\n }\n }\n\n getMinWaitTime(): number {\n const eligible = this.getEligibleAccounts();\n const available = eligible.filter((account) => !this.isRateLimited(account));\n if (available.length > 0) return 0;\n\n const now = Date.now();\n const waits: number[] = [];\n\n for (const account of eligible) {\n if (account.rateLimitResetAt) {\n const ms = account.rateLimitResetAt - now;\n if (ms > 0) waits.push(ms);\n }\n\n const usageResetMs = this.getUsageResetMs(account);\n if (usageResetMs !== null && usageResetMs > 0) {\n waits.push(usageResetMs);\n }\n }\n\n return waits.length > 0 ? Math.min(...waits) : 0;\n }\n\n private getUsageResetMs(account: ManagedAccount): number | null {\n const usage = account.cachedUsage;\n if (!usage) return null;\n\n const now = Date.now();\n const candidates: number[] = [];\n const tiers = [usage.five_hour, usage.seven_day];\n\n for (const tier of tiers) {\n if (tier != null && tier.utilization >= 100 && tier.resets_at != null) {\n const ms = Date.parse(tier.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n }\n\n return candidates.length > 0 ? Math.min(...candidates) : null;\n }\n\n async selectAccount(): Promise<ManagedAccount | null> {\n await this.refresh();\n this.clearExpiredRateLimits();\n\n const eligible = this.getEligibleAccounts();\n if (eligible.length === 0) return null;\n\n const config = getConfig();\n const claims = config.cross_process_claims ? await readClaims() : {};\n\n const strategy = config.account_selection_strategy;\n let selected: ManagedAccount | null;\n switch (strategy) {\n case \"round-robin\":\n selected = this.selectRoundRobin(eligible, claims);\n break;\n case \"hybrid\":\n selected = this.selectHybrid(eligible, claims);\n break;\n case \"sticky\":\n default:\n selected = this.selectSticky(eligible, claims);\n break;\n }\n\n if (selected?.uuid) {\n this.activeAccountUuid = selected.uuid;\n this.store.setActiveUuid(selected.uuid).catch(() => {});\n }\n\n if (config.cross_process_claims && selected?.uuid) {\n writeClaim(selected.uuid).catch(() => {});\n }\n\n return selected;\n }\n\n private isUsable(account: ManagedAccount): boolean {\n return !this.isRateLimited(account)\n && !this.isInRecentCooldown(account)\n && !this.exceedsSoftQuota(account);\n }\n\n private isInRecentCooldown(account: ManagedAccount): boolean {\n if (!account.last429At) return false;\n return Date.now() - account.last429At < RECENT_429_COOLDOWN_MS;\n }\n\n private fallbackNotRateLimited(eligible: ManagedAccount[]): ManagedAccount | null {\n const account = eligible.find((candidate) => !this.isRateLimited(candidate));\n if (account) {\n this.activateAccount(account);\n return account;\n }\n return null;\n }\n\n private selectSticky(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n const current = this.getActiveAccount();\n if (current?.enabled && !current.isAuthDisabled && this.isUsable(current)) {\n this.activateAccount(current);\n return current;\n }\n\n const unclaimed = eligible.find(\n (account) => this.isUsable(account) && !isClaimedByOther(claims, account.uuid),\n );\n if (unclaimed) {\n this.activateAccount(unclaimed);\n return unclaimed;\n }\n\n const available = eligible.find((account) => this.isUsable(account));\n if (available) {\n this.activateAccount(available);\n return available;\n }\n\n return this.fallbackNotRateLimited(eligible);\n }\n\n private selectRoundRobin(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n for (let i = 0; i < eligible.length; i++) {\n const index = (this.roundRobinCursor + i) % eligible.length;\n const account = eligible[index]!;\n if (this.isUsable(account) && !isClaimedByOther(claims, account.uuid)) {\n this.roundRobinCursor = (index + 1) % eligible.length;\n this.activateAccount(account);\n return account;\n }\n }\n\n for (let i = 0; i < eligible.length; i++) {\n const index = (this.roundRobinCursor + i) % eligible.length;\n const account = eligible[index]!;\n if (this.isUsable(account)) {\n this.roundRobinCursor = (index + 1) % eligible.length;\n this.activateAccount(account);\n return account;\n }\n }\n\n return this.fallbackNotRateLimited(eligible);\n }\n\n private selectHybrid(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n const usable = eligible.filter((account) => this.isUsable(account));\n const pool = usable.length > 0\n ? usable\n : eligible.filter((account) => !this.isRateLimited(account));\n\n if (pool.length === 0) return null;\n\n const activeUuid = this.activeAccountUuid;\n\n let best = pool[0]!;\n let bestScore = this.calculateHybridScore(best, best.uuid === activeUuid, claims);\n\n for (let i = 1; i < pool.length; i++) {\n const account = pool[i]!;\n const score = this.calculateHybridScore(account, account.uuid === activeUuid, claims);\n if (score > bestScore) {\n best = account;\n bestScore = score;\n }\n }\n\n const current = pool.find((account) => account.uuid === activeUuid);\n if (current && current !== best) {\n const currentScore = this.calculateHybridScore(current, true, claims);\n const bestWithoutStickiness = this.calculateHybridScore(best, false, claims);\n if (bestWithoutStickiness <= currentScore + HYBRID_SWITCH_MARGIN) {\n this.activateAccount(current);\n return current;\n }\n }\n\n this.activateAccount(best);\n return best;\n }\n\n private calculateHybridScore(account: ManagedAccount, isActive: boolean, claims: ClaimsMap): number {\n const maxUtilization = Math.min(100, Math.max(0, this.getMaxUtilization(account)));\n const usageScore = ((100 - maxUtilization) / 100) * 450;\n\n const maxFailures = Math.max(1, getConfig().max_consecutive_auth_failures);\n const healthScore = Math.max(0, ((maxFailures - account.consecutiveAuthFailures) / maxFailures) * 250);\n\n const secondsSinceUsed = (Date.now() - account.lastUsed) / 1000;\n const freshnessScore = (Math.min(secondsSinceUsed, 900) / 900) * 60;\n\n const stickinessBonus = isActive ? 120 : 0;\n const claimPenalty = isClaimedByOther(claims, account.uuid) ? -200 : 0;\n\n return usageScore + healthScore + freshnessScore + stickinessBonus + claimPenalty;\n }\n\n private getMaxUtilization(account: ManagedAccount): number {\n const usage = account.cachedUsage;\n if (!usage) return 65;\n\n const tiers = [usage.five_hour, usage.seven_day];\n const utilizations = tiers\n .filter((tier): tier is NonNullable<typeof tier> => tier != null)\n .map((tier) => tier.utilization);\n\n return utilizations.length > 0 ? Math.max(...utilizations) : 65;\n }\n\n private activateAccount(account: ManagedAccount): void {\n this.activeAccountUuid = account.uuid;\n account.lastUsed = Date.now();\n }\n\n async markRateLimited(uuid: string, backoffMs?: number): Promise<void> {\n const effectiveBackoff = backoffMs ?? getConfig().rate_limit_min_backoff_ms;\n this.last429Map.set(uuid, Date.now());\n await this.store.mutateAccount(uuid, (account) => {\n account.rateLimitResetAt = Date.now() + effectiveBackoff;\n });\n }\n\n async markRevoked(uuid: string): Promise<void> {\n await this.removeAccountByUuid(uuid);\n }\n\n async markSuccess(uuid: string): Promise<void> {\n this.last429Map.delete(uuid);\n await this.store.mutateAccount(uuid, (account) => {\n account.rateLimitResetAt = undefined;\n account.consecutiveAuthFailures = 0;\n account.lastUsed = Date.now();\n });\n }\n\n private syncToOpenCode(account: Pick<StoredAccount, \"refreshToken\" | \"accessToken\" | \"expiresAt\">): void {\n if (!this.client || !account.accessToken || !account.expiresAt) return;\n this.client.auth.set({\n path: { id: providerAuthId },\n body: {\n type: \"oauth\",\n refresh: account.refreshToken,\n access: account.accessToken,\n expires: account.expiresAt,\n },\n }).catch(() => {});\n }\n\n private async clearOpenCodeAuthIfNoAccountsRemain(): Promise<void> {\n if (!this.client) return;\n\n const storage = await this.store.load();\n if (storage.accounts.length > 0) return;\n\n await this.client.auth\n .set({\n path: { id: providerAuthId },\n body: getClearedOAuthBody(),\n })\n .catch(() => {});\n }\n\n private async removeAccountByUuid(uuid: string): Promise<void> {\n const removed = await this.store.removeAccount(uuid);\n if (!removed) return;\n\n this.last429Map.delete(uuid);\n this.runtimeFactory?.invalidate(uuid);\n await this.refresh();\n await this.clearOpenCodeAuthIfNoAccountsRemain();\n }\n\n async markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void> {\n if (!result.ok && result.permanent) {\n await this.removeAccountByUuid(uuid);\n return;\n }\n\n await this.store.mutateStorage((storage) => {\n const account = storage.accounts.find((entry) => entry.uuid === uuid);\n if (!account) return;\n\n account.consecutiveAuthFailures = (account.consecutiveAuthFailures ?? 0) + 1;\n const maxFailures = getConfig().max_consecutive_auth_failures;\n const usableCount = storage.accounts.filter(\n (entry) => entry.enabled && !entry.isAuthDisabled && entry.uuid !== uuid,\n ).length;\n\n if (account.consecutiveAuthFailures >= maxFailures && usableCount > 0) {\n account.isAuthDisabled = true;\n account.authDisabledReason = `${maxFailures} consecutive auth failures`;\n }\n });\n }\n\n async applyUsageCache(uuid: string, usage: UsageLimits): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n const now = Date.now();\n const exhaustedTierResetTimes = [usage.five_hour, usage.seven_day]\n .flatMap((tier) => {\n if (tier == null || tier.utilization < 100 || tier.resets_at == null) {\n return [];\n }\n return [Date.parse(tier.resets_at)];\n })\n .filter((resetAt) => Number.isFinite(resetAt) && resetAt > now);\n\n account.cachedUsage = usage;\n account.cachedUsageAt = Date.now();\n account.rateLimitResetAt = exhaustedTierResetTimes.length > 0\n ? Math.min(...exhaustedTierResetTimes)\n : undefined;\n });\n }\n\n async applyProfileCache(uuid: string, profile: ProfileData): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n account.email = profile.email ?? account.email;\n account.planTier = profile.planTier;\n });\n }\n\n async ensureValidToken(uuid: string, client: PluginClient): Promise<TokenRefreshResult> {\n const credentials = await this.store.readCredentials(uuid);\n if (!credentials) return { ok: false, permanent: true };\n\n if (credentials.accessToken && credentials.expiresAt && !isTokenExpired(credentials)) {\n return {\n ok: true,\n patch: { accessToken: credentials.accessToken, expiresAt: credentials.expiresAt },\n };\n }\n\n const result = await refreshToken(credentials.refreshToken, uuid, client);\n if (!result.ok) return result;\n\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.accessToken = result.patch.accessToken;\n account.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) account.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid && result.patch.uuid !== uuid) account.uuid = result.patch.uuid;\n if (result.patch.accountId) account.accountId = result.patch.accountId;\n if (result.patch.email) account.email = result.patch.email;\n account.consecutiveAuthFailures = 0;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n });\n\n if (result.patch.uuid && result.patch.uuid !== uuid && this.activeAccountUuid === uuid) {\n this.activeAccountUuid = result.patch.uuid;\n this.store.setActiveUuid(result.patch.uuid).catch(() => {});\n }\n\n if (updated && (uuid === this.activeAccountUuid || updated.uuid === this.activeAccountUuid)) {\n this.syncToOpenCode(updated);\n }\n\n return result;\n }\n\n async validateNonActiveTokens(client: PluginClient): Promise<void> {\n await this.refresh();\n\n const activeUuid = this.activeAccountUuid;\n const eligible = this.cached.filter(\n (account) => account.enabled && !account.isAuthDisabled && account.uuid && account.uuid !== activeUuid,\n );\n\n for (let i = 0; i < eligible.length; i += STARTUP_REFRESH_CONCURRENCY) {\n const batch = eligible.slice(i, i + STARTUP_REFRESH_CONCURRENCY);\n await Promise.all(\n batch.map(async (account) => {\n if (!account.uuid || !isTokenExpired(account)) return;\n\n const result = await this.ensureValidToken(account.uuid, client);\n if (!result.ok) {\n await this.markAuthFailure(account.uuid, result);\n }\n }),\n );\n }\n }\n\n async removeAccount(index: number): Promise<boolean> {\n const account = this.cached[index];\n if (!account?.uuid) return false;\n\n const removed = await this.store.removeAccount(account.uuid);\n if (removed) {\n await this.refresh();\n }\n return removed;\n }\n\n async clearAllAccounts(): Promise<void> {\n await this.store.clear();\n this.cached = [];\n this.activeAccountUuid = undefined;\n }\n\n async addAccount(auth: OAuthCredentials, email?: string): Promise<void> {\n if (!auth.refresh) return;\n\n const existingByToken = this.cached.find((account) => account.refreshToken === auth.refresh);\n if (existingByToken) return;\n\n if (email) {\n const existingByEmail = this.cached.find(\n (account) => account.email && account.email === email,\n );\n if (existingByEmail?.uuid) {\n await this.replaceAccountCredentials(existingByEmail.uuid, auth);\n return;\n }\n }\n\n const newAccount = this.createNewAccount(auth, Date.now());\n if (email) newAccount.email = email;\n await this.store.addAccount(newAccount);\n this.activeAccountUuid = newAccount.uuid;\n await this.store.setActiveUuid(newAccount.uuid);\n await this.refresh();\n }\n\n async toggleEnabled(uuid: string): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n account.enabled = !(account.enabled ?? true);\n if (account.enabled) {\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n account.consecutiveAuthFailures = 0;\n }\n });\n }\n\n async replaceAccountCredentials(uuid: string, auth: OAuthCredentials): Promise<void> {\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.refreshToken = auth.refresh;\n account.accessToken = auth.access;\n account.expiresAt = auth.expires;\n account.lastUsed = Date.now();\n account.enabled = true;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n account.consecutiveAuthFailures = 0;\n account.rateLimitResetAt = undefined;\n });\n this.runtimeFactory?.invalidate(uuid);\n\n if (updated && uuid === this.activeAccountUuid) {\n this.syncToOpenCode(updated);\n }\n }\n\n async retryAuth(uuid: string, client: PluginClient): Promise<TokenRefreshResult> {\n await this.store.mutateAccount(uuid, (account) => {\n account.consecutiveAuthFailures = 0;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n });\n this.runtimeFactory?.invalidate(uuid);\n\n const credentials = await this.store.readCredentials(uuid);\n if (!credentials) return { ok: false, permanent: true };\n\n const result = await refreshToken(credentials.refreshToken, uuid, client);\n if (result.ok) {\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.accessToken = result.patch.accessToken;\n account.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) account.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid) account.uuid = result.patch.uuid;\n if (result.patch.accountId) account.accountId = result.patch.accountId;\n if (result.patch.email) account.email = result.patch.email;\n account.enabled = true;\n account.consecutiveAuthFailures = 0;\n });\n this.runtimeFactory?.invalidate(uuid);\n if (result.patch.uuid) {\n this.runtimeFactory?.invalidate(result.patch.uuid);\n }\n\n const nextUuid = result.patch.uuid ?? uuid;\n if (this.activeAccountUuid === uuid && result.patch.uuid && result.patch.uuid !== uuid) {\n this.activeAccountUuid = result.patch.uuid;\n await this.store.setActiveUuid(result.patch.uuid);\n }\n\n if (updated && (uuid === this.activeAccountUuid || nextUuid === this.activeAccountUuid)) {\n const freshCredentials = await this.store.readCredentials(nextUuid);\n if (freshCredentials) {\n this.syncToOpenCode({\n refreshToken: freshCredentials.refreshToken,\n accessToken: freshCredentials.accessToken,\n expiresAt: freshCredentials.expiresAt,\n });\n }\n }\n } else {\n await this.markAuthFailure(uuid, result);\n this.runtimeFactory?.invalidate(uuid);\n }\n\n return result;\n }\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { getConfigDir } from \"./utils\";\n\nconst CLAIMS_FILENAME = \"multiauth-claims.json\";\nconst CLAIM_EXPIRY_MS = 60_000;\n\nexport type ClaimsMap = Record<string, { pid: number; at: number }>;\n\nfunction getClaimsPath(): string {\n return join(getConfigDir(), CLAIMS_FILENAME);\n}\n\nfunction isClaimShape(value: unknown): value is { pid: number; at: number } {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const claim = value as Record<string, unknown>;\n return (\n typeof claim.pid === \"number\"\n && Number.isInteger(claim.pid)\n && claim.pid > 0\n && typeof claim.at === \"number\"\n && Number.isFinite(claim.at)\n );\n}\n\nfunction parseClaims(raw: string): ClaimsMap {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n\n const claims: ClaimsMap = {};\n for (const [accountId, claim] of Object.entries(parsed)) {\n if (isClaimShape(claim)) {\n claims[accountId] = claim;\n }\n }\n\n return claims;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction cleanClaims(\n claims: ClaimsMap,\n now: number,\n): { cleaned: ClaimsMap; changed: boolean } {\n const cleaned: ClaimsMap = {};\n let changed = false;\n\n for (const [accountId, claim] of Object.entries(claims)) {\n const expiredByTime = now - claim.at > CLAIM_EXPIRY_MS;\n const zombieClaim = !isProcessAlive(claim.pid);\n if (expiredByTime || zombieClaim) {\n changed = true;\n continue;\n }\n\n cleaned[accountId] = claim;\n }\n\n return { cleaned, changed };\n}\n\nasync function writeClaimsFile(claims: ClaimsMap): Promise<void> {\n const path = getClaimsPath();\n const tempPath = `${path}.${randomBytes(6).toString(\"hex\")}.tmp`;\n await fs.mkdir(dirname(path), { recursive: true });\n\n try {\n await fs.writeFile(tempPath, JSON.stringify(claims, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n await fs.rename(tempPath, path);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {\n // ignore cleanup failure\n }\n throw error;\n }\n}\n\nexport async function readClaims(): Promise<ClaimsMap> {\n try {\n const data = await fs.readFile(getClaimsPath(), \"utf-8\");\n const parsed = parseClaims(data);\n const now = Date.now();\n const { cleaned, changed } = cleanClaims(parsed, now);\n\n if (changed) {\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort cleanup\n }\n }\n\n return cleaned;\n } catch {\n return {};\n }\n}\n\n// Best-effort read-modify-write: not atomic across processes, but acceptable\n// because stale/duplicate claims self-expire via CLAIM_EXPIRY_MS and zombie detection.\nexport async function writeClaim(accountId: string): Promise<void> {\n const now = Date.now();\n const claims = await readClaims();\n const { cleaned } = cleanClaims(claims, now);\n\n cleaned[accountId] = { pid: process.pid, at: now };\n\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort claim update\n }\n}\n\n// Best-effort read-modify-write: same rationale as writeClaim above.\nexport async function releaseClaim(accountId: string): Promise<void> {\n const now = Date.now();\n const claims = await readClaims();\n const { cleaned } = cleanClaims(claims, now);\n\n const currentClaim = cleaned[accountId];\n if (!currentClaim || currentClaim.pid !== process.pid) {\n return;\n }\n\n delete cleaned[accountId];\n\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort release\n }\n}\n\nexport function isClaimedByOther(\n claims: ClaimsMap,\n accountId: string | undefined,\n): boolean {\n if (!accountId) return false;\n const claim = claims[accountId];\n if (!claim) return false;\n if (Date.now() - claim.at > CLAIM_EXPIRY_MS) return false;\n if (!isProcessAlive(claim.pid)) return false;\n return claim.pid !== process.pid;\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { getConfig } from \"./config\";\nimport type { ManagedAccount, PluginClient } from \"./types\";\n\n// ─── Shared Filesystem Utilities ─────────────────────────────────\n\nexport function getConfigDir(): string {\n return process.env.OPENCODE_CONFIG_DIR\n || join(process.env.XDG_CONFIG_HOME || join(homedir(), \".config\"), \"opencode\");\n}\n\nexport function getErrorCode(error: unknown): string | undefined {\n if (typeof error !== \"object\" || error === null || !(\"code\" in error)) {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\n// ─── Formatting & Display ────────────────────────────────────────\n\nexport function formatWaitTime(ms: number): string {\n const totalSeconds = Math.ceil(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n\n const days = Math.floor(totalSeconds / 86_400);\n const hours = Math.floor((totalSeconds % 86_400) / 3_600);\n const minutes = Math.floor((totalSeconds % 3_600) / 60);\n const seconds = totalSeconds % 60;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0 && days === 0) parts.push(`${seconds}s`);\n\n return parts.join(\" \") || \"0s\";\n}\n\nexport function getAccountLabel(account: ManagedAccount): string {\n if (account.label) return account.label;\n if (account.email) return account.email;\n if (account.uuid) return `Account (${account.uuid.slice(0, 8)})`;\n return `Account ${account.index + 1}`;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function showToast(\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n): Promise<void> {\n if (getConfig().quiet_mode) return;\n try {\n await client.tui.showToast({ body: { message, variant } });\n } catch {\n // TUI may not be available\n }\n}\n\nexport function debugLog(\n client: PluginClient,\n message: string,\n extra?: Record<string, unknown>,\n): void {\n if (!getConfig().debug) return;\n client.app.log({\n body: { service: \"claude-multiauth\", level: \"debug\", message, extra },\n }).catch(() => {});\n}\n\nexport function createMinimalClient(): PluginClient {\n return {\n auth: {\n set: async () => {},\n },\n tui: {\n showToast: async () => {},\n },\n app: {\n log: async () => {},\n },\n };\n}\n\n// ─── OAuth Helpers ───────────────────────────────────────────────\n\nexport function getClearedOAuthBody() {\n return {\n type: \"oauth\" as const,\n refresh: \"\",\n access: \"\",\n expires: 0,\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as v from \"valibot\";\nimport { PluginConfigSchema } from \"./types\";\nimport type { PluginConfig } from \"./types\";\n\nexport type CoreConfig = Pick<PluginConfig, \"quiet_mode\" | \"debug\">;\n\nconst DEFAULT_CONFIG_FILENAME = \"multiauth-config.json\";\nconst DEFAULT_CONFIG: PluginConfig = v.parse(PluginConfigSchema, {});\n\nlet configFilename = DEFAULT_CONFIG_FILENAME;\nlet cachedConfig: PluginConfig | null = null;\nlet externalConfigGetter: (() => PluginConfig) | null = null;\n\nfunction getConfigDir(): string {\n return process.env.OPENCODE_CONFIG_DIR\n || join(process.env.XDG_CONFIG_HOME || join(homedir(), \".config\"), \"opencode\");\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), configFilename);\n}\n\nfunction parseConfig(raw: unknown): PluginConfig {\n const result = v.safeParse(PluginConfigSchema, raw);\n return result.success ? result.output : DEFAULT_CONFIG;\n}\n\nexport function initCoreConfig(filename: string): void {\n configFilename = filename || DEFAULT_CONFIG_FILENAME;\n cachedConfig = null;\n}\n\nexport async function loadConfig(): Promise<PluginConfig> {\n if (cachedConfig) return cachedConfig;\n\n const path = getConfigPath();\n try {\n const content = await fs.readFile(path, \"utf-8\");\n cachedConfig = parseConfig(JSON.parse(content));\n } catch {\n cachedConfig = DEFAULT_CONFIG;\n }\n\n return cachedConfig;\n}\n\nexport function getConfig(): PluginConfig {\n if (cachedConfig) return cachedConfig;\n\n if (externalConfigGetter && externalConfigGetter !== getConfig) {\n try {\n return parseConfig(externalConfigGetter());\n } catch {\n return DEFAULT_CONFIG;\n }\n }\n\n return DEFAULT_CONFIG;\n}\n\nexport function resetConfigCache(): void {\n cachedConfig = null;\n}\n\nexport function setConfigGetter(getter: () => PluginConfig): void {\n if (getter === getConfig) {\n return;\n }\n externalConfigGetter = getter;\n}\n\nexport async function updateConfigField<K extends keyof PluginConfig>(\n key: K,\n value: PluginConfig[K],\n): Promise<void> {\n const path = getConfigPath();\n\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(path, \"utf-8\");\n existing = JSON.parse(content) as Record<string, unknown>;\n } catch {}\n\n existing[key] = value;\n\n await fs.mkdir(dirname(path), { recursive: true });\n const content = `${JSON.stringify(existing, null, 2)}\\n`;\n const tempPath = `${path}.${randomBytes(8).toString(\"hex\")}.tmp`;\n try {\n await fs.writeFile(tempPath, content, \"utf-8\");\n await fs.rename(tempPath, path);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n\n cachedConfig = null;\n await loadConfig();\n}\n","import * as v from \"valibot\";\n\nexport const OAuthCredentialsSchema = v.object({\n type: v.literal(\"oauth\"),\n refresh: v.string(),\n access: v.string(),\n expires: v.number(),\n});\n\nexport const UsageLimitEntrySchema = v.object({\n utilization: v.number(),\n resets_at: v.nullable(v.string()),\n});\n\nexport const UsageLimitsSchema = v.object({\n five_hour: v.optional(v.nullable(UsageLimitEntrySchema), null),\n seven_day: v.optional(v.nullable(UsageLimitEntrySchema), null),\n seven_day_sonnet: v.optional(v.nullable(UsageLimitEntrySchema), null),\n});\n\nexport const CredentialRefreshPatchSchema = v.object({\n accessToken: v.string(),\n expiresAt: v.number(),\n refreshToken: v.optional(v.string()),\n uuid: v.optional(v.string()),\n accountId: v.optional(v.string()),\n email: v.optional(v.string()),\n});\n\nexport const StoredAccountSchema = v.object({\n uuid: v.optional(v.string()),\n accountId: v.optional(v.string()),\n label: v.optional(v.string()),\n email: v.optional(v.string()),\n planTier: v.optional(v.string(), \"\"),\n refreshToken: v.string(),\n accessToken: v.optional(v.string()),\n expiresAt: v.optional(v.number()),\n addedAt: v.number(),\n lastUsed: v.number(),\n enabled: v.optional(v.boolean(), true),\n rateLimitResetAt: v.optional(v.number()),\n cachedUsage: v.optional(UsageLimitsSchema),\n cachedUsageAt: v.optional(v.number()),\n consecutiveAuthFailures: v.optional(v.number(), 0),\n isAuthDisabled: v.optional(v.boolean(), false),\n authDisabledReason: v.optional(v.string()),\n});\n\nexport const AccountStorageSchema = v.object({\n version: v.literal(1),\n accounts: v.optional(v.array(StoredAccountSchema), []),\n activeAccountUuid: v.optional(v.string()),\n});\n\nexport const AccountSelectionStrategySchema = v.picklist([\"sticky\", \"round-robin\", \"hybrid\"]);\n\nexport const PluginConfigSchema = v.object({\n account_selection_strategy: v.optional(AccountSelectionStrategySchema, \"sticky\"),\n cross_process_claims: v.optional(v.boolean(), true),\n soft_quota_threshold_percent: v.optional(v.pipe(v.number(), v.minValue(0), v.maxValue(100)), 100),\n rate_limit_min_backoff_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 30_000),\n default_retry_after_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 60_000),\n max_consecutive_auth_failures: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1)), 3),\n token_failure_backoff_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 30_000),\n proactive_refresh: v.optional(v.boolean(), true),\n proactive_refresh_buffer_seconds: v.optional(v.pipe(v.number(), v.minValue(60)), 1800),\n proactive_refresh_interval_seconds: v.optional(v.pipe(v.number(), v.minValue(30)), 300),\n quiet_mode: v.optional(v.boolean(), false),\n debug: v.optional(v.boolean(), false),\n});\n\nexport type OAuthCredentials = v.InferOutput<typeof OAuthCredentialsSchema>;\nexport type UsageLimitEntry = v.InferOutput<typeof UsageLimitEntrySchema>;\nexport type UsageLimits = v.InferOutput<typeof UsageLimitsSchema>;\nexport type CredentialRefreshPatch = v.InferOutput<typeof CredentialRefreshPatchSchema>;\nexport type StoredAccount = v.InferOutput<typeof StoredAccountSchema>;\nexport type AccountStorage = v.InferOutput<typeof AccountStorageSchema>;\nexport type AccountSelectionStrategy = v.InferOutput<typeof AccountSelectionStrategySchema>;\nexport type PluginConfig = v.InferOutput<typeof PluginConfigSchema>;\n\nexport type TokenRefreshResult =\n | { ok: true; patch: CredentialRefreshPatch }\n | { ok: false; permanent: boolean; status?: number };\n\nexport class TokenRefreshError extends Error {\n readonly status?: number;\n readonly permanent: boolean;\n\n constructor(permanent: boolean, status?: number) {\n super(status === undefined ? \"Token refresh failed\" : `Token refresh failed: ${status}`);\n this.name = \"TokenRefreshError\";\n this.status = status;\n this.permanent = permanent;\n Object.setPrototypeOf(this, TokenRefreshError.prototype);\n }\n}\n\nexport function isTokenRefreshError(error: unknown): error is TokenRefreshError {\n if (error instanceof TokenRefreshError) return true;\n if (!(error instanceof Error)) return false;\n\n const candidate = error as Error & Partial<TokenRefreshError>;\n return (\n candidate.name === \"TokenRefreshError\"\n && typeof candidate.permanent === \"boolean\"\n && (candidate.status === undefined || typeof candidate.status === \"number\")\n );\n}\n\nexport interface ManagedAccount {\n index: number;\n uuid?: string;\n accountId?: string;\n label?: string;\n email?: string;\n planTier?: string;\n refreshToken: string;\n accessToken?: string;\n expiresAt?: number;\n addedAt: number;\n lastUsed: number;\n enabled: boolean;\n rateLimitResetAt?: number;\n last429At?: number;\n cachedUsage?: UsageLimits;\n cachedUsageAt?: number;\n consecutiveAuthFailures: number;\n isAuthDisabled: boolean;\n authDisabledReason?: string;\n}\n\nexport interface PluginClient {\n auth: {\n set: (params: {\n path: { id: string };\n body: {\n type: string;\n refresh: string;\n access: string;\n expires: number;\n };\n }) => Promise<void>;\n };\n tui: {\n showToast: (params: {\n body: {\n title?: string;\n message: string;\n variant: \"info\" | \"warning\" | \"success\" | \"error\";\n };\n }) => Promise<void>;\n };\n app: {\n log: (params: {\n body: {\n service: string;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n message: string;\n extra?: Record<string, unknown>;\n };\n }) => Promise<void>;\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { loadAccounts, readStorageFromDisk } from \"./storage\";\nimport { ACCOUNTS_FILENAME } from \"./constants\";\nimport { withDirectoryLock } from \"./file-lock\";\nimport { AccountStorageSchema } from \"./types\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport type { AccountStorage, StoredAccount } from \"./types\";\n\nconst FILE_MODE = 0o600;\n\nfunction getStoragePath(): string {\n return join(getConfigDir(), ACCOUNTS_FILENAME);\n}\n\nfunction createEmptyStorage(): AccountStorage {\n return { version: 1, accounts: [] };\n}\n\nfunction buildTempPath(targetPath: string): string {\n return `${targetPath}.${randomBytes(8).toString(\"hex\")}.tmp`;\n}\n\nasync function writeAtomicText(targetPath: string, content: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const tempPath = buildTempPath(targetPath);\n try {\n await fs.writeFile(tempPath, content, { encoding: \"utf-8\", mode: FILE_MODE });\n await fs.chmod(tempPath, FILE_MODE);\n await fs.rename(tempPath, targetPath);\n await fs.chmod(targetPath, FILE_MODE);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n}\n\nasync function writeStorageAtomic(targetPath: string, storage: AccountStorage): Promise<void> {\n const validation = v.safeParse(AccountStorageSchema, storage);\n if (!validation.success) {\n throw new Error(\"Invalid account storage payload\");\n }\n await writeAtomicText(targetPath, `${JSON.stringify(validation.output, null, 2)}\\n`);\n}\n\nasync function ensureStorageFileExists(targetPath: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const emptyContent = `${JSON.stringify(createEmptyStorage(), null, 2)}\\n`;\n try {\n await fs.writeFile(targetPath, emptyContent, { flag: \"wx\", mode: FILE_MODE });\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") throw error;\n }\n}\n\nasync function withFileLock<T>(fn: (storagePath: string) => Promise<T>): Promise<T> {\n const storagePath = getStoragePath();\n await ensureStorageFileExists(storagePath);\n return await withDirectoryLock(storagePath, () => fn(storagePath));\n}\n\nexport interface DiskCredentials {\n refreshToken: string;\n accessToken?: string;\n expiresAt?: number;\n accountId?: string;\n}\n\nexport class AccountStore {\n async load(): Promise<AccountStorage> {\n const storage = await loadAccounts();\n return storage ?? createEmptyStorage();\n }\n\n async readCredentials(uuid: string): Promise<DiskCredentials | null> {\n const storagePath = getStoragePath();\n const storage = await readStorageFromDisk(storagePath, false);\n if (!storage) return null;\n\n const account = storage.accounts.find((a) => a.uuid === uuid);\n if (!account) return null;\n\n return {\n refreshToken: account.refreshToken,\n accessToken: account.accessToken,\n expiresAt: account.expiresAt,\n accountId: account.accountId,\n };\n }\n\n async mutateAccount(\n uuid: string,\n fn: (account: StoredAccount) => void,\n ): Promise<StoredAccount | null> {\n return await withFileLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false);\n if (!current) return null;\n\n const account = current.accounts.find((a) => a.uuid === uuid);\n if (!account) return null;\n\n fn(account);\n\n await writeStorageAtomic(storagePath, current);\n return { ...account };\n });\n }\n\n async mutateStorage(\n fn: (storage: AccountStorage) => void,\n ): Promise<void> {\n await withFileLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();\n fn(current);\n await writeStorageAtomic(storagePath, current);\n });\n }\n\n async addAccount(account: StoredAccount): Promise<void> {\n await withFileLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();\n const exists = current.accounts.some(\n (a) => a.uuid === account.uuid || a.refreshToken === account.refreshToken,\n );\n if (exists) return;\n\n current.accounts.push(account);\n await writeStorageAtomic(storagePath, current);\n });\n }\n\n async removeAccount(uuid: string): Promise<boolean> {\n return await withFileLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false);\n if (!current) return false;\n\n const initialLength = current.accounts.length;\n current.accounts = current.accounts.filter((a) => a.uuid !== uuid);\n if (current.accounts.length === initialLength) return false;\n\n if (current.activeAccountUuid === uuid) {\n current.activeAccountUuid = current.accounts[0]?.uuid;\n }\n\n await writeStorageAtomic(storagePath, current);\n return true;\n });\n }\n\n async setActiveUuid(uuid: string | undefined): Promise<void> {\n await this.mutateStorage((storage) => {\n storage.activeAccountUuid = uuid;\n });\n }\n\n async clear(): Promise<void> {\n await withFileLock(async (storagePath) => {\n await writeStorageAtomic(storagePath, createEmptyStorage());\n });\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { ACCOUNTS_FILENAME } from \"./constants\";\nimport { AccountStorageSchema } from \"./types\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport type { AccountStorage, StoredAccount } from \"./types\";\n\nfunction getStoragePath(): string {\n return join(getConfigDir(), ACCOUNTS_FILENAME);\n}\n\nasync function backupCorruptFile(targetPath: string, content: string): Promise<void> {\n const backupPath = `${targetPath}.corrupt.${Date.now()}.bak`;\n await fs.mkdir(dirname(backupPath), { recursive: true });\n await fs.writeFile(backupPath, content, \"utf-8\");\n}\n\nexport async function readStorageFromDisk(\n targetPath: string,\n backupOnCorrupt: boolean,\n): Promise<AccountStorage | null> {\n let content: string;\n try {\n content = await fs.readFile(targetPath, \"utf-8\");\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n if (backupOnCorrupt) {\n try {\n await backupCorruptFile(targetPath, content);\n } catch {\n // best-effort backup\n }\n }\n return null;\n }\n\n const validation = v.safeParse(AccountStorageSchema, parsed);\n if (!validation.success) {\n if (backupOnCorrupt) {\n try {\n await backupCorruptFile(targetPath, content);\n } catch {\n // best-effort backup\n }\n }\n return null;\n }\n\n return validation.output;\n}\n\nexport function deduplicateAccounts(accounts: StoredAccount[]): StoredAccount[] {\n const deduplicated: StoredAccount[] = [];\n const indexByUuid = new Map<string, number>();\n\n for (const account of accounts) {\n if (!account.uuid) {\n deduplicated.push(account);\n continue;\n }\n\n const existingIndex = indexByUuid.get(account.uuid);\n if (existingIndex === undefined) {\n indexByUuid.set(account.uuid, deduplicated.length);\n deduplicated.push(account);\n continue;\n }\n\n const existingAccount = deduplicated[existingIndex];\n if (!existingAccount || account.lastUsed >= existingAccount.lastUsed) {\n deduplicated[existingIndex] = account;\n }\n }\n\n return deduplicated;\n}\n\nexport async function loadAccounts(): Promise<AccountStorage | null> {\n const storagePath = getStoragePath();\n const storage = await readStorageFromDisk(storagePath, true);\n if (!storage) {\n return null;\n }\n\n return {\n ...storage,\n accounts: deduplicateAccounts(storage.accounts || []),\n };\n}\n","const DEFAULT_ACCOUNTS_FILENAME = \"multiauth-accounts.json\";\n\nexport let ACCOUNTS_FILENAME = DEFAULT_ACCOUNTS_FILENAME;\n\nexport function setAccountsFilename(filename: string): void {\n if (!filename) {\n ACCOUNTS_FILENAME = DEFAULT_ACCOUNTS_FILENAME;\n return;\n }\n\n ACCOUNTS_FILENAME = filename;\n}\n","import { promises as fs } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst DEFAULT_STALE_MS = 10_000;\nconst DEFAULT_RETRY_DELAY_MS = 50;\nconst DEFAULT_MAX_RETRIES = 10;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function removeIfStale(lockPath: string, staleMs: number): Promise<void> {\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.rm(lockPath, { recursive: true, force: true });\n }\n } catch {}\n}\n\nexport async function withDirectoryLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n options?: {\n staleMs?: number;\n retryDelayMs?: number;\n retries?: number;\n },\n): Promise<T> {\n const lockPath = `${targetPath}.lock`;\n const staleMs = options?.staleMs ?? DEFAULT_STALE_MS;\n const retryDelayMs = options?.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;\n const retries = options?.retries ?? DEFAULT_MAX_RETRIES;\n\n await fs.mkdir(dirname(targetPath), { recursive: true });\n\n for (let attempt = 0; ; attempt += 1) {\n try {\n await fs.mkdir(lockPath, { mode: 0o700 });\n break;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"EEXIST\") {\n throw error;\n }\n\n await removeIfStale(lockPath, staleMs);\n if (attempt >= retries) {\n throw new Error(`Failed to acquire lock for ${targetPath}`);\n }\n await sleep(retryDelayMs * (attempt + 1));\n }\n }\n\n try {\n return await fn();\n } finally {\n await fs.rm(lockPath, { recursive: true, force: true }).catch(() => {});\n }\n}\n","import {\n isTokenRefreshError,\n type ManagedAccount,\n type PluginClient,\n type TokenRefreshResult,\n} from \"./types\";\n\nconst MIN_MAX_RETRIES = 6;\nconst RETRIES_PER_ACCOUNT = 3;\nconst MAX_SERVER_RETRIES_PER_ATTEMPT = 2;\nconst MAX_RESOLVE_ATTEMPTS = 10;\nconst SERVER_RETRY_BASE_MS = 1_000;\nconst SERVER_RETRY_MAX_MS = 4_000;\nexport interface ExecutorAccountManager {\n getAccountCount(): number;\n refresh(): Promise<void>;\n selectAccount(): Promise<ManagedAccount | null>;\n markSuccess(uuid: string): Promise<void>;\n markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void>;\n markRevoked(uuid: string): Promise<void>;\n hasAnyUsableAccount(): boolean;\n getMinWaitTime(): number;\n}\n\nexport interface ExecutorRuntimeFactory {\n getRuntime(uuid: string): Promise<{ fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response> }>;\n invalidate(uuid: string): void;\n}\n\nexport interface ExecutorDependencies {\n handleRateLimitResponse: (\n manager: unknown,\n client: PluginClient,\n account: ManagedAccount,\n response: Response,\n ) => Promise<void>;\n formatWaitTime: (ms: number) => string;\n sleep: (ms: number) => Promise<void>;\n showToast: (\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n ) => Promise<void>;\n getAccountLabel: (account: ManagedAccount) => string;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n\nexport function createExecutorForProvider(\n providerName: string,\n dependencies: ExecutorDependencies,\n): {\n executeWithAccountRotation: (\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n input: RequestInfo | URL,\n init?: RequestInit,\n ) => Promise<Response>;\n} {\n const {\n handleRateLimitResponse,\n formatWaitTime,\n sleep,\n showToast,\n getAccountLabel,\n } = dependencies;\n\n async function executeWithAccountRotation(\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const maxRetries = Math.max(MIN_MAX_RETRIES, manager.getAccountCount() * RETRIES_PER_ACCOUNT);\n let previousAccountUuid: string | undefined;\n\n type StatusTransition =\n | { type: \"success\"; response: Response }\n | { type: \"handled\"; response?: Response }\n | { type: \"retryOuter\" };\n\n async function retryServerErrors(\n account: ManagedAccount,\n runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>,\n ): Promise<Response | null> {\n for (let attempt = 0; attempt < MAX_SERVER_RETRIES_PER_ATTEMPT; attempt++) {\n const backoff = Math.min(SERVER_RETRY_BASE_MS * 2 ** attempt, SERVER_RETRY_MAX_MS);\n const jitteredBackoff = backoff * (0.5 + Math.random() * 0.5);\n await sleep(jitteredBackoff);\n\n let retryResponse: Response;\n try {\n retryResponse = await runtime.fetch(input, init);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n return null;\n }\n void showToast(client, `${getAccountLabel(account)} network error — switching`, \"warning\");\n return null;\n }\n\n if (retryResponse.status < 500) return retryResponse;\n }\n\n return null;\n }\n\n const dispatchResponseStatus = async (\n account: ManagedAccount,\n accountUuid: string,\n runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>,\n response: Response,\n allow401Retry: boolean,\n from401RefreshRetry: boolean,\n ): Promise<StatusTransition> => {\n if (response.status >= 500) {\n const recovered = await retryServerErrors(account, runtime);\n if (recovered === null) {\n return { type: \"retryOuter\" };\n }\n response = recovered;\n }\n\n if (response.status === 401) {\n if (allow401Retry) {\n runtimeFactory.invalidate(accountUuid);\n try {\n const retryRuntime = await runtimeFactory.getRuntime(accountUuid);\n const retryResponse = await retryRuntime.fetch(input, init);\n return dispatchResponseStatus(account, accountUuid, retryRuntime, retryResponse, false, true);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n return { type: \"retryOuter\" };\n }\n return { type: \"retryOuter\" };\n }\n }\n\n await manager.markAuthFailure(accountUuid, { ok: false, permanent: false });\n await manager.refresh();\n\n if (!manager.hasAnyUsableAccount()) {\n void showToast(client, \"All accounts have auth failures.\", \"error\");\n throw new Error(\n `All ${providerName} accounts have authentication failures. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n void showToast(client, `${getAccountLabel(account)} auth failed — switching to next account.`, \"warning\");\n return { type: \"retryOuter\" };\n }\n\n if (response.status === 403) {\n const revoked = await isRevokedTokenResponse(response);\n if (revoked) {\n await manager.markRevoked(accountUuid);\n await manager.refresh();\n void showToast(\n client,\n `${getAccountLabel(account)} disabled: OAuth token revoked.`,\n \"error\",\n );\n\n if (!manager.hasAnyUsableAccount()) {\n throw new Error(\n `All ${providerName} accounts have been revoked or disabled. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n return { type: \"retryOuter\" };\n }\n\n if (from401RefreshRetry) {\n return { type: \"handled\", response };\n }\n }\n\n if (response.status === 429) {\n await handleRateLimitResponse(manager, client, account, response);\n return { type: \"handled\" };\n }\n\n return { type: \"success\", response };\n };\n\n for (let retries = 1; retries <= maxRetries; retries++) {\n await manager.refresh();\n const account = await resolveAccount(manager, client);\n const accountUuid = account.uuid;\n if (!accountUuid) continue;\n\n if (previousAccountUuid && accountUuid !== previousAccountUuid && manager.getAccountCount() > 1) {\n void showToast(client, `Switched to ${getAccountLabel(account)}`, \"info\");\n }\n previousAccountUuid = accountUuid;\n\n let runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>;\n let response: Response;\n try {\n runtime = await runtimeFactory.getRuntime(accountUuid);\n response = await runtime.fetch(input, init);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n continue;\n }\n void showToast(client, `${getAccountLabel(account)} network error — switching`, \"warning\");\n continue;\n }\n\n const transition = await dispatchResponseStatus(account, accountUuid, runtime, response, true, false);\n if (transition.type === \"retryOuter\" || transition.type === \"handled\") {\n if (transition.type === \"handled\" && transition.response) {\n return transition.response;\n }\n continue;\n }\n\n await manager.markSuccess(accountUuid);\n return transition.response;\n }\n\n throw new Error(\n `Exhausted ${maxRetries} retries across all accounts. All attempts failed due to auth errors, rate limits, or token issues.`,\n );\n }\n\n async function handleRuntimeFetchFailure(\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n account: ManagedAccount,\n error: unknown,\n ): Promise<boolean> {\n if (!isTokenRefreshError(error)) return false;\n if (!account.uuid) return false;\n\n const accountUuid = account.uuid;\n runtimeFactory.invalidate(accountUuid);\n await manager.markAuthFailure(accountUuid, {\n ok: false,\n permanent: error.permanent,\n });\n await manager.refresh();\n\n if (!manager.hasAnyUsableAccount()) {\n void showToast(client, \"All accounts have auth failures.\", \"error\");\n throw new Error(\n `All ${providerName} accounts have authentication failures. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n void showToast(client, `${getAccountLabel(account)} auth failed — switching to next account.`, \"warning\");\n return true;\n }\n\n async function resolveAccount(\n manager: ExecutorAccountManager,\n client: PluginClient,\n ): Promise<ManagedAccount> {\n let attempts = 0;\n\n while (true) {\n if (++attempts > MAX_RESOLVE_ATTEMPTS) {\n throw new Error(\n `Failed to resolve an available account after ${MAX_RESOLVE_ATTEMPTS} attempts. All accounts may be rate-limited or disabled.`,\n );\n }\n\n const account = await manager.selectAccount();\n if (account) return account;\n\n if (!manager.hasAnyUsableAccount()) {\n throw new Error(\n `All ${providerName} accounts are disabled. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n const waitMs = manager.getMinWaitTime();\n if (waitMs <= 0) {\n throw new Error(\n `All ${providerName} accounts are rate-limited. Add more accounts with \\`opencode auth login\\` or wait.`,\n );\n }\n\n await showToast(\n client,\n `All ${manager.getAccountCount()} account(s) rate-limited. Waiting ${formatWaitTime(waitMs)}...`,\n \"warning\",\n );\n await sleep(waitMs);\n }\n }\n\n return {\n executeWithAccountRotation,\n };\n}\n\nasync function isRevokedTokenResponse(response: Response): Promise<boolean> {\n try {\n const cloned = response.clone();\n const body = await cloned.text();\n return body.includes(\"revoked\");\n } catch {\n return false;\n }\n}\n","import { AccountStore } from \"./account-store\";\nimport type { PluginClient, PluginConfig, StoredAccount, TokenRefreshResult } from \"./types\";\nimport { getClearedOAuthBody } from \"./utils\";\n\nconst INITIAL_DELAY_MS = 5_000;\n\nexport interface ProactiveRefreshDependencies {\n providerAuthId: string;\n getConfig: () => PluginConfig;\n refreshToken: (\n currentRefreshToken: string,\n accountId: string,\n client: PluginClient,\n ) => Promise<TokenRefreshResult>;\n isTokenExpired: (account: Pick<StoredAccount, \"accessToken\" | \"expiresAt\">) => boolean;\n debugLog: (client: PluginClient, message: string, extra?: Record<string, unknown>) => void;\n}\n\nexport interface ProactiveRefreshQueueInstance {\n start(): void;\n stop(): Promise<void>;\n}\n\nexport interface ProactiveRefreshQueueClass {\n new (\n client: PluginClient,\n store: AccountStore,\n onInvalidate?: (uuid: string) => void,\n ): ProactiveRefreshQueueInstance;\n}\n\nexport function createProactiveRefreshQueueForProvider(dependencies: ProactiveRefreshDependencies): ProactiveRefreshQueueClass {\n const {\n providerAuthId,\n getConfig,\n refreshToken,\n isTokenExpired,\n debugLog,\n } = dependencies;\n\n return class ProactiveRefreshQueue {\n private timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n private runToken = 0;\n private inFlight: Promise<void> | null = null;\n\n constructor(\n private readonly client: PluginClient,\n private readonly store: AccountStore,\n private readonly onInvalidate?: (uuid: string) => void,\n ) {}\n\n start(): void {\n const config = getConfig();\n if (!config.proactive_refresh) return;\n\n this.runToken++;\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle);\n this.timeoutHandle = null;\n }\n this.scheduleNext(this.runToken, INITIAL_DELAY_MS);\n\n debugLog(this.client, \"Proactive refresh started\", {\n intervalSeconds: config.proactive_refresh_interval_seconds,\n bufferSeconds: config.proactive_refresh_buffer_seconds,\n });\n }\n\n async stop(): Promise<void> {\n this.runToken++;\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle);\n this.timeoutHandle = null;\n }\n if (this.inFlight) {\n await this.inFlight;\n this.inFlight = null;\n }\n debugLog(this.client, \"Proactive refresh stopped\");\n }\n\n private scheduleNext(token: number, delayMs: number): void {\n this.timeoutHandle = setTimeout(() => {\n if (token !== this.runToken) return;\n this.inFlight = this.runCheck(token).finally(() => {\n this.inFlight = null;\n });\n }, delayMs);\n }\n\n private needsProactiveRefresh(account: Pick<StoredAccount, \"accessToken\" | \"expiresAt\">): boolean {\n if (!account.accessToken || !account.expiresAt) return false;\n if (isTokenExpired(account)) return false;\n const bufferMs = getConfig().proactive_refresh_buffer_seconds * 1000;\n return account.expiresAt <= Date.now() + bufferMs;\n }\n\n private async runCheck(token: number): Promise<void> {\n try {\n const stored = await this.store.load();\n if (token !== this.runToken) return;\n\n const candidates = stored.accounts.filter((a) =>\n a.enabled !== false\n && !a.isAuthDisabled\n && a.uuid\n && this.needsProactiveRefresh(a),\n );\n\n if (candidates.length === 0) return;\n\n debugLog(this.client, `Proactive refresh: ${candidates.length} account(s) approaching expiry`);\n\n for (const account of candidates) {\n if (token !== this.runToken) return;\n\n const credentials = await this.store.readCredentials(account.uuid!);\n if (!credentials || !this.needsProactiveRefresh(credentials)) continue;\n\n const result = await refreshToken(credentials.refreshToken, account.uuid!, this.client);\n if (result.ok) {\n await this.store.mutateAccount(account.uuid!, (target) => {\n target.accessToken = result.patch.accessToken;\n target.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) target.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid) target.uuid = result.patch.uuid;\n if (result.patch.email) target.email = result.patch.email;\n if (result.patch.accountId) target.accountId = result.patch.accountId;\n target.consecutiveAuthFailures = 0;\n target.isAuthDisabled = false;\n target.authDisabledReason = undefined;\n });\n this.onInvalidate?.(account.uuid!);\n } else {\n await this.persistFailure(account, result.permanent);\n }\n }\n } catch (error) {\n debugLog(this.client, `Proactive refresh check error: ${error}`);\n } finally {\n if (token === this.runToken) {\n const intervalMs = getConfig().proactive_refresh_interval_seconds * 1000;\n this.scheduleNext(token, intervalMs);\n }\n }\n }\n\n private async persistFailure(account: StoredAccount, permanent: boolean): Promise<void> {\n try {\n const accountUuid = account.uuid;\n if (!accountUuid) return;\n\n if (permanent) {\n const removed = await this.store.removeAccount(accountUuid);\n if (!removed) return;\n\n this.onInvalidate?.(accountUuid);\n await this.clearOpenCodeAuthIfNoAccountsRemain();\n return;\n }\n\n await this.store.mutateStorage((storage) => {\n const target = storage.accounts.find((entry) => entry.uuid === accountUuid);\n if (!target) return;\n\n target.consecutiveAuthFailures = (target.consecutiveAuthFailures ?? 0) + 1;\n const maxFailures = getConfig().max_consecutive_auth_failures;\n const usableCount = storage.accounts.filter(\n (entry) => entry.enabled && !entry.isAuthDisabled && entry.uuid !== accountUuid,\n ).length;\n\n if (target.consecutiveAuthFailures >= maxFailures && usableCount > 0) {\n target.isAuthDisabled = true;\n target.authDisabledReason = `${maxFailures} consecutive auth failures (proactive refresh)`;\n }\n });\n } catch {\n debugLog(this.client, `Failed to persist auth failure for ${account.uuid}`);\n }\n }\n\n private async clearOpenCodeAuthIfNoAccountsRemain(): Promise<void> {\n const storage = await this.store.load();\n if (storage.accounts.length > 0) return;\n\n await this.client.auth\n .set({\n path: { id: providerAuthId },\n body: getClearedOAuthBody(),\n })\n .catch(() => {});\n }\n };\n}\n","import type { ManagedAccount, PluginClient, PluginConfig, UsageLimits } from \"./types\";\n\nconst USAGE_FETCH_COOLDOWN_MS = 30_000;\n\nexport interface RateLimitDependencies {\n fetchUsage: (accessToken: string, accountId?: string) => Promise<{ ok: true; data: UsageLimits } | { ok: false; reason: string }>;\n getConfig: () => Pick<PluginConfig, \"default_retry_after_ms\">;\n formatWaitTime: (ms: number) => string;\n getAccountLabel: (account: ManagedAccount) => string;\n showToast: (\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n ) => Promise<void>;\n}\n\nexport interface RateLimitAccountManager {\n markRateLimited(uuid: string, backoffMs?: number): Promise<void>;\n applyUsageCache(uuid: string, usage: UsageLimits): Promise<void>;\n getAccountCount(): number;\n}\n\nexport function createRateLimitHandlers(dependencies: RateLimitDependencies) {\n const {\n fetchUsage,\n getConfig,\n formatWaitTime,\n getAccountLabel,\n showToast,\n } = dependencies;\n\n function retryAfterMsFromResponse(response: Response): number {\n const retryAfterMs = response.headers.get(\"retry-after-ms\");\n if (retryAfterMs) {\n const parsed = parseInt(retryAfterMs, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n\n const retryAfter = response.headers.get(\"retry-after\");\n if (retryAfter) {\n const parsed = parseInt(retryAfter, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed * 1000;\n }\n\n return getConfig().default_retry_after_ms;\n }\n\n function getResetMsFromUsage(account: ManagedAccount): number | null {\n const usage = account.cachedUsage;\n if (!usage) return null;\n\n const now = Date.now();\n const candidates: number[] = [];\n\n if (usage.five_hour?.resets_at) {\n const ms = Date.parse(usage.five_hour.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n if (usage.seven_day?.resets_at) {\n const ms = Date.parse(usage.seven_day.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n\n return candidates.length > 0 ? Math.min(...candidates) : null;\n }\n\n async function fetchUsageLimits(accessToken: string, accountId?: string): Promise<UsageLimits | null> {\n if (!accessToken) return null;\n try {\n const result = await fetchUsage(accessToken, accountId);\n return result.ok ? result.data : null;\n } catch {\n return null;\n }\n }\n\n async function handleRateLimitResponse(\n manager: RateLimitAccountManager,\n client: PluginClient,\n account: ManagedAccount,\n response: Response,\n ): Promise<void> {\n if (!account.uuid) return;\n\n const resetMs = getResetMsFromUsage(account) ?? retryAfterMsFromResponse(response);\n await manager.markRateLimited(account.uuid, resetMs);\n\n const shouldFetchUsage = account.accessToken\n && (!account.cachedUsageAt || Date.now() - account.cachedUsageAt > USAGE_FETCH_COOLDOWN_MS);\n\n if (shouldFetchUsage) {\n const usage = await fetchUsageLimits(account.accessToken!, account.accountId);\n if (usage) {\n await manager.applyUsageCache(account.uuid, usage);\n }\n }\n\n if (manager.getAccountCount() > 1) {\n void showToast(\n client,\n `${getAccountLabel(account)} rate-limited (resets in ${formatWaitTime(resetMs)}). Switching...`,\n \"warning\",\n );\n }\n }\n\n return {\n retryAfterMsFromResponse,\n getResetMsFromUsage,\n fetchUsageLimits,\n handleRateLimitResponse,\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"./utils\";\nimport type { AccountStore } from \"./account-store\";\n\nconst AUTH_JSON_FILENAME = \"auth.json\";\n\ninterface AuthJsonCredential {\n type: string;\n refresh: string;\n access?: string;\n expires?: number;\n}\n\nfunction isValidOAuthCredential(value: unknown): value is AuthJsonCredential {\n if (typeof value !== \"object\" || value === null) return false;\n\n const candidate = value as Record<string, unknown>;\n return (\n candidate.type === \"oauth\" &&\n typeof candidate.refresh === \"string\" &&\n candidate.refresh.length > 0\n );\n}\n\nfunction resolveAuthJsonPath(): string {\n return join(getConfigDir(), AUTH_JSON_FILENAME);\n}\n\nasync function readAuthJson(): Promise<Record<string, unknown> | null> {\n const authPath = resolveAuthJsonPath();\n\n let content: string;\n try {\n content = await fs.readFile(authPath, \"utf-8\");\n } catch {\n return null;\n }\n\n try {\n const parsed = JSON.parse(content);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Imports an existing OAuth credential from OpenCode's auth.json\n * into the multi-account storage on first use.\n *\n * Only runs when storage has zero accounts. Does not modify auth.json.\n *\n * @param providerKey - The key in auth.json (\"anthropic\" or \"openai\")\n * @param store - The AccountStore instance to import into\n * @returns true if a credential was imported, false otherwise\n */\nexport async function migrateFromAuthJson(\n providerKey: string,\n store: AccountStore,\n): Promise<boolean> {\n const storage = await store.load();\n const hasExistingAccounts = storage.accounts.length > 0;\n if (hasExistingAccounts) return false;\n\n const authData = await readAuthJson();\n if (!authData) return false;\n\n const providerCredential = authData[providerKey];\n if (!isValidOAuthCredential(providerCredential)) return false;\n\n const now = Date.now();\n const newAccount = {\n uuid: crypto.randomUUID(),\n refreshToken: providerCredential.refresh,\n accessToken: providerCredential.access,\n expiresAt: providerCredential.expires,\n addedAt: now,\n lastUsed: now,\n enabled: true,\n planTier: \"\",\n consecutiveAuthFailures: 0,\n isAuthDisabled: false,\n };\n\n await store.addAccount(newAccount);\n await store.setActiveUuid(newAccount.uuid);\n\n return true;\n}\n","export const ANSI = {\n hide: \"\\x1b[?25l\",\n show: \"\\x1b[?25h\",\n up: (n = 1) => `\\x1b[${n}A`,\n down: (n = 1) => `\\x1b[${n}B`,\n clearLine: \"\\x1b[2K\",\n\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n red: \"\\x1b[31m\",\n yellow: \"\\x1b[33m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n reset: \"\\x1b[0m\",\n} as const;\n\nexport type KeyAction = \"up\" | \"down\" | \"enter\" | \"escape\" | \"escape-start\" | null;\n\nexport function parseKey(data: Buffer): KeyAction {\n const s = data.toString();\n\n // Standard: \\x1b[A / Application mode: \\x1bOA\n if (s === \"\\x1b[A\" || s === \"\\x1bOA\") return \"up\";\n if (s === \"\\x1b[B\" || s === \"\\x1bOB\") return \"down\";\n\n if (s === \"\\r\" || s === \"\\n\") return \"enter\";\n if (s === \"\\x03\") return \"escape\";\n\n // Bare escape byte — may be start of arrow key sequence\n if (s === \"\\x1b\") return \"escape-start\";\n\n return null;\n}\n\nexport function isTTY(): boolean {\n return Boolean(process.stdin.isTTY);\n}\n","import { ANSI, isTTY, parseKey } from \"./ansi\";\n\nexport interface MenuItem<T = string> {\n label: string;\n value: T;\n hint?: string;\n disabled?: boolean;\n separator?: boolean;\n color?: \"red\" | \"green\" | \"yellow\" | \"cyan\";\n}\n\nexport interface SelectOptions {\n message: string;\n subtitle?: string;\n}\n\nconst ESCAPE_TIMEOUT_MS = 50;\n\nconst COLOR_MAP: Record<string, string> = {\n red: ANSI.red,\n green: ANSI.green,\n yellow: ANSI.yellow,\n cyan: ANSI.cyan,\n};\n\nexport async function select<T>(\n items: MenuItem<T>[],\n options: SelectOptions,\n): Promise<T | null> {\n if (!isTTY()) {\n throw new Error(\"Interactive select requires a TTY terminal\");\n }\n\n const enabledItems = items.filter((i) => !i.disabled && !i.separator);\n if (enabledItems.length === 0) {\n throw new Error(\"All items disabled\");\n }\n\n if (enabledItems.length === 1) {\n return enabledItems[0]!.value;\n }\n\n const { message, subtitle } = options;\n const { stdin, stdout } = process;\n\n let cursor = items.findIndex((i) => !i.disabled && !i.separator);\n if (cursor === -1) cursor = 0;\n let escapeTimeout: ReturnType<typeof setTimeout> | null = null;\n let isCleanedUp = false;\n let isFirstRender = true;\n\n const getTotalLines = (): number => {\n const subtitleLines = subtitle ? 3 : 0;\n return 1 + subtitleLines + items.length + 1 + 1;\n };\n\n const renderItemLabel = (item: MenuItem<T>, isSelected: boolean): string => {\n const colorCode = item.color ? (COLOR_MAP[item.color] ?? \"\") : \"\";\n\n if (item.disabled) {\n return `${ANSI.dim}${item.label} (unavailable)${ANSI.reset}`;\n }\n\n const hintSuffix = item.hint ? ` ${ANSI.dim}${item.hint}${ANSI.reset}` : \"\";\n\n if (isSelected) {\n const label = colorCode ? `${colorCode}${item.label}${ANSI.reset}` : item.label;\n return `${label}${hintSuffix}`;\n }\n\n const dimLabel = colorCode\n ? `${ANSI.dim}${colorCode}${item.label}${ANSI.reset}`\n : `${ANSI.dim}${item.label}${ANSI.reset}`;\n return `${dimLabel}${hintSuffix}`;\n };\n\n const render = () => {\n const totalLines = getTotalLines();\n\n if (!isFirstRender) {\n stdout.write(ANSI.up(totalLines) + \"\\r\");\n }\n isFirstRender = false;\n\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u250c ${ANSI.reset}${message}\\n`);\n\n if (subtitle) {\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u2502${ANSI.reset}\\n`);\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u25c6${ANSI.reset} ${subtitle}\\n`);\n stdout.write(`${ANSI.clearLine}\\n`);\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (!item) continue;\n\n if (item.separator) {\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u2502${ANSI.reset}\\n`);\n continue;\n }\n\n const isSelected = i === cursor;\n const labelText = renderItemLabel(item, isSelected);\n const bullet = isSelected\n ? `${ANSI.green}\\u25cf${ANSI.reset}`\n : `${ANSI.dim}\\u25cb${ANSI.reset}`;\n\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2502${ANSI.reset} ${bullet} ${labelText}\\n`);\n }\n\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2502${ANSI.reset} ${ANSI.dim}\\u2191/\\u2193 to select \\u2022 Enter: confirm${ANSI.reset}\\n`);\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2514${ANSI.reset}\\n`);\n };\n\n return new Promise((resolve) => {\n const wasRaw = stdin.isRaw ?? false;\n\n const cleanup = () => {\n if (isCleanedUp) return;\n isCleanedUp = true;\n\n if (escapeTimeout) {\n clearTimeout(escapeTimeout);\n escapeTimeout = null;\n }\n\n try {\n stdin.removeListener(\"data\", onKey);\n stdin.setRawMode(wasRaw);\n stdin.pause();\n stdout.write(ANSI.show);\n } catch {\n // best-effort cleanup\n }\n\n process.removeListener(\"SIGINT\", onSignal);\n process.removeListener(\"SIGTERM\", onSignal);\n };\n\n const onSignal = () => {\n cleanup();\n resolve(null);\n };\n\n const finishWithValue = (value: T | null) => {\n cleanup();\n resolve(value);\n };\n\n const findNextSelectable = (from: number, direction: 1 | -1): number => {\n if (items.length === 0) return from;\n let next = from;\n do {\n next = (next + direction + items.length) % items.length;\n } while (items[next]?.disabled || items[next]?.separator);\n return next;\n };\n\n const onKey = (data: Buffer) => {\n if (escapeTimeout) {\n clearTimeout(escapeTimeout);\n escapeTimeout = null;\n }\n\n const action = parseKey(data);\n\n switch (action) {\n case \"up\":\n cursor = findNextSelectable(cursor, -1);\n render();\n return;\n case \"down\":\n cursor = findNextSelectable(cursor, 1);\n render();\n return;\n case \"enter\":\n finishWithValue(items[cursor]?.value ?? null);\n return;\n case \"escape\":\n finishWithValue(null);\n return;\n case \"escape-start\":\n escapeTimeout = setTimeout(() => {\n finishWithValue(null);\n }, ESCAPE_TIMEOUT_MS);\n return;\n default:\n return;\n }\n };\n\n process.once(\"SIGINT\", onSignal);\n process.once(\"SIGTERM\", onSignal);\n\n try {\n stdin.setRawMode(true);\n } catch {\n cleanup();\n resolve(null);\n return;\n }\n\n stdin.resume();\n stdout.write(ANSI.hide);\n render();\n\n stdin.on(\"data\", onKey);\n });\n}\n","import { select } from \"./select\";\n\nexport async function confirm(message: string, defaultYes = false): Promise<boolean> {\n const items = defaultYes\n ? [\n { label: \"Yes\", value: true },\n { label: \"No\", value: false },\n ]\n : [\n { label: \"No\", value: false },\n { label: \"Yes\", value: true },\n ];\n\n const result = await select(items, { message });\n return result ?? false;\n}\n","import type { OAuthAdapter } from \"./types\";\n\nexport const anthropicOAuthAdapter: OAuthAdapter = {\n id: \"anthropic\",\n authProviderId: \"anthropic\",\n modelDisplayName: \"Claude\",\n statusToolName: \"claude_multiauth_status\",\n authMethodLabel: \"Claude Pro/Max (Multi-Auth)\",\n serviceLogName: \"claude-multiauth\",\n oauthClientId: \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\",\n tokenEndpoint: \"https://console.anthropic.com/v1/oauth/token\",\n usageEndpoint: \"https://api.anthropic.com/api/oauth/usage\",\n profileEndpoint: \"https://api.anthropic.com/api/oauth/profile\",\n oauthBetaHeader: \"oauth-2025-04-20\",\n requestBetaHeader: \"oauth-2025-04-20,interleaved-thinking-2025-05-14\",\n cliUserAgent: \"claude-cli/2.1.2 (external, cli)\",\n cliVersion: \"2.1.80\",\n billingSalt: \"59cf53e54c78\",\n toolPrefix: \"mcp_\",\n accountStorageFilename: \"anthropic-multi-account-accounts.json\",\n transform: {\n rewriteOpenCodeBranding: true,\n addToolPrefix: true,\n stripToolPrefixInResponse: true,\n enableMessagesBetaQuery: true,\n },\n planLabels: {\n max: \"Claude Max\",\n pro: \"Claude Pro\",\n free: \"Free\",\n },\n supported: true,\n};\n","import type { OAuthAdapter } from \"./types\";\n\nconst ISSUER = \"https://auth.openai.com\";\n\nexport const openAIOAuthAdapter: OAuthAdapter = {\n id: \"openai\",\n authProviderId: \"openai\",\n modelDisplayName: \"ChatGPT\",\n statusToolName: \"chatgpt_multiauth_status\",\n authMethodLabel: \"ChatGPT Plus/Pro (Multi-Auth)\",\n serviceLogName: \"chatgpt-multiauth\",\n oauthClientId: \"app_EMoamEEZ73f0CkXaXp7hrann\",\n tokenEndpoint: `${ISSUER}/oauth/token`,\n usageEndpoint: \"\",\n profileEndpoint: \"\",\n oauthBetaHeader: \"\",\n requestBetaHeader: \"\",\n cliUserAgent: \"opencode/1.1.53\",\n cliVersion: \"\",\n billingSalt: \"\",\n toolPrefix: \"mcp_\",\n accountStorageFilename: \"openai-multi-account-accounts.json\",\n transform: {\n rewriteOpenCodeBranding: false,\n addToolPrefix: false,\n stripToolPrefixInResponse: false,\n enableMessagesBetaQuery: false,\n },\n planLabels: {\n pro: \"ChatGPT Pro\",\n plus: \"ChatGPT Plus\",\n go: \"ChatGPT Go\",\n free: \"Free\",\n },\n supported: true,\n};\n","import * as v from \"valibot\";\n\n// ─── Valibot Schemas (disk-persisted config) ─────────────────────\n\nexport const PoolConfigSchema = v.object({\n name: v.string(),\n baseProvider: v.string(),\n members: v.array(v.string()),\n enabled: v.boolean(),\n});\n\nexport const ChainEntryConfigSchema = v.object({\n pool: v.string(),\n model: v.optional(v.string()),\n enabled: v.boolean(),\n});\n\nexport const ChainConfigSchema = v.object({\n name: v.string(),\n entries: v.array(ChainEntryConfigSchema),\n enabled: v.boolean(),\n});\n\nexport const PoolChainConfigSchema = v.object({\n pools: v.optional(v.array(PoolConfigSchema), []),\n chains: v.optional(v.array(ChainConfigSchema), []),\n});\n\n// ─── Inferred Types (from schemas) ───────────────────────────────\n\nexport type PoolConfig = v.InferOutput<typeof PoolConfigSchema>;\nexport type ChainEntryConfig = v.InferOutput<typeof ChainEntryConfigSchema>;\nexport type ChainConfig = v.InferOutput<typeof ChainConfigSchema>;\nexport type PoolChainConfig = v.InferOutput<typeof PoolChainConfigSchema>;\n\n// In-memory cascade state (NOT persisted)\nexport interface CascadeState {\n prompt: string;\n attemptedAccounts: Set<string>;\n visitedChainIndexes: Set<number>;\n}\n\n// Candidate for failover rotation\nexport interface FailoverCandidate {\n poolName: string;\n accountUuid: string;\n source: \"pool\" | \"chain\";\n chainIndex?: number;\n}\n\n// Skipped entry during failover planning\nexport interface FailoverSkip {\n type: \"pool_exhausted\" | \"chain_disabled\" | \"account_attempted\" | \"account_unavailable\";\n poolName: string;\n reason: string;\n detail?: string;\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { withDirectoryLock } from \"./file-lock\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport { PoolChainConfigSchema } from \"./pool-types\";\nimport type { PoolChainConfig } from \"./pool-types\";\n\nconst POOL_CONFIG_FILENAME = \"multiauth-pools.json\";\nconst FILE_MODE = 0o600;\n\nfunction createEmptyConfig(): PoolChainConfig {\n return { pools: [], chains: [] };\n}\n\nfunction getGlobalConfigPath(): string {\n return join(getConfigDir(), POOL_CONFIG_FILENAME);\n}\n\nfunction buildTempPath(targetPath: string): string {\n return `${targetPath}.${randomBytes(8).toString(\"hex\")}.tmp`;\n}\n\nasync function resolveConfigPath(): Promise<string> {\n const projectPath = join(process.cwd(), \".opencode\", POOL_CONFIG_FILENAME);\n try {\n await fs.access(projectPath);\n return projectPath;\n } catch {\n }\n return getGlobalConfigPath();\n}\n\nasync function ensureConfigFileExists(targetPath: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const emptyContent = `${JSON.stringify(createEmptyConfig(), null, 2)}\\n`;\n try {\n await fs.writeFile(targetPath, emptyContent, { flag: \"wx\", mode: FILE_MODE });\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") throw error;\n }\n}\n\nasync function writeAtomicText(targetPath: string, content: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const tempPath = buildTempPath(targetPath);\n try {\n await fs.writeFile(tempPath, content, { encoding: \"utf-8\", mode: FILE_MODE });\n await fs.chmod(tempPath, FILE_MODE);\n await fs.rename(tempPath, targetPath);\n await fs.chmod(targetPath, FILE_MODE);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n}\n\nasync function withConfigLock<T>(fn: (configPath: string) => Promise<T>): Promise<T> {\n const configPath = await resolveConfigPath();\n await ensureConfigFileExists(configPath);\n return await withDirectoryLock(configPath, () => fn(configPath));\n}\n\nfunction parsePoolChainConfig(content: string): PoolChainConfig | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n\n const validation = v.safeParse(PoolChainConfigSchema, parsed);\n return validation.success ? validation.output : null;\n}\n\nexport async function loadPoolChainConfig(): Promise<PoolChainConfig> {\n const path = await resolveConfigPath();\n try {\n const content = await fs.readFile(path, \"utf-8\");\n return parsePoolChainConfig(content) ?? createEmptyConfig();\n } catch {\n return createEmptyConfig();\n }\n}\n\nexport async function savePoolChainConfig(config: PoolChainConfig): Promise<void> {\n await withConfigLock(async (configPath) => {\n const validation = v.safeParse(PoolChainConfigSchema, config);\n if (!validation.success) {\n throw new Error(\"Invalid pool/chain config payload\");\n }\n await writeAtomicText(configPath, `${JSON.stringify(validation.output, null, 2)}\\n`);\n });\n}\n","import type { ManagedAccount } from \"./types\";\nimport type { FailoverCandidate, FailoverSkip, PoolChainConfig, PoolConfig } from \"./pool-types\";\n\nconst DEFAULT_EXHAUSTED_COOLDOWN_MS = 5 * 60 * 1000;\n\ninterface PoolAwareAccountManager {\n getAccounts(): ManagedAccount[];\n isRateLimited(account: ManagedAccount): boolean;\n selectAccount(): Promise<ManagedAccount | null>;\n}\n\nexport interface BuildFailoverPlanOptions {\n attemptedAccounts?: Set<string>;\n visitedChainIndexes?: Set<number>;\n}\n\nexport interface FailoverPlan {\n candidates: FailoverCandidate[];\n skips: FailoverSkip[];\n}\n\nexport class PoolManager {\n private poolsByName = new Map<string, PoolConfig>();\n private exhaustedUntilByAccount = new Map<string, number>();\n private exhaustedCooldownMs: number;\n\n constructor(options?: { exhaustedCooldownMs?: number }) {\n this.exhaustedCooldownMs = options?.exhaustedCooldownMs ?? DEFAULT_EXHAUSTED_COOLDOWN_MS;\n }\n\n loadPools(configs: PoolConfig[]): void {\n this.poolsByName.clear();\n for (const pool of configs) {\n this.poolsByName.set(pool.name, pool);\n }\n }\n\n getPoolForAccount(accountUuid: string): PoolConfig | null {\n for (const pool of this.poolsByName.values()) {\n if (!pool.enabled) continue;\n if (pool.members.includes(accountUuid)) return pool;\n }\n return null;\n }\n\n getAvailableMembers(pool: PoolConfig, accountManager: PoolAwareAccountManager): string[] {\n if (!pool.enabled) return [];\n this.clearExpiredExhausted();\n\n const accountsByUuid = new Map<string, ManagedAccount>();\n for (const account of accountManager.getAccounts()) {\n if (!account.uuid) continue;\n accountsByUuid.set(account.uuid, account);\n }\n\n return pool.members.filter((accountUuid) => {\n const account = accountsByUuid.get(accountUuid);\n if (!account) return false;\n if (!account.enabled || account.isAuthDisabled) return false;\n if (this.isExhausted(accountUuid)) return false;\n if (accountManager.isRateLimited(account)) return false;\n return true;\n });\n }\n\n markExhausted(accountUuid: string): void {\n this.exhaustedUntilByAccount.set(accountUuid, Date.now() + this.exhaustedCooldownMs);\n }\n\n async getNextMember(\n pool: PoolConfig,\n currentUuid: string | undefined,\n accountManager: PoolAwareAccountManager,\n ): Promise<string | null> {\n const availableMembers = this.getAvailableMembers(pool, accountManager);\n if (availableMembers.length === 0) return null;\n\n const excluded = new Set<string>();\n if (currentUuid) excluded.add(currentUuid);\n\n const preferred = await this.selectPreferredMember(availableMembers, excluded, accountManager);\n if (preferred) return preferred;\n\n for (const candidate of availableMembers) {\n if (candidate !== currentUuid) return candidate;\n }\n\n return null;\n }\n\n async buildFailoverPlan(\n currentAccount: Pick<ManagedAccount, \"uuid\" | \"accountId\"> | null,\n config: PoolChainConfig,\n accountManager: PoolAwareAccountManager,\n options?: BuildFailoverPlanOptions,\n ): Promise<FailoverPlan> {\n this.loadPools(config.pools ?? []);\n\n if ((config.pools?.length ?? 0) === 0 && (config.chains?.length ?? 0) === 0) {\n return { candidates: [], skips: [] };\n }\n\n const attemptedAccounts = options?.attemptedAccounts ?? new Set<string>();\n const visitedChainIndexes = options?.visitedChainIndexes ?? new Set<number>();\n const currentUuid = currentAccount?.uuid;\n\n const candidates: FailoverCandidate[] = [];\n const skips: FailoverSkip[] = [];\n const addedCandidateUuids = new Set<string>();\n\n const appendPoolCandidates = async (\n poolName: string,\n source: \"pool\" | \"chain\",\n chainIndex?: number,\n ): Promise<void> => {\n const pool = this.poolsByName.get(poolName);\n if (!pool || !pool.enabled) {\n skips.push({\n type: \"chain_disabled\",\n poolName,\n reason: \"Pool is missing or disabled\",\n });\n return;\n }\n\n const available = this.getAvailableMembers(pool, accountManager);\n if (available.length === 0) {\n skips.push({\n type: \"pool_exhausted\",\n poolName,\n reason: \"No available members\",\n });\n return;\n }\n\n const poolExclusions = new Set<string>();\n if (currentUuid) poolExclusions.add(currentUuid);\n\n while (poolExclusions.size < available.length + (currentUuid ? 1 : 0)) {\n const nextMember = await this.selectPreferredMember(available, poolExclusions, accountManager);\n if (!nextMember) break;\n\n poolExclusions.add(nextMember);\n\n if (attemptedAccounts.has(nextMember)) {\n skips.push({\n type: \"account_attempted\",\n poolName,\n reason: \"Already attempted in this cascade\",\n detail: nextMember,\n });\n continue;\n }\n\n if (addedCandidateUuids.has(nextMember)) continue;\n\n candidates.push({\n poolName,\n accountUuid: nextMember,\n source,\n chainIndex,\n });\n addedCandidateUuids.add(nextMember);\n }\n\n for (const memberUuid of available) {\n if (poolExclusions.has(memberUuid)) continue;\n if (attemptedAccounts.has(memberUuid)) {\n skips.push({\n type: \"account_attempted\",\n poolName,\n reason: \"Already attempted in this cascade\",\n detail: memberUuid,\n });\n continue;\n }\n if (addedCandidateUuids.has(memberUuid)) continue;\n\n candidates.push({\n poolName,\n accountUuid: memberUuid,\n source,\n chainIndex,\n });\n addedCandidateUuids.add(memberUuid);\n }\n };\n\n if (currentUuid) {\n const currentPool = this.getPoolForAccount(currentUuid);\n if (currentPool) {\n await appendPoolCandidates(currentPool.name, \"pool\");\n }\n }\n\n let flattenedChainIndex = 0;\n for (const chain of config.chains ?? []) {\n if (!chain.enabled) {\n for (let i = 0; i < chain.entries.length; i++) {\n skips.push({\n type: \"chain_disabled\",\n poolName: chain.entries[i]?.pool ?? chain.name,\n reason: `Chain '${chain.name}' is disabled`,\n });\n flattenedChainIndex += 1;\n }\n continue;\n }\n\n for (const entry of chain.entries) {\n if (visitedChainIndexes.has(flattenedChainIndex)) {\n skips.push({\n type: \"chain_disabled\",\n poolName: entry.pool,\n reason: \"Chain entry already visited in this cascade\",\n detail: `${flattenedChainIndex}`,\n });\n flattenedChainIndex += 1;\n continue;\n }\n\n if (!entry.enabled) {\n skips.push({\n type: \"chain_disabled\",\n poolName: entry.pool,\n reason: \"Chain entry is disabled\",\n detail: `${flattenedChainIndex}`,\n });\n flattenedChainIndex += 1;\n continue;\n }\n\n await appendPoolCandidates(entry.pool, \"chain\", flattenedChainIndex);\n flattenedChainIndex += 1;\n }\n }\n\n return { candidates, skips };\n }\n\n private isExhausted(accountUuid: string): boolean {\n const exhaustedUntil = this.exhaustedUntilByAccount.get(accountUuid);\n if (!exhaustedUntil) return false;\n if (Date.now() >= exhaustedUntil) {\n this.exhaustedUntilByAccount.delete(accountUuid);\n return false;\n }\n return true;\n }\n\n private clearExpiredExhausted(): void {\n const now = Date.now();\n for (const [accountUuid, exhaustedUntil] of this.exhaustedUntilByAccount.entries()) {\n if (now >= exhaustedUntil) this.exhaustedUntilByAccount.delete(accountUuid);\n }\n }\n\n private async selectPreferredMember(\n availableMembers: string[],\n excludedMembers: Set<string>,\n accountManager: PoolAwareAccountManager,\n ): Promise<string | null> {\n const availableSet = new Set(availableMembers);\n const maxAttempts = Math.max(availableMembers.length * 2, 6);\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const selected = await accountManager.selectAccount();\n if (!selected?.uuid) continue;\n if (!availableSet.has(selected.uuid)) continue;\n if (excludedMembers.has(selected.uuid)) continue;\n return selected.uuid;\n }\n\n for (const memberUuid of availableMembers) {\n if (!excludedMembers.has(memberUuid)) return memberUuid;\n }\n return null;\n }\n}\n","import type { CascadeState } from \"./pool-types\";\n\nfunction createCascadeState(prompt: string, currentAccountUuid?: string): CascadeState {\n const attemptedAccounts = new Set<string>();\n if (currentAccountUuid) {\n attemptedAccounts.add(currentAccountUuid);\n }\n\n return {\n prompt,\n attemptedAccounts,\n visitedChainIndexes: new Set<number>(),\n };\n}\n\nexport class CascadeStateManager {\n public suppressNextStartTurn = false;\n private cascadeState: CascadeState | null = null;\n\n startTurn(prompt: string, currentAccountUuid?: string): CascadeState {\n if (this.suppressNextStartTurn) {\n this.suppressNextStartTurn = false;\n return this.ensureCascadeState(prompt, currentAccountUuid);\n }\n\n const shouldReset = !this.cascadeState || this.cascadeState.prompt !== prompt;\n if (shouldReset) {\n this.cascadeState = createCascadeState(prompt, currentAccountUuid);\n return this.cascadeState;\n }\n\n return this.ensureCascadeState(prompt, currentAccountUuid);\n }\n\n ensureCascadeState(prompt: string, currentAccountUuid?: string): CascadeState {\n if (!this.cascadeState || this.cascadeState.prompt !== prompt) {\n this.cascadeState = createCascadeState(prompt, currentAccountUuid);\n return this.cascadeState;\n }\n\n if (currentAccountUuid) {\n this.cascadeState.attemptedAccounts.add(currentAccountUuid);\n }\n\n return this.cascadeState;\n }\n\n markAttempted(accountUuid: string): void {\n if (!this.cascadeState) return;\n this.cascadeState.attemptedAccounts.add(accountUuid);\n }\n\n markVisitedChainIndex(index: number): void {\n if (!this.cascadeState) return;\n this.cascadeState.visitedChainIndexes.add(index);\n }\n\n clearCascadeState(): void {\n this.cascadeState = null;\n this.suppressNextStartTurn = false;\n }\n\n getSnapshot(): CascadeState | null {\n if (!this.cascadeState) return null;\n return {\n prompt: this.cascadeState.prompt,\n attemptedAccounts: new Set(this.cascadeState.attemptedAccounts),\n visitedChainIndexes: new Set(this.cascadeState.visitedChainIndexes),\n };\n }\n}\n"],"mappings":"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","names":["fs","randomBytes","dirname","join","join","homedir","v","content","getConfigDir","join","homedir","join","getConfigDir","randomBytes","fs","dirname","fs","randomBytes","dirname","join","v","fs","dirname","join","v","join","getConfigDir","fs","dirname","fs","dirname","sleep","getStoragePath","join","getConfigDir","randomBytes","fs","dirname","formatWaitTime","sleep","showToast","getAccountLabel","getConfig","debugLog","getConfig","formatWaitTime","getAccountLabel","showToast","fs","join","join","getConfigDir","fs","v","fs","randomBytes","dirname","join","v","FILE_MODE","join","getConfigDir","buildTempPath","randomBytes","fs","dirname","writeAtomicText"]}
1
+ {"version":3,"sources":["../src/account-manager.ts","../src/claims.ts","../src/utils.ts","../src/config.ts","../src/types.ts","../src/account-store.ts","../src/storage.ts","../src/constants.ts","../src/file-lock.ts","../src/executor.ts","../src/proactive-refresh.ts","../src/rate-limit.ts","../src/auth-migration.ts","../src/ui/ansi.ts","../src/ui/select.ts","../src/ui/confirm.ts","../src/adapters/anthropic.ts","../src/adapters/openai.ts","../src/pool-types.ts","../src/pool-config-store.ts","../src/pool-manager.ts","../src/cascade-state.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { readClaims, writeClaim, isClaimedByOther, type ClaimsMap } from \"./claims\";\nimport { getConfig } from \"./config\";\nimport { getClearedOAuthBody } from \"./utils\";\nimport type { AccountStore } from \"./account-store\";\nimport type {\n ManagedAccount,\n OAuthCredentials,\n PluginClient,\n StoredAccount,\n TokenRefreshResult,\n UsageLimits,\n} from \"./types\";\n\nconst STARTUP_REFRESH_CONCURRENCY = 3;\nconst RECENT_429_COOLDOWN_MS = 30_000;\nconst HYBRID_SWITCH_MARGIN = 40;\n\nexport interface ProfileData {\n email?: string;\n planTier: string;\n}\n\nexport interface RuntimeFactoryLike {\n invalidate(uuid: string): void;\n}\n\nexport interface AccountManagerDependencies {\n providerAuthId: string;\n isTokenExpired: (account: Pick<ManagedAccount, \"accessToken\" | \"expiresAt\">) => boolean;\n refreshToken: (\n currentRefreshToken: string,\n accountId: string,\n client: PluginClient,\n ) => Promise<TokenRefreshResult>;\n}\n\nexport interface AccountManagerInstance {\n initialize(currentAuth: OAuthCredentials, client?: PluginClient): Promise<void>;\n refresh(): Promise<void>;\n getAccountCount(): number;\n getAccounts(): ManagedAccount[];\n getActiveAccount(): ManagedAccount | null;\n setClient(client: PluginClient): void;\n setRuntimeFactory(factory: RuntimeFactoryLike): void;\n hasAnyUsableAccount(): boolean;\n isRateLimited(account: ManagedAccount): boolean;\n clearExpiredRateLimits(): void;\n getMinWaitTime(): number;\n selectAccount(): Promise<ManagedAccount | null>;\n markRateLimited(uuid: string, backoffMs?: number): Promise<void>;\n markRevoked(uuid: string): Promise<void>;\n markSuccess(uuid: string): Promise<void>;\n markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void>;\n applyUsageCache(uuid: string, usage: UsageLimits): Promise<void>;\n applyProfileCache(uuid: string, profile: ProfileData): Promise<void>;\n ensureValidToken(uuid: string, client: PluginClient): Promise<TokenRefreshResult>;\n validateNonActiveTokens(client: PluginClient): Promise<void>;\n removeAccount(index: number): Promise<boolean>;\n clearAllAccounts(): Promise<void>;\n addAccount(auth: OAuthCredentials, email?: string): Promise<void>;\n toggleEnabled(uuid: string): Promise<void>;\n replaceAccountCredentials(uuid: string, auth: OAuthCredentials): Promise<void>;\n retryAuth(uuid: string, client: PluginClient): Promise<TokenRefreshResult>;\n}\n\nexport interface AccountManagerClass {\n new (store: AccountStore): AccountManagerInstance;\n create(store: AccountStore, currentAuth: OAuthCredentials, client?: PluginClient): Promise<AccountManagerInstance>;\n}\n\nexport function createAccountManagerForProvider(dependencies: AccountManagerDependencies): AccountManagerClass {\n const {\n providerAuthId,\n isTokenExpired,\n refreshToken,\n } = dependencies;\n\n return class AccountManager {\n private cached: ManagedAccount[] = [];\n private activeAccountUuid?: string;\n private client: PluginClient | null = null;\n private runtimeFactory: RuntimeFactoryLike | null = null;\n private roundRobinCursor = 0;\n private last429Map = new Map<string, number>();\n\n constructor(private store: AccountStore) {}\n\n static async create(\n store: AccountStore,\n currentAuth: OAuthCredentials,\n client?: PluginClient,\n ): Promise<AccountManager> {\n const manager = new AccountManager(store);\n await manager.initialize(currentAuth, client);\n return manager;\n }\n\n async initialize(currentAuth: OAuthCredentials, client?: PluginClient): Promise<void> {\n if (client) this.client = client;\n\n const storage = await this.store.load();\n if (storage.accounts.length > 0) {\n this.cached = storage.accounts.map((account, index) => this.toManagedAccount(account, index));\n this.activeAccountUuid = storage.activeAccountUuid;\n if (!this.getActiveAccount() && this.cached.length > 0) {\n this.activeAccountUuid = this.cached[0]!.uuid;\n }\n return;\n }\n\n if (currentAuth.refresh) {\n const newAccount = this.createNewAccount(currentAuth, Date.now());\n await this.store.addAccount(newAccount);\n await this.store.setActiveUuid(newAccount.uuid);\n this.cached = [this.toManagedAccount(newAccount, 0)];\n this.activeAccountUuid = newAccount.uuid;\n }\n }\n\n async refresh(): Promise<void> {\n const storage = await this.store.load();\n this.cached = storage.accounts.map((account, index) => this.toManagedAccount(account, index));\n if (storage.activeAccountUuid) {\n this.activeAccountUuid = storage.activeAccountUuid;\n }\n }\n\n private toManagedAccount(storedAccount: StoredAccount, index: number): ManagedAccount {\n return {\n index,\n uuid: storedAccount.uuid,\n accountId: storedAccount.accountId,\n label: storedAccount.label,\n email: storedAccount.email,\n planTier: storedAccount.planTier,\n refreshToken: storedAccount.refreshToken,\n accessToken: storedAccount.accessToken,\n expiresAt: storedAccount.expiresAt,\n addedAt: storedAccount.addedAt,\n lastUsed: storedAccount.lastUsed,\n enabled: storedAccount.enabled,\n rateLimitResetAt: storedAccount.rateLimitResetAt,\n cachedUsage: storedAccount.cachedUsage,\n cachedUsageAt: storedAccount.cachedUsageAt,\n consecutiveAuthFailures: storedAccount.consecutiveAuthFailures,\n isAuthDisabled: storedAccount.isAuthDisabled,\n authDisabledReason: storedAccount.authDisabledReason,\n last429At: storedAccount.uuid ? this.last429Map.get(storedAccount.uuid) : undefined,\n };\n }\n\n private createNewAccount(auth: OAuthCredentials, now: number): StoredAccount {\n return {\n uuid: randomUUID(),\n refreshToken: auth.refresh,\n accessToken: auth.access,\n expiresAt: auth.expires,\n addedAt: now,\n lastUsed: now,\n enabled: true,\n planTier: \"\",\n consecutiveAuthFailures: 0,\n isAuthDisabled: false,\n };\n }\n\n getAccountCount(): number {\n return this.getEligibleAccounts().length;\n }\n\n getAccounts(): ManagedAccount[] {\n return [...this.cached];\n }\n\n getActiveAccount(): ManagedAccount | null {\n if (this.activeAccountUuid) {\n return this.cached.find((account) => account.uuid === this.activeAccountUuid) ?? null;\n }\n return this.cached[0] ?? null;\n }\n\n setClient(client: PluginClient): void {\n this.client = client;\n }\n\n setRuntimeFactory(factory: RuntimeFactoryLike): void {\n this.runtimeFactory = factory;\n }\n\n private getEligibleAccounts(): ManagedAccount[] {\n return this.cached.filter((account) => account.uuid && account.enabled && !account.isAuthDisabled);\n }\n\n private exceedsSoftQuota(account: ManagedAccount): boolean {\n const threshold = getConfig().soft_quota_threshold_percent;\n if (threshold >= 100) return false;\n\n const usage = account.cachedUsage;\n if (!usage) return false;\n\n const tiers = [usage.five_hour, usage.seven_day];\n return tiers.some((tier) => tier != null && tier.utilization >= threshold);\n }\n\n hasAnyUsableAccount(): boolean {\n return this.getEligibleAccounts().length > 0;\n }\n\n isRateLimited(account: ManagedAccount): boolean {\n if (account.rateLimitResetAt && Date.now() < account.rateLimitResetAt) {\n return true;\n }\n return this.isUsageExhausted(account);\n }\n\n private isUsageExhausted(account: ManagedAccount): boolean {\n const usage = account.cachedUsage;\n if (!usage) return false;\n\n const now = Date.now();\n const tiers = [usage.five_hour, usage.seven_day];\n return tiers.some((tier) =>\n tier != null\n && tier.utilization >= 100\n && tier.resets_at != null\n && Date.parse(tier.resets_at) > now,\n );\n }\n\n clearExpiredRateLimits(): void {\n const now = Date.now();\n for (const account of this.cached) {\n if (account.rateLimitResetAt && now >= account.rateLimitResetAt) {\n account.rateLimitResetAt = undefined;\n }\n }\n }\n\n getMinWaitTime(): number {\n const eligible = this.getEligibleAccounts();\n const available = eligible.filter((account) => !this.isRateLimited(account));\n if (available.length > 0) return 0;\n\n const now = Date.now();\n const waits: number[] = [];\n\n for (const account of eligible) {\n if (account.rateLimitResetAt) {\n const ms = account.rateLimitResetAt - now;\n if (ms > 0) waits.push(ms);\n }\n\n const usageResetMs = this.getUsageResetMs(account);\n if (usageResetMs !== null && usageResetMs > 0) {\n waits.push(usageResetMs);\n }\n }\n\n return waits.length > 0 ? Math.min(...waits) : 0;\n }\n\n private getUsageResetMs(account: ManagedAccount): number | null {\n const usage = account.cachedUsage;\n if (!usage) return null;\n\n const now = Date.now();\n const candidates: number[] = [];\n const tiers = [usage.five_hour, usage.seven_day];\n\n for (const tier of tiers) {\n if (tier != null && tier.utilization >= 100 && tier.resets_at != null) {\n const ms = Date.parse(tier.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n }\n\n return candidates.length > 0 ? Math.min(...candidates) : null;\n }\n\n async selectAccount(): Promise<ManagedAccount | null> {\n await this.refresh();\n this.clearExpiredRateLimits();\n\n const eligible = this.getEligibleAccounts();\n if (eligible.length === 0) return null;\n\n const config = getConfig();\n const claims = config.cross_process_claims ? await readClaims() : {};\n\n const strategy = config.account_selection_strategy;\n let selected: ManagedAccount | null;\n switch (strategy) {\n case \"round-robin\":\n selected = this.selectRoundRobin(eligible, claims);\n break;\n case \"hybrid\":\n selected = this.selectHybrid(eligible, claims);\n break;\n case \"sticky\":\n default:\n selected = this.selectSticky(eligible, claims);\n break;\n }\n\n if (selected?.uuid) {\n this.activeAccountUuid = selected.uuid;\n this.store.setActiveUuid(selected.uuid).catch(() => {});\n }\n\n if (config.cross_process_claims && selected?.uuid) {\n writeClaim(selected.uuid).catch(() => {});\n }\n\n return selected;\n }\n\n private isUsable(account: ManagedAccount): boolean {\n return !this.isRateLimited(account)\n && !this.isInRecentCooldown(account)\n && !this.exceedsSoftQuota(account);\n }\n\n private isInRecentCooldown(account: ManagedAccount): boolean {\n if (!account.last429At) return false;\n return Date.now() - account.last429At < RECENT_429_COOLDOWN_MS;\n }\n\n private fallbackNotRateLimited(eligible: ManagedAccount[]): ManagedAccount | null {\n const account = eligible.find((candidate) => !this.isRateLimited(candidate));\n if (account) {\n this.activateAccount(account);\n return account;\n }\n return null;\n }\n\n private selectSticky(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n const current = this.getActiveAccount();\n if (current?.enabled && !current.isAuthDisabled && this.isUsable(current)) {\n this.activateAccount(current);\n return current;\n }\n\n const unclaimed = eligible.find(\n (account) => this.isUsable(account) && !isClaimedByOther(claims, account.uuid),\n );\n if (unclaimed) {\n this.activateAccount(unclaimed);\n return unclaimed;\n }\n\n const available = eligible.find((account) => this.isUsable(account));\n if (available) {\n this.activateAccount(available);\n return available;\n }\n\n return this.fallbackNotRateLimited(eligible);\n }\n\n private selectRoundRobin(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n for (let i = 0; i < eligible.length; i++) {\n const index = (this.roundRobinCursor + i) % eligible.length;\n const account = eligible[index]!;\n if (this.isUsable(account) && !isClaimedByOther(claims, account.uuid)) {\n this.roundRobinCursor = (index + 1) % eligible.length;\n this.activateAccount(account);\n return account;\n }\n }\n\n for (let i = 0; i < eligible.length; i++) {\n const index = (this.roundRobinCursor + i) % eligible.length;\n const account = eligible[index]!;\n if (this.isUsable(account)) {\n this.roundRobinCursor = (index + 1) % eligible.length;\n this.activateAccount(account);\n return account;\n }\n }\n\n return this.fallbackNotRateLimited(eligible);\n }\n\n private selectHybrid(eligible: ManagedAccount[], claims: ClaimsMap): ManagedAccount | null {\n const usable = eligible.filter((account) => this.isUsable(account));\n const pool = usable.length > 0\n ? usable\n : eligible.filter((account) => !this.isRateLimited(account));\n\n if (pool.length === 0) return null;\n\n const activeUuid = this.activeAccountUuid;\n\n let best = pool[0]!;\n let bestScore = this.calculateHybridScore(best, best.uuid === activeUuid, claims);\n\n for (let i = 1; i < pool.length; i++) {\n const account = pool[i]!;\n const score = this.calculateHybridScore(account, account.uuid === activeUuid, claims);\n if (score > bestScore) {\n best = account;\n bestScore = score;\n }\n }\n\n const current = pool.find((account) => account.uuid === activeUuid);\n if (current && current !== best) {\n const currentScore = this.calculateHybridScore(current, true, claims);\n const bestWithoutStickiness = this.calculateHybridScore(best, false, claims);\n if (bestWithoutStickiness <= currentScore + HYBRID_SWITCH_MARGIN) {\n this.activateAccount(current);\n return current;\n }\n }\n\n this.activateAccount(best);\n return best;\n }\n\n private calculateHybridScore(account: ManagedAccount, isActive: boolean, claims: ClaimsMap): number {\n const maxUtilization = Math.min(100, Math.max(0, this.getMaxUtilization(account)));\n const usageScore = ((100 - maxUtilization) / 100) * 450;\n\n const maxFailures = Math.max(1, getConfig().max_consecutive_auth_failures);\n const healthScore = Math.max(0, ((maxFailures - account.consecutiveAuthFailures) / maxFailures) * 250);\n\n const secondsSinceUsed = (Date.now() - account.lastUsed) / 1000;\n const freshnessScore = (Math.min(secondsSinceUsed, 900) / 900) * 60;\n\n const stickinessBonus = isActive ? 120 : 0;\n const claimPenalty = isClaimedByOther(claims, account.uuid) ? -200 : 0;\n\n return usageScore + healthScore + freshnessScore + stickinessBonus + claimPenalty;\n }\n\n private getMaxUtilization(account: ManagedAccount): number {\n const usage = account.cachedUsage;\n if (!usage) return 65;\n\n const tiers = [usage.five_hour, usage.seven_day];\n const utilizations = tiers\n .filter((tier): tier is NonNullable<typeof tier> => tier != null)\n .map((tier) => tier.utilization);\n\n return utilizations.length > 0 ? Math.max(...utilizations) : 65;\n }\n\n private activateAccount(account: ManagedAccount): void {\n this.activeAccountUuid = account.uuid;\n account.lastUsed = Date.now();\n }\n\n async markRateLimited(uuid: string, backoffMs?: number): Promise<void> {\n const effectiveBackoff = backoffMs ?? getConfig().rate_limit_min_backoff_ms;\n this.last429Map.set(uuid, Date.now());\n await this.store.mutateAccount(uuid, (account) => {\n account.rateLimitResetAt = Date.now() + effectiveBackoff;\n });\n }\n\n async markRevoked(uuid: string): Promise<void> {\n await this.removeAccountByUuid(uuid);\n }\n\n async markSuccess(uuid: string): Promise<void> {\n this.last429Map.delete(uuid);\n await this.store.mutateAccount(uuid, (account) => {\n account.rateLimitResetAt = undefined;\n account.consecutiveAuthFailures = 0;\n account.lastUsed = Date.now();\n });\n }\n\n private syncToOpenCode(account: Pick<StoredAccount, \"refreshToken\" | \"accessToken\" | \"expiresAt\">): void {\n if (!this.client || !account.accessToken || !account.expiresAt) return;\n this.client.auth.set({\n path: { id: providerAuthId },\n body: {\n type: \"oauth\",\n refresh: account.refreshToken,\n access: account.accessToken,\n expires: account.expiresAt,\n },\n }).catch(() => {});\n }\n\n private async clearOpenCodeAuthIfNoAccountsRemain(): Promise<void> {\n if (!this.client) return;\n\n const storage = await this.store.load();\n if (storage.accounts.length > 0) return;\n\n await this.client.auth\n .set({\n path: { id: providerAuthId },\n body: getClearedOAuthBody(),\n })\n .catch(() => {});\n }\n\n private async removeAccountByUuid(uuid: string): Promise<void> {\n const removed = await this.store.removeAccount(uuid);\n if (!removed) return;\n\n this.last429Map.delete(uuid);\n this.runtimeFactory?.invalidate(uuid);\n await this.refresh();\n await this.clearOpenCodeAuthIfNoAccountsRemain();\n }\n\n async markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void> {\n if (!result.ok && result.permanent) {\n await this.removeAccountByUuid(uuid);\n return;\n }\n\n await this.store.mutateStorage((storage) => {\n const account = storage.accounts.find((entry) => entry.uuid === uuid);\n if (!account) return;\n\n account.consecutiveAuthFailures = (account.consecutiveAuthFailures ?? 0) + 1;\n const maxFailures = getConfig().max_consecutive_auth_failures;\n const usableCount = storage.accounts.filter(\n (entry) => entry.enabled && !entry.isAuthDisabled && entry.uuid !== uuid,\n ).length;\n\n if (account.consecutiveAuthFailures >= maxFailures && usableCount > 0) {\n account.isAuthDisabled = true;\n account.authDisabledReason = `${maxFailures} consecutive auth failures`;\n }\n });\n }\n\n async applyUsageCache(uuid: string, usage: UsageLimits): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n const now = Date.now();\n const exhaustedTierResetTimes = [usage.five_hour, usage.seven_day]\n .flatMap((tier) => {\n if (tier == null || tier.utilization < 100 || tier.resets_at == null) {\n return [];\n }\n return [Date.parse(tier.resets_at)];\n })\n .filter((resetAt) => Number.isFinite(resetAt) && resetAt > now);\n\n account.cachedUsage = usage;\n account.cachedUsageAt = Date.now();\n account.rateLimitResetAt = exhaustedTierResetTimes.length > 0\n ? Math.min(...exhaustedTierResetTimes)\n : undefined;\n });\n }\n\n async applyProfileCache(uuid: string, profile: ProfileData): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n account.email = profile.email ?? account.email;\n account.planTier = profile.planTier;\n });\n }\n\n async ensureValidToken(uuid: string, client: PluginClient): Promise<TokenRefreshResult> {\n const credentials = await this.store.readCredentials(uuid);\n if (!credentials) return { ok: false, permanent: true };\n\n if (credentials.accessToken && credentials.expiresAt && !isTokenExpired(credentials)) {\n return {\n ok: true,\n patch: { accessToken: credentials.accessToken, expiresAt: credentials.expiresAt },\n };\n }\n\n const result = await refreshToken(credentials.refreshToken, uuid, client);\n if (!result.ok) return result;\n\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.accessToken = result.patch.accessToken;\n account.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) account.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid && result.patch.uuid !== uuid) account.uuid = result.patch.uuid;\n if (result.patch.accountId) account.accountId = result.patch.accountId;\n if (result.patch.email) account.email = result.patch.email;\n account.consecutiveAuthFailures = 0;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n });\n\n if (result.patch.uuid && result.patch.uuid !== uuid && this.activeAccountUuid === uuid) {\n this.activeAccountUuid = result.patch.uuid;\n this.store.setActiveUuid(result.patch.uuid).catch(() => {});\n }\n\n if (updated && (uuid === this.activeAccountUuid || updated.uuid === this.activeAccountUuid)) {\n this.syncToOpenCode(updated);\n }\n\n return result;\n }\n\n async validateNonActiveTokens(client: PluginClient): Promise<void> {\n await this.refresh();\n\n const activeUuid = this.activeAccountUuid;\n const eligible = this.cached.filter(\n (account) => account.enabled && !account.isAuthDisabled && account.uuid && account.uuid !== activeUuid,\n );\n\n for (let i = 0; i < eligible.length; i += STARTUP_REFRESH_CONCURRENCY) {\n const batch = eligible.slice(i, i + STARTUP_REFRESH_CONCURRENCY);\n await Promise.all(\n batch.map(async (account) => {\n if (!account.uuid || !isTokenExpired(account)) return;\n\n const result = await this.ensureValidToken(account.uuid, client);\n if (!result.ok) {\n await this.markAuthFailure(account.uuid, result);\n }\n }),\n );\n }\n }\n\n async removeAccount(index: number): Promise<boolean> {\n const account = this.cached[index];\n if (!account?.uuid) return false;\n\n const removed = await this.store.removeAccount(account.uuid);\n if (removed) {\n await this.refresh();\n }\n return removed;\n }\n\n async clearAllAccounts(): Promise<void> {\n await this.store.clear();\n this.cached = [];\n this.activeAccountUuid = undefined;\n }\n\n async addAccount(auth: OAuthCredentials, email?: string): Promise<void> {\n if (!auth.refresh) return;\n\n const existingByToken = this.cached.find((account) => account.refreshToken === auth.refresh);\n if (existingByToken) return;\n\n if (email) {\n const existingByEmail = this.cached.find(\n (account) => account.email && account.email === email,\n );\n if (existingByEmail?.uuid) {\n await this.replaceAccountCredentials(existingByEmail.uuid, auth);\n return;\n }\n }\n\n const newAccount = this.createNewAccount(auth, Date.now());\n if (email) newAccount.email = email;\n await this.store.addAccount(newAccount);\n this.activeAccountUuid = newAccount.uuid;\n await this.store.setActiveUuid(newAccount.uuid);\n await this.refresh();\n }\n\n async toggleEnabled(uuid: string): Promise<void> {\n await this.store.mutateAccount(uuid, (account) => {\n account.enabled = !(account.enabled ?? true);\n if (account.enabled) {\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n account.consecutiveAuthFailures = 0;\n }\n });\n }\n\n async replaceAccountCredentials(uuid: string, auth: OAuthCredentials): Promise<void> {\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.refreshToken = auth.refresh;\n account.accessToken = auth.access;\n account.expiresAt = auth.expires;\n account.lastUsed = Date.now();\n account.enabled = true;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n account.consecutiveAuthFailures = 0;\n account.rateLimitResetAt = undefined;\n });\n this.runtimeFactory?.invalidate(uuid);\n\n if (updated && uuid === this.activeAccountUuid) {\n this.syncToOpenCode(updated);\n }\n }\n\n async retryAuth(uuid: string, client: PluginClient): Promise<TokenRefreshResult> {\n await this.store.mutateAccount(uuid, (account) => {\n account.consecutiveAuthFailures = 0;\n account.isAuthDisabled = false;\n account.authDisabledReason = undefined;\n });\n this.runtimeFactory?.invalidate(uuid);\n\n const credentials = await this.store.readCredentials(uuid);\n if (!credentials) return { ok: false, permanent: true };\n\n const result = await refreshToken(credentials.refreshToken, uuid, client);\n if (result.ok) {\n const updated = await this.store.mutateAccount(uuid, (account) => {\n account.accessToken = result.patch.accessToken;\n account.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) account.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid) account.uuid = result.patch.uuid;\n if (result.patch.accountId) account.accountId = result.patch.accountId;\n if (result.patch.email) account.email = result.patch.email;\n account.enabled = true;\n account.consecutiveAuthFailures = 0;\n });\n this.runtimeFactory?.invalidate(uuid);\n if (result.patch.uuid) {\n this.runtimeFactory?.invalidate(result.patch.uuid);\n }\n\n const nextUuid = result.patch.uuid ?? uuid;\n if (this.activeAccountUuid === uuid && result.patch.uuid && result.patch.uuid !== uuid) {\n this.activeAccountUuid = result.patch.uuid;\n await this.store.setActiveUuid(result.patch.uuid);\n }\n\n if (updated && (uuid === this.activeAccountUuid || nextUuid === this.activeAccountUuid)) {\n const freshCredentials = await this.store.readCredentials(nextUuid);\n if (freshCredentials) {\n this.syncToOpenCode({\n refreshToken: freshCredentials.refreshToken,\n accessToken: freshCredentials.accessToken,\n expiresAt: freshCredentials.expiresAt,\n });\n }\n }\n } else {\n await this.markAuthFailure(uuid, result);\n this.runtimeFactory?.invalidate(uuid);\n }\n\n return result;\n }\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { getConfigDir } from \"./utils\";\n\nconst CLAIMS_FILENAME = \"multiauth-claims.json\";\nconst CLAIM_EXPIRY_MS = 60_000;\n\nexport type ClaimsMap = Record<string, { pid: number; at: number }>;\n\nfunction getClaimsPath(): string {\n return join(getConfigDir(), CLAIMS_FILENAME);\n}\n\nfunction isClaimShape(value: unknown): value is { pid: number; at: number } {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const claim = value as Record<string, unknown>;\n return (\n typeof claim.pid === \"number\"\n && Number.isInteger(claim.pid)\n && claim.pid > 0\n && typeof claim.at === \"number\"\n && Number.isFinite(claim.at)\n );\n}\n\nfunction parseClaims(raw: string): ClaimsMap {\n let parsed: unknown;\n\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n\n const claims: ClaimsMap = {};\n for (const [accountId, claim] of Object.entries(parsed)) {\n if (isClaimShape(claim)) {\n claims[accountId] = claim;\n }\n }\n\n return claims;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction cleanClaims(\n claims: ClaimsMap,\n now: number,\n): { cleaned: ClaimsMap; changed: boolean } {\n const cleaned: ClaimsMap = {};\n let changed = false;\n\n for (const [accountId, claim] of Object.entries(claims)) {\n const expiredByTime = now - claim.at > CLAIM_EXPIRY_MS;\n const zombieClaim = !isProcessAlive(claim.pid);\n if (expiredByTime || zombieClaim) {\n changed = true;\n continue;\n }\n\n cleaned[accountId] = claim;\n }\n\n return { cleaned, changed };\n}\n\nasync function writeClaimsFile(claims: ClaimsMap): Promise<void> {\n const path = getClaimsPath();\n const tempPath = `${path}.${randomBytes(6).toString(\"hex\")}.tmp`;\n await fs.mkdir(dirname(path), { recursive: true });\n\n try {\n await fs.writeFile(tempPath, JSON.stringify(claims, null, 2), { encoding: \"utf-8\", mode: 0o600 });\n await fs.rename(tempPath, path);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {\n // ignore cleanup failure\n }\n throw error;\n }\n}\n\nexport async function readClaims(): Promise<ClaimsMap> {\n try {\n const data = await fs.readFile(getClaimsPath(), \"utf-8\");\n const parsed = parseClaims(data);\n const now = Date.now();\n const { cleaned, changed } = cleanClaims(parsed, now);\n\n if (changed) {\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort cleanup\n }\n }\n\n return cleaned;\n } catch {\n return {};\n }\n}\n\n// Best-effort read-modify-write: not atomic across processes, but acceptable\n// because stale/duplicate claims self-expire via CLAIM_EXPIRY_MS and zombie detection.\nexport async function writeClaim(accountId: string): Promise<void> {\n const now = Date.now();\n const claims = await readClaims();\n const { cleaned } = cleanClaims(claims, now);\n\n cleaned[accountId] = { pid: process.pid, at: now };\n\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort claim update\n }\n}\n\n// Best-effort read-modify-write: same rationale as writeClaim above.\nexport async function releaseClaim(accountId: string): Promise<void> {\n const now = Date.now();\n const claims = await readClaims();\n const { cleaned } = cleanClaims(claims, now);\n\n const currentClaim = cleaned[accountId];\n if (!currentClaim || currentClaim.pid !== process.pid) {\n return;\n }\n\n delete cleaned[accountId];\n\n try {\n await writeClaimsFile(cleaned);\n } catch {\n // best-effort release\n }\n}\n\nexport function isClaimedByOther(\n claims: ClaimsMap,\n accountId: string | undefined,\n): boolean {\n if (!accountId) return false;\n const claim = claims[accountId];\n if (!claim) return false;\n if (Date.now() - claim.at > CLAIM_EXPIRY_MS) return false;\n if (!isProcessAlive(claim.pid)) return false;\n return claim.pid !== process.pid;\n}\n","import { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { getConfig } from \"./config\";\nimport type { ManagedAccount, PluginClient } from \"./types\";\n\n// ─── Shared Filesystem Utilities ─────────────────────────────────\n\nexport function getConfigDir(): string {\n return process.env.OPENCODE_CONFIG_DIR\n || join(process.env.XDG_CONFIG_HOME || join(homedir(), \".config\"), \"opencode\");\n}\n\nexport function getErrorCode(error: unknown): string | undefined {\n if (typeof error !== \"object\" || error === null || !(\"code\" in error)) {\n return undefined;\n }\n const code = (error as { code?: unknown }).code;\n return typeof code === \"string\" ? code : undefined;\n}\n\n// ─── Formatting & Display ────────────────────────────────────────\n\nexport function formatWaitTime(ms: number): string {\n const totalSeconds = Math.ceil(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n\n const days = Math.floor(totalSeconds / 86_400);\n const hours = Math.floor((totalSeconds % 86_400) / 3_600);\n const minutes = Math.floor((totalSeconds % 3_600) / 60);\n const seconds = totalSeconds % 60;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0 && days === 0) parts.push(`${seconds}s`);\n\n return parts.join(\" \") || \"0s\";\n}\n\nexport function getAccountLabel(account: ManagedAccount): string {\n if (account.label) return account.label;\n if (account.email) return account.email;\n if (account.uuid) return `Account (${account.uuid.slice(0, 8)})`;\n return `Account ${account.index + 1}`;\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function showToast(\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n): Promise<void> {\n if (getConfig().quiet_mode) return;\n try {\n await client.tui.showToast({ body: { message, variant } });\n } catch {\n // TUI may not be available\n }\n}\n\nexport function debugLog(\n client: PluginClient,\n message: string,\n extra?: Record<string, unknown>,\n): void {\n if (!getConfig().debug) return;\n client.app.log({\n body: { service: \"claude-multiauth\", level: \"debug\", message, extra },\n }).catch(() => {});\n}\n\nexport function createMinimalClient(): PluginClient {\n return {\n auth: {\n set: async () => {},\n },\n tui: {\n showToast: async () => {},\n },\n app: {\n log: async () => {},\n },\n };\n}\n\n// ─── OAuth Helpers ───────────────────────────────────────────────\n\nexport function getClearedOAuthBody() {\n return {\n type: \"oauth\" as const,\n refresh: \"\",\n access: \"\",\n expires: 0,\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport * as v from \"valibot\";\nimport { PluginConfigSchema } from \"./types\";\nimport type { PluginConfig } from \"./types\";\n\nexport type CoreConfig = Pick<PluginConfig, \"quiet_mode\" | \"debug\">;\n\nconst DEFAULT_CONFIG_FILENAME = \"multiauth-config.json\";\nconst DEFAULT_CONFIG: PluginConfig = v.parse(PluginConfigSchema, {});\n\nlet configFilename = DEFAULT_CONFIG_FILENAME;\nlet cachedConfig: PluginConfig | null = null;\nlet externalConfigGetter: (() => PluginConfig) | null = null;\n\nfunction getConfigDir(): string {\n return process.env.OPENCODE_CONFIG_DIR\n || join(process.env.XDG_CONFIG_HOME || join(homedir(), \".config\"), \"opencode\");\n}\n\nfunction getConfigPath(): string {\n return join(getConfigDir(), configFilename);\n}\n\nfunction parseConfig(raw: unknown): PluginConfig {\n const result = v.safeParse(PluginConfigSchema, raw);\n return result.success ? result.output : DEFAULT_CONFIG;\n}\n\nexport function initCoreConfig(filename: string): void {\n configFilename = filename || DEFAULT_CONFIG_FILENAME;\n cachedConfig = null;\n}\n\nexport async function loadConfig(): Promise<PluginConfig> {\n if (cachedConfig) return cachedConfig;\n\n const path = getConfigPath();\n try {\n const content = await fs.readFile(path, \"utf-8\");\n cachedConfig = parseConfig(JSON.parse(content));\n } catch {\n cachedConfig = DEFAULT_CONFIG;\n }\n\n return cachedConfig;\n}\n\nexport function getConfig(): PluginConfig {\n if (cachedConfig) return cachedConfig;\n\n if (externalConfigGetter && externalConfigGetter !== getConfig) {\n try {\n return parseConfig(externalConfigGetter());\n } catch {\n return DEFAULT_CONFIG;\n }\n }\n\n return DEFAULT_CONFIG;\n}\n\nexport function resetConfigCache(): void {\n cachedConfig = null;\n}\n\nexport function setConfigGetter(getter: () => PluginConfig): void {\n if (getter === getConfig) {\n return;\n }\n externalConfigGetter = getter;\n}\n\nexport async function updateConfigField<K extends keyof PluginConfig>(\n key: K,\n value: PluginConfig[K],\n): Promise<void> {\n const path = getConfigPath();\n\n let existing: Record<string, unknown> = {};\n try {\n const content = await fs.readFile(path, \"utf-8\");\n existing = JSON.parse(content) as Record<string, unknown>;\n } catch {}\n\n existing[key] = value;\n\n await fs.mkdir(dirname(path), { recursive: true });\n const content = `${JSON.stringify(existing, null, 2)}\\n`;\n const tempPath = `${path}.${randomBytes(8).toString(\"hex\")}.tmp`;\n try {\n await fs.writeFile(tempPath, content, \"utf-8\");\n await fs.rename(tempPath, path);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n\n cachedConfig = null;\n await loadConfig();\n}\n","import * as v from \"valibot\";\n\nexport const OAuthCredentialsSchema = v.object({\n type: v.literal(\"oauth\"),\n refresh: v.string(),\n access: v.string(),\n expires: v.number(),\n});\n\nexport const UsageLimitEntrySchema = v.object({\n utilization: v.number(),\n resets_at: v.nullable(v.string()),\n});\n\nexport const UsageLimitsSchema = v.object({\n five_hour: v.optional(v.nullable(UsageLimitEntrySchema), null),\n seven_day: v.optional(v.nullable(UsageLimitEntrySchema), null),\n seven_day_sonnet: v.optional(v.nullable(UsageLimitEntrySchema), null),\n});\n\nexport const CredentialRefreshPatchSchema = v.object({\n accessToken: v.string(),\n expiresAt: v.number(),\n refreshToken: v.optional(v.string()),\n uuid: v.optional(v.string()),\n accountId: v.optional(v.string()),\n email: v.optional(v.string()),\n});\n\nexport const StoredAccountSchema = v.object({\n uuid: v.optional(v.string()),\n accountId: v.optional(v.string()),\n label: v.optional(v.string()),\n email: v.optional(v.string()),\n planTier: v.optional(v.string(), \"\"),\n refreshToken: v.string(),\n accessToken: v.optional(v.string()),\n expiresAt: v.optional(v.number()),\n addedAt: v.number(),\n lastUsed: v.number(),\n enabled: v.optional(v.boolean(), true),\n rateLimitResetAt: v.optional(v.number()),\n cachedUsage: v.optional(UsageLimitsSchema),\n cachedUsageAt: v.optional(v.number()),\n consecutiveAuthFailures: v.optional(v.number(), 0),\n isAuthDisabled: v.optional(v.boolean(), false),\n authDisabledReason: v.optional(v.string()),\n});\n\nexport const AccountStorageSchema = v.object({\n version: v.literal(1),\n accounts: v.optional(v.array(StoredAccountSchema), []),\n activeAccountUuid: v.optional(v.string()),\n});\n\nexport const AccountSelectionStrategySchema = v.picklist([\"sticky\", \"round-robin\", \"hybrid\"]);\n\nexport const PluginConfigSchema = v.object({\n account_selection_strategy: v.optional(AccountSelectionStrategySchema, \"sticky\"),\n cross_process_claims: v.optional(v.boolean(), true),\n soft_quota_threshold_percent: v.optional(v.pipe(v.number(), v.minValue(0), v.maxValue(100)), 100),\n rate_limit_min_backoff_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 30_000),\n default_retry_after_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 60_000),\n max_consecutive_auth_failures: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1)), 3),\n token_failure_backoff_ms: v.optional(v.pipe(v.number(), v.minValue(0)), 30_000),\n proactive_refresh: v.optional(v.boolean(), true),\n proactive_refresh_buffer_seconds: v.optional(v.pipe(v.number(), v.minValue(60)), 1800),\n proactive_refresh_interval_seconds: v.optional(v.pipe(v.number(), v.minValue(30)), 300),\n quiet_mode: v.optional(v.boolean(), false),\n debug: v.optional(v.boolean(), false),\n});\n\nexport type OAuthCredentials = v.InferOutput<typeof OAuthCredentialsSchema>;\nexport type UsageLimitEntry = v.InferOutput<typeof UsageLimitEntrySchema>;\nexport type UsageLimits = v.InferOutput<typeof UsageLimitsSchema>;\nexport type CredentialRefreshPatch = v.InferOutput<typeof CredentialRefreshPatchSchema>;\nexport type StoredAccount = v.InferOutput<typeof StoredAccountSchema>;\nexport type AccountStorage = v.InferOutput<typeof AccountStorageSchema>;\nexport type AccountSelectionStrategy = v.InferOutput<typeof AccountSelectionStrategySchema>;\nexport type PluginConfig = v.InferOutput<typeof PluginConfigSchema>;\n\nexport type TokenRefreshResult =\n | { ok: true; patch: CredentialRefreshPatch }\n | { ok: false; permanent: boolean; status?: number };\n\nexport class TokenRefreshError extends Error {\n readonly status?: number;\n readonly permanent: boolean;\n\n constructor(permanent: boolean, status?: number) {\n super(status === undefined ? \"Token refresh failed\" : `Token refresh failed: ${status}`);\n this.name = \"TokenRefreshError\";\n this.status = status;\n this.permanent = permanent;\n Object.setPrototypeOf(this, TokenRefreshError.prototype);\n }\n}\n\nexport function isTokenRefreshError(error: unknown): error is TokenRefreshError {\n if (error instanceof TokenRefreshError) return true;\n if (!(error instanceof Error)) return false;\n\n const candidate = error as Error & Partial<TokenRefreshError>;\n return (\n candidate.name === \"TokenRefreshError\"\n && typeof candidate.permanent === \"boolean\"\n && (candidate.status === undefined || typeof candidate.status === \"number\")\n );\n}\n\nexport interface ManagedAccount {\n index: number;\n uuid?: string;\n accountId?: string;\n label?: string;\n email?: string;\n planTier?: string;\n refreshToken: string;\n accessToken?: string;\n expiresAt?: number;\n addedAt: number;\n lastUsed: number;\n enabled: boolean;\n rateLimitResetAt?: number;\n last429At?: number;\n cachedUsage?: UsageLimits;\n cachedUsageAt?: number;\n consecutiveAuthFailures: number;\n isAuthDisabled: boolean;\n authDisabledReason?: string;\n}\n\nexport interface PluginClient {\n auth: {\n set: (params: {\n path: { id: string };\n body: {\n type: string;\n refresh: string;\n access: string;\n expires: number;\n };\n }) => Promise<void>;\n };\n tui: {\n showToast: (params: {\n body: {\n title?: string;\n message: string;\n variant: \"info\" | \"warning\" | \"success\" | \"error\";\n };\n }) => Promise<void>;\n };\n app: {\n log: (params: {\n body: {\n service: string;\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n message: string;\n extra?: Record<string, unknown>;\n };\n }) => Promise<void>;\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { loadAccounts, readStorageFromDisk } from \"./storage\";\nimport { ACCOUNTS_FILENAME } from \"./constants\";\nimport { withDirectoryLock } from \"./file-lock\";\nimport { AccountStorageSchema } from \"./types\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport type { AccountStorage, StoredAccount } from \"./types\";\n\nconst FILE_MODE = 0o600;\n\nfunction resolveStoragePath(filename: string): string {\n return join(getConfigDir(), filename);\n}\n\nfunction createEmptyStorage(): AccountStorage {\n return { version: 1, accounts: [] };\n}\n\nfunction buildTempPath(targetPath: string): string {\n return `${targetPath}.${randomBytes(8).toString(\"hex\")}.tmp`;\n}\n\nasync function writeAtomicText(targetPath: string, content: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const tempPath = buildTempPath(targetPath);\n try {\n await fs.writeFile(tempPath, content, { encoding: \"utf-8\", mode: FILE_MODE });\n await fs.chmod(tempPath, FILE_MODE);\n await fs.rename(tempPath, targetPath);\n await fs.chmod(targetPath, FILE_MODE);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n}\n\nasync function writeStorageAtomic(targetPath: string, storage: AccountStorage): Promise<void> {\n const validation = v.safeParse(AccountStorageSchema, storage);\n if (!validation.success) {\n throw new Error(\"Invalid account storage payload\");\n }\n await writeAtomicText(targetPath, `${JSON.stringify(validation.output, null, 2)}\\n`);\n}\n\nasync function ensureStorageFileExists(targetPath: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const emptyContent = `${JSON.stringify(createEmptyStorage(), null, 2)}\\n`;\n try {\n await fs.writeFile(targetPath, emptyContent, { flag: \"wx\", mode: FILE_MODE });\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") throw error;\n }\n}\n\nexport interface DiskCredentials {\n refreshToken: string;\n accessToken?: string;\n expiresAt?: number;\n accountId?: string;\n}\n\nexport class AccountStore {\n private readonly storagePath: string;\n\n constructor(filename?: string) {\n this.storagePath = resolveStoragePath(filename ?? ACCOUNTS_FILENAME);\n }\n\n private async withLock<T>(fn: (storagePath: string) => Promise<T>): Promise<T> {\n await ensureStorageFileExists(this.storagePath);\n return await withDirectoryLock(this.storagePath, () => fn(this.storagePath));\n }\n\n async load(): Promise<AccountStorage> {\n const storage = await loadAccounts(this.storagePath);\n return storage ?? createEmptyStorage();\n }\n\n async readCredentials(uuid: string): Promise<DiskCredentials | null> {\n const storage = await readStorageFromDisk(this.storagePath, false);\n if (!storage) return null;\n\n const account = storage.accounts.find((a) => a.uuid === uuid);\n if (!account) return null;\n\n return {\n refreshToken: account.refreshToken,\n accessToken: account.accessToken,\n expiresAt: account.expiresAt,\n accountId: account.accountId,\n };\n }\n\n async mutateAccount(\n uuid: string,\n fn: (account: StoredAccount) => void,\n ): Promise<StoredAccount | null> {\n return await this.withLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false);\n if (!current) return null;\n\n const account = current.accounts.find((a) => a.uuid === uuid);\n if (!account) return null;\n\n fn(account);\n\n await writeStorageAtomic(storagePath, current);\n return { ...account };\n });\n }\n\n async mutateStorage(\n fn: (storage: AccountStorage) => void,\n ): Promise<void> {\n await this.withLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();\n fn(current);\n await writeStorageAtomic(storagePath, current);\n });\n }\n\n async addAccount(account: StoredAccount): Promise<void> {\n await this.withLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false) ?? createEmptyStorage();\n const exists = current.accounts.some(\n (a) => a.uuid === account.uuid || a.refreshToken === account.refreshToken,\n );\n if (exists) return;\n\n current.accounts.push(account);\n await writeStorageAtomic(storagePath, current);\n });\n }\n\n async removeAccount(uuid: string): Promise<boolean> {\n return await this.withLock(async (storagePath) => {\n const current = await readStorageFromDisk(storagePath, false);\n if (!current) return false;\n\n const initialLength = current.accounts.length;\n current.accounts = current.accounts.filter((a) => a.uuid !== uuid);\n if (current.accounts.length === initialLength) return false;\n\n if (current.activeAccountUuid === uuid) {\n current.activeAccountUuid = current.accounts[0]?.uuid;\n }\n\n await writeStorageAtomic(storagePath, current);\n return true;\n });\n }\n\n async setActiveUuid(uuid: string | undefined): Promise<void> {\n await this.mutateStorage((storage) => {\n storage.activeAccountUuid = uuid;\n });\n }\n\n async clear(): Promise<void> {\n await this.withLock(async (storagePath) => {\n await writeStorageAtomic(storagePath, createEmptyStorage());\n });\n }\n}\n","import { promises as fs } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { ACCOUNTS_FILENAME } from \"./constants\";\nimport { AccountStorageSchema } from \"./types\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport type { AccountStorage, StoredAccount } from \"./types\";\n\nfunction getDefaultStoragePath(): string {\n return join(getConfigDir(), ACCOUNTS_FILENAME);\n}\n\nasync function backupCorruptFile(targetPath: string, content: string): Promise<void> {\n const backupPath = `${targetPath}.corrupt.${Date.now()}.bak`;\n await fs.mkdir(dirname(backupPath), { recursive: true });\n await fs.writeFile(backupPath, content, \"utf-8\");\n}\n\nexport async function readStorageFromDisk(\n targetPath: string,\n backupOnCorrupt: boolean,\n): Promise<AccountStorage | null> {\n let content: string;\n try {\n content = await fs.readFile(targetPath, \"utf-8\");\n } catch (error) {\n if (getErrorCode(error) === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n if (backupOnCorrupt) {\n try {\n await backupCorruptFile(targetPath, content);\n } catch {\n // best-effort backup\n }\n }\n return null;\n }\n\n const validation = v.safeParse(AccountStorageSchema, parsed);\n if (!validation.success) {\n if (backupOnCorrupt) {\n try {\n await backupCorruptFile(targetPath, content);\n } catch {\n // best-effort backup\n }\n }\n return null;\n }\n\n return validation.output;\n}\n\nexport function deduplicateAccounts(accounts: StoredAccount[]): StoredAccount[] {\n const deduplicated: StoredAccount[] = [];\n const indexByUuid = new Map<string, number>();\n\n for (const account of accounts) {\n if (!account.uuid) {\n deduplicated.push(account);\n continue;\n }\n\n const existingIndex = indexByUuid.get(account.uuid);\n if (existingIndex === undefined) {\n indexByUuid.set(account.uuid, deduplicated.length);\n deduplicated.push(account);\n continue;\n }\n\n const existingAccount = deduplicated[existingIndex];\n if (!existingAccount || account.lastUsed >= existingAccount.lastUsed) {\n deduplicated[existingIndex] = account;\n }\n }\n\n return deduplicated;\n}\n\nexport async function loadAccounts(storagePath?: string): Promise<AccountStorage | null> {\n const effectivePath = storagePath ?? getDefaultStoragePath();\n const storage = await readStorageFromDisk(effectivePath, true);\n if (!storage) {\n return null;\n }\n\n return {\n ...storage,\n accounts: deduplicateAccounts(storage.accounts || []),\n };\n}\n","const DEFAULT_ACCOUNTS_FILENAME = \"multiauth-accounts.json\";\n\n/**\n * @deprecated Use `new AccountStore(filename)` instead.\n * This global is kept only for backward-compatible test helpers.\n * When two plugins share the same core module instance, mutating\n * this global causes one plugin to read the other's account file.\n */\nexport let ACCOUNTS_FILENAME = DEFAULT_ACCOUNTS_FILENAME;\n\n/**\n * @deprecated Use `new AccountStore(filename)` instead.\n */\nexport function setAccountsFilename(filename: string): void {\n if (!filename) {\n ACCOUNTS_FILENAME = DEFAULT_ACCOUNTS_FILENAME;\n return;\n }\n\n ACCOUNTS_FILENAME = filename;\n}\n","import { promises as fs } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst DEFAULT_STALE_MS = 10_000;\nconst DEFAULT_RETRY_DELAY_MS = 50;\nconst DEFAULT_MAX_RETRIES = 10;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function removeIfStale(lockPath: string, staleMs: number): Promise<void> {\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.rm(lockPath, { recursive: true, force: true });\n }\n } catch {}\n}\n\nexport async function withDirectoryLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n options?: {\n staleMs?: number;\n retryDelayMs?: number;\n retries?: number;\n },\n): Promise<T> {\n const lockPath = `${targetPath}.lock`;\n const staleMs = options?.staleMs ?? DEFAULT_STALE_MS;\n const retryDelayMs = options?.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;\n const retries = options?.retries ?? DEFAULT_MAX_RETRIES;\n\n await fs.mkdir(dirname(targetPath), { recursive: true });\n\n for (let attempt = 0; ; attempt += 1) {\n try {\n await fs.mkdir(lockPath, { mode: 0o700 });\n break;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n if (code !== \"EEXIST\") {\n throw error;\n }\n\n await removeIfStale(lockPath, staleMs);\n if (attempt >= retries) {\n throw new Error(`Failed to acquire lock for ${targetPath}`);\n }\n await sleep(retryDelayMs * (attempt + 1));\n }\n }\n\n try {\n return await fn();\n } finally {\n await fs.rm(lockPath, { recursive: true, force: true }).catch(() => {});\n }\n}\n","import {\n isTokenRefreshError,\n type ManagedAccount,\n type PluginClient,\n type TokenRefreshResult,\n} from \"./types\";\n\nconst MIN_MAX_RETRIES = 6;\nconst RETRIES_PER_ACCOUNT = 3;\nconst MAX_SERVER_RETRIES_PER_ATTEMPT = 2;\nconst MAX_RESOLVE_ATTEMPTS = 10;\nconst SERVER_RETRY_BASE_MS = 1_000;\nconst SERVER_RETRY_MAX_MS = 4_000;\nexport interface ExecutorAccountManager {\n getAccountCount(): number;\n refresh(): Promise<void>;\n selectAccount(): Promise<ManagedAccount | null>;\n markSuccess(uuid: string): Promise<void>;\n markAuthFailure(uuid: string, result: TokenRefreshResult): Promise<void>;\n markRevoked(uuid: string): Promise<void>;\n hasAnyUsableAccount(): boolean;\n getMinWaitTime(): number;\n}\n\nexport interface ExecutorRuntimeFactory {\n getRuntime(uuid: string): Promise<{ fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response> }>;\n invalidate(uuid: string): void;\n}\n\nexport interface ExecutorDependencies {\n handleRateLimitResponse: (\n manager: unknown,\n client: PluginClient,\n account: ManagedAccount,\n response: Response,\n ) => Promise<void>;\n formatWaitTime: (ms: number) => string;\n sleep: (ms: number) => Promise<void>;\n showToast: (\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n ) => Promise<void>;\n getAccountLabel: (account: ManagedAccount) => string;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n\nexport function createExecutorForProvider(\n providerName: string,\n dependencies: ExecutorDependencies,\n): {\n executeWithAccountRotation: (\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n input: RequestInfo | URL,\n init?: RequestInit,\n ) => Promise<Response>;\n} {\n const {\n handleRateLimitResponse,\n formatWaitTime,\n sleep,\n showToast,\n getAccountLabel,\n } = dependencies;\n\n async function executeWithAccountRotation(\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n const maxRetries = Math.max(MIN_MAX_RETRIES, manager.getAccountCount() * RETRIES_PER_ACCOUNT);\n let previousAccountUuid: string | undefined;\n\n type StatusTransition =\n | { type: \"success\"; response: Response }\n | { type: \"handled\"; response?: Response }\n | { type: \"retryOuter\" };\n\n async function retryServerErrors(\n account: ManagedAccount,\n runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>,\n ): Promise<Response | null> {\n for (let attempt = 0; attempt < MAX_SERVER_RETRIES_PER_ATTEMPT; attempt++) {\n const backoff = Math.min(SERVER_RETRY_BASE_MS * 2 ** attempt, SERVER_RETRY_MAX_MS);\n const jitteredBackoff = backoff * (0.5 + Math.random() * 0.5);\n await sleep(jitteredBackoff);\n\n let retryResponse: Response;\n try {\n retryResponse = await runtime.fetch(input, init);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n return null;\n }\n void showToast(client, `${getAccountLabel(account)} network error — switching`, \"warning\");\n return null;\n }\n\n if (retryResponse.status < 500) return retryResponse;\n }\n\n return null;\n }\n\n const dispatchResponseStatus = async (\n account: ManagedAccount,\n accountUuid: string,\n runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>,\n response: Response,\n allow401Retry: boolean,\n from401RefreshRetry: boolean,\n ): Promise<StatusTransition> => {\n if (response.status >= 500) {\n const recovered = await retryServerErrors(account, runtime);\n if (recovered === null) {\n return { type: \"retryOuter\" };\n }\n response = recovered;\n }\n\n if (response.status === 401) {\n if (allow401Retry) {\n runtimeFactory.invalidate(accountUuid);\n try {\n const retryRuntime = await runtimeFactory.getRuntime(accountUuid);\n const retryResponse = await retryRuntime.fetch(input, init);\n return dispatchResponseStatus(account, accountUuid, retryRuntime, retryResponse, false, true);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n return { type: \"retryOuter\" };\n }\n return { type: \"retryOuter\" };\n }\n }\n\n await manager.markAuthFailure(accountUuid, { ok: false, permanent: false });\n await manager.refresh();\n\n if (!manager.hasAnyUsableAccount()) {\n void showToast(client, \"All accounts have auth failures.\", \"error\");\n throw new Error(\n `All ${providerName} accounts have authentication failures. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n void showToast(client, `${getAccountLabel(account)} auth failed — switching to next account.`, \"warning\");\n return { type: \"retryOuter\" };\n }\n\n if (response.status === 403) {\n const revoked = await isRevokedTokenResponse(response);\n if (revoked) {\n await manager.markRevoked(accountUuid);\n await manager.refresh();\n void showToast(\n client,\n `${getAccountLabel(account)} disabled: OAuth token revoked.`,\n \"error\",\n );\n\n if (!manager.hasAnyUsableAccount()) {\n throw new Error(\n `All ${providerName} accounts have been revoked or disabled. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n return { type: \"retryOuter\" };\n }\n\n if (from401RefreshRetry) {\n return { type: \"handled\", response };\n }\n }\n\n if (response.status === 429) {\n await handleRateLimitResponse(manager, client, account, response);\n return { type: \"handled\" };\n }\n\n return { type: \"success\", response };\n };\n\n for (let retries = 1; retries <= maxRetries; retries++) {\n await manager.refresh();\n const account = await resolveAccount(manager, client);\n const accountUuid = account.uuid;\n if (!accountUuid) continue;\n\n if (previousAccountUuid && accountUuid !== previousAccountUuid && manager.getAccountCount() > 1) {\n void showToast(client, `Switched to ${getAccountLabel(account)}`, \"info\");\n }\n previousAccountUuid = accountUuid;\n\n let runtime: Awaited<ReturnType<ExecutorRuntimeFactory[\"getRuntime\"]>>;\n let response: Response;\n try {\n runtime = await runtimeFactory.getRuntime(accountUuid);\n response = await runtime.fetch(input, init);\n } catch (error) {\n if (isAbortError(error)) throw error;\n if (await handleRuntimeFetchFailure(manager, runtimeFactory, client, account, error)) {\n continue;\n }\n void showToast(client, `${getAccountLabel(account)} network error — switching`, \"warning\");\n continue;\n }\n\n const transition = await dispatchResponseStatus(account, accountUuid, runtime, response, true, false);\n if (transition.type === \"retryOuter\" || transition.type === \"handled\") {\n if (transition.type === \"handled\" && transition.response) {\n return transition.response;\n }\n continue;\n }\n\n await manager.markSuccess(accountUuid);\n return transition.response;\n }\n\n throw new Error(\n `Exhausted ${maxRetries} retries across all accounts. All attempts failed due to auth errors, rate limits, or token issues.`,\n );\n }\n\n async function handleRuntimeFetchFailure(\n manager: ExecutorAccountManager,\n runtimeFactory: ExecutorRuntimeFactory,\n client: PluginClient,\n account: ManagedAccount,\n error: unknown,\n ): Promise<boolean> {\n if (!isTokenRefreshError(error)) return false;\n if (!account.uuid) return false;\n\n const accountUuid = account.uuid;\n runtimeFactory.invalidate(accountUuid);\n await manager.markAuthFailure(accountUuid, {\n ok: false,\n permanent: error.permanent,\n });\n await manager.refresh();\n\n if (!manager.hasAnyUsableAccount()) {\n void showToast(client, \"All accounts have auth failures.\", \"error\");\n throw new Error(\n `All ${providerName} accounts have authentication failures. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n void showToast(client, `${getAccountLabel(account)} auth failed — switching to next account.`, \"warning\");\n return true;\n }\n\n async function resolveAccount(\n manager: ExecutorAccountManager,\n client: PluginClient,\n ): Promise<ManagedAccount> {\n let attempts = 0;\n\n while (true) {\n if (++attempts > MAX_RESOLVE_ATTEMPTS) {\n throw new Error(\n `Failed to resolve an available account after ${MAX_RESOLVE_ATTEMPTS} attempts. All accounts may be rate-limited or disabled.`,\n );\n }\n\n const account = await manager.selectAccount();\n if (account) return account;\n\n if (!manager.hasAnyUsableAccount()) {\n throw new Error(\n `All ${providerName} accounts are disabled. Re-authenticate with \\`opencode auth login\\`.`,\n );\n }\n\n const waitMs = manager.getMinWaitTime();\n if (waitMs <= 0) {\n throw new Error(\n `All ${providerName} accounts are rate-limited. Add more accounts with \\`opencode auth login\\` or wait.`,\n );\n }\n\n await showToast(\n client,\n `All ${manager.getAccountCount()} account(s) rate-limited. Waiting ${formatWaitTime(waitMs)}...`,\n \"warning\",\n );\n await sleep(waitMs);\n }\n }\n\n return {\n executeWithAccountRotation,\n };\n}\n\nasync function isRevokedTokenResponse(response: Response): Promise<boolean> {\n try {\n const cloned = response.clone();\n const body = await cloned.text();\n return body.includes(\"revoked\");\n } catch {\n return false;\n }\n}\n","import { AccountStore } from \"./account-store\";\nimport type { PluginClient, PluginConfig, StoredAccount, TokenRefreshResult } from \"./types\";\nimport { getClearedOAuthBody } from \"./utils\";\n\nconst INITIAL_DELAY_MS = 5_000;\n\nexport interface ProactiveRefreshDependencies {\n providerAuthId: string;\n getConfig: () => PluginConfig;\n refreshToken: (\n currentRefreshToken: string,\n accountId: string,\n client: PluginClient,\n ) => Promise<TokenRefreshResult>;\n isTokenExpired: (account: Pick<StoredAccount, \"accessToken\" | \"expiresAt\">) => boolean;\n debugLog: (client: PluginClient, message: string, extra?: Record<string, unknown>) => void;\n}\n\nexport interface ProactiveRefreshQueueInstance {\n start(): void;\n stop(): Promise<void>;\n}\n\nexport interface ProactiveRefreshQueueClass {\n new (\n client: PluginClient,\n store: AccountStore,\n onInvalidate?: (uuid: string) => void,\n ): ProactiveRefreshQueueInstance;\n}\n\nexport function createProactiveRefreshQueueForProvider(dependencies: ProactiveRefreshDependencies): ProactiveRefreshQueueClass {\n const {\n providerAuthId,\n getConfig,\n refreshToken,\n isTokenExpired,\n debugLog,\n } = dependencies;\n\n return class ProactiveRefreshQueue {\n private timeoutHandle: ReturnType<typeof setTimeout> | null = null;\n private runToken = 0;\n private inFlight: Promise<void> | null = null;\n\n constructor(\n private readonly client: PluginClient,\n private readonly store: AccountStore,\n private readonly onInvalidate?: (uuid: string) => void,\n ) {}\n\n start(): void {\n const config = getConfig();\n if (!config.proactive_refresh) return;\n\n this.runToken++;\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle);\n this.timeoutHandle = null;\n }\n this.scheduleNext(this.runToken, INITIAL_DELAY_MS);\n\n debugLog(this.client, \"Proactive refresh started\", {\n intervalSeconds: config.proactive_refresh_interval_seconds,\n bufferSeconds: config.proactive_refresh_buffer_seconds,\n });\n }\n\n async stop(): Promise<void> {\n this.runToken++;\n if (this.timeoutHandle) {\n clearTimeout(this.timeoutHandle);\n this.timeoutHandle = null;\n }\n if (this.inFlight) {\n await this.inFlight;\n this.inFlight = null;\n }\n debugLog(this.client, \"Proactive refresh stopped\");\n }\n\n private scheduleNext(token: number, delayMs: number): void {\n this.timeoutHandle = setTimeout(() => {\n if (token !== this.runToken) return;\n this.inFlight = this.runCheck(token).finally(() => {\n this.inFlight = null;\n });\n }, delayMs);\n }\n\n private needsProactiveRefresh(account: Pick<StoredAccount, \"accessToken\" | \"expiresAt\">): boolean {\n if (!account.accessToken || !account.expiresAt) return false;\n if (isTokenExpired(account)) return false;\n const bufferMs = getConfig().proactive_refresh_buffer_seconds * 1000;\n return account.expiresAt <= Date.now() + bufferMs;\n }\n\n private async runCheck(token: number): Promise<void> {\n try {\n const stored = await this.store.load();\n if (token !== this.runToken) return;\n\n const candidates = stored.accounts.filter((a) =>\n a.enabled !== false\n && !a.isAuthDisabled\n && a.uuid\n && this.needsProactiveRefresh(a),\n );\n\n if (candidates.length === 0) return;\n\n debugLog(this.client, `Proactive refresh: ${candidates.length} account(s) approaching expiry`);\n\n for (const account of candidates) {\n if (token !== this.runToken) return;\n\n const credentials = await this.store.readCredentials(account.uuid!);\n if (!credentials || !this.needsProactiveRefresh(credentials)) continue;\n\n const result = await refreshToken(credentials.refreshToken, account.uuid!, this.client);\n if (result.ok) {\n await this.store.mutateAccount(account.uuid!, (target) => {\n target.accessToken = result.patch.accessToken;\n target.expiresAt = result.patch.expiresAt;\n if (result.patch.refreshToken) target.refreshToken = result.patch.refreshToken;\n if (result.patch.uuid) target.uuid = result.patch.uuid;\n if (result.patch.email) target.email = result.patch.email;\n if (result.patch.accountId) target.accountId = result.patch.accountId;\n target.consecutiveAuthFailures = 0;\n target.isAuthDisabled = false;\n target.authDisabledReason = undefined;\n });\n this.onInvalidate?.(account.uuid!);\n } else {\n await this.persistFailure(account, result.permanent);\n }\n }\n } catch (error) {\n debugLog(this.client, `Proactive refresh check error: ${error}`);\n } finally {\n if (token === this.runToken) {\n const intervalMs = getConfig().proactive_refresh_interval_seconds * 1000;\n this.scheduleNext(token, intervalMs);\n }\n }\n }\n\n private async persistFailure(account: StoredAccount, permanent: boolean): Promise<void> {\n try {\n const accountUuid = account.uuid;\n if (!accountUuid) return;\n\n if (permanent) {\n const removed = await this.store.removeAccount(accountUuid);\n if (!removed) return;\n\n this.onInvalidate?.(accountUuid);\n await this.clearOpenCodeAuthIfNoAccountsRemain();\n return;\n }\n\n await this.store.mutateStorage((storage) => {\n const target = storage.accounts.find((entry) => entry.uuid === accountUuid);\n if (!target) return;\n\n target.consecutiveAuthFailures = (target.consecutiveAuthFailures ?? 0) + 1;\n const maxFailures = getConfig().max_consecutive_auth_failures;\n const usableCount = storage.accounts.filter(\n (entry) => entry.enabled && !entry.isAuthDisabled && entry.uuid !== accountUuid,\n ).length;\n\n if (target.consecutiveAuthFailures >= maxFailures && usableCount > 0) {\n target.isAuthDisabled = true;\n target.authDisabledReason = `${maxFailures} consecutive auth failures (proactive refresh)`;\n }\n });\n } catch {\n debugLog(this.client, `Failed to persist auth failure for ${account.uuid}`);\n }\n }\n\n private async clearOpenCodeAuthIfNoAccountsRemain(): Promise<void> {\n const storage = await this.store.load();\n if (storage.accounts.length > 0) return;\n\n await this.client.auth\n .set({\n path: { id: providerAuthId },\n body: getClearedOAuthBody(),\n })\n .catch(() => {});\n }\n };\n}\n","import type { ManagedAccount, PluginClient, PluginConfig, UsageLimits } from \"./types\";\n\nconst USAGE_FETCH_COOLDOWN_MS = 30_000;\n\nexport interface RateLimitDependencies {\n fetchUsage: (accessToken: string, accountId?: string) => Promise<{ ok: true; data: UsageLimits } | { ok: false; reason: string }>;\n getConfig: () => Pick<PluginConfig, \"default_retry_after_ms\">;\n formatWaitTime: (ms: number) => string;\n getAccountLabel: (account: ManagedAccount) => string;\n showToast: (\n client: PluginClient,\n message: string,\n variant: \"info\" | \"warning\" | \"success\" | \"error\",\n ) => Promise<void>;\n}\n\nexport interface RateLimitAccountManager {\n markRateLimited(uuid: string, backoffMs?: number): Promise<void>;\n applyUsageCache(uuid: string, usage: UsageLimits): Promise<void>;\n getAccountCount(): number;\n}\n\nexport function createRateLimitHandlers(dependencies: RateLimitDependencies) {\n const {\n fetchUsage,\n getConfig,\n formatWaitTime,\n getAccountLabel,\n showToast,\n } = dependencies;\n\n function retryAfterMsFromResponse(response: Response): number {\n const retryAfterMs = response.headers.get(\"retry-after-ms\");\n if (retryAfterMs) {\n const parsed = parseInt(retryAfterMs, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed;\n }\n\n const retryAfter = response.headers.get(\"retry-after\");\n if (retryAfter) {\n const parsed = parseInt(retryAfter, 10);\n if (!isNaN(parsed) && parsed > 0) return parsed * 1000;\n }\n\n return getConfig().default_retry_after_ms;\n }\n\n function getResetMsFromUsage(account: ManagedAccount): number | null {\n const usage = account.cachedUsage;\n if (!usage) return null;\n\n const now = Date.now();\n const candidates: number[] = [];\n\n if (usage.five_hour?.resets_at) {\n const ms = Date.parse(usage.five_hour.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n if (usage.seven_day?.resets_at) {\n const ms = Date.parse(usage.seven_day.resets_at) - now;\n if (ms > 0) candidates.push(ms);\n }\n\n return candidates.length > 0 ? Math.min(...candidates) : null;\n }\n\n async function fetchUsageLimits(accessToken: string, accountId?: string): Promise<UsageLimits | null> {\n if (!accessToken) return null;\n try {\n const result = await fetchUsage(accessToken, accountId);\n return result.ok ? result.data : null;\n } catch {\n return null;\n }\n }\n\n async function handleRateLimitResponse(\n manager: RateLimitAccountManager,\n client: PluginClient,\n account: ManagedAccount,\n response: Response,\n ): Promise<void> {\n if (!account.uuid) return;\n\n const resetMs = getResetMsFromUsage(account) ?? retryAfterMsFromResponse(response);\n await manager.markRateLimited(account.uuid, resetMs);\n\n const shouldFetchUsage = account.accessToken\n && (!account.cachedUsageAt || Date.now() - account.cachedUsageAt > USAGE_FETCH_COOLDOWN_MS);\n\n if (shouldFetchUsage) {\n const usage = await fetchUsageLimits(account.accessToken!, account.accountId);\n if (usage) {\n await manager.applyUsageCache(account.uuid, usage);\n }\n }\n\n if (manager.getAccountCount() > 1) {\n void showToast(\n client,\n `${getAccountLabel(account)} rate-limited (resets in ${formatWaitTime(resetMs)}). Switching...`,\n \"warning\",\n );\n }\n }\n\n return {\n retryAfterMsFromResponse,\n getResetMsFromUsage,\n fetchUsageLimits,\n handleRateLimitResponse,\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { getConfigDir } from \"./utils\";\nimport type { AccountStore } from \"./account-store\";\n\nconst AUTH_JSON_FILENAME = \"auth.json\";\n\ninterface AuthJsonCredential {\n type: string;\n refresh: string;\n access?: string;\n expires?: number;\n}\n\nfunction isValidOAuthCredential(value: unknown): value is AuthJsonCredential {\n if (typeof value !== \"object\" || value === null) return false;\n\n const candidate = value as Record<string, unknown>;\n return (\n candidate.type === \"oauth\" &&\n typeof candidate.refresh === \"string\" &&\n candidate.refresh.length > 0\n );\n}\n\nfunction resolveAuthJsonPath(): string {\n return join(getConfigDir(), AUTH_JSON_FILENAME);\n}\n\nasync function readAuthJson(): Promise<Record<string, unknown> | null> {\n const authPath = resolveAuthJsonPath();\n\n let content: string;\n try {\n content = await fs.readFile(authPath, \"utf-8\");\n } catch {\n return null;\n }\n\n try {\n const parsed = JSON.parse(content);\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return null;\n }\n return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Imports an existing OAuth credential from OpenCode's auth.json\n * into the multi-account storage on first use.\n *\n * Only runs when storage has zero accounts. Does not modify auth.json.\n *\n * @param providerKey - The key in auth.json (\"anthropic\" or \"openai\")\n * @param store - The AccountStore instance to import into\n * @returns true if a credential was imported, false otherwise\n */\nexport async function migrateFromAuthJson(\n providerKey: string,\n store: AccountStore,\n): Promise<boolean> {\n const storage = await store.load();\n const hasExistingAccounts = storage.accounts.length > 0;\n if (hasExistingAccounts) return false;\n\n const authData = await readAuthJson();\n if (!authData) return false;\n\n const providerCredential = authData[providerKey];\n if (!isValidOAuthCredential(providerCredential)) return false;\n\n const now = Date.now();\n const newAccount = {\n uuid: crypto.randomUUID(),\n refreshToken: providerCredential.refresh,\n accessToken: providerCredential.access,\n expiresAt: providerCredential.expires,\n addedAt: now,\n lastUsed: now,\n enabled: true,\n planTier: \"\",\n consecutiveAuthFailures: 0,\n isAuthDisabled: false,\n };\n\n await store.addAccount(newAccount);\n await store.setActiveUuid(newAccount.uuid);\n\n return true;\n}\n","export const ANSI = {\n hide: \"\\x1b[?25l\",\n show: \"\\x1b[?25h\",\n up: (n = 1) => `\\x1b[${n}A`,\n down: (n = 1) => `\\x1b[${n}B`,\n clearLine: \"\\x1b[2K\",\n\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n red: \"\\x1b[31m\",\n yellow: \"\\x1b[33m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n reset: \"\\x1b[0m\",\n} as const;\n\nexport type KeyAction = \"up\" | \"down\" | \"enter\" | \"escape\" | \"escape-start\" | null;\n\nexport function parseKey(data: Buffer): KeyAction {\n const s = data.toString();\n\n // Standard: \\x1b[A / Application mode: \\x1bOA\n if (s === \"\\x1b[A\" || s === \"\\x1bOA\") return \"up\";\n if (s === \"\\x1b[B\" || s === \"\\x1bOB\") return \"down\";\n\n if (s === \"\\r\" || s === \"\\n\") return \"enter\";\n if (s === \"\\x03\") return \"escape\";\n\n // Bare escape byte — may be start of arrow key sequence\n if (s === \"\\x1b\") return \"escape-start\";\n\n return null;\n}\n\nexport function isTTY(): boolean {\n return Boolean(process.stdin.isTTY);\n}\n","import { ANSI, isTTY, parseKey } from \"./ansi\";\n\nexport interface MenuItem<T = string> {\n label: string;\n value: T;\n hint?: string;\n disabled?: boolean;\n separator?: boolean;\n color?: \"red\" | \"green\" | \"yellow\" | \"cyan\";\n}\n\nexport interface SelectOptions {\n message: string;\n subtitle?: string;\n}\n\nconst ESCAPE_TIMEOUT_MS = 50;\n\nconst COLOR_MAP: Record<string, string> = {\n red: ANSI.red,\n green: ANSI.green,\n yellow: ANSI.yellow,\n cyan: ANSI.cyan,\n};\n\nexport async function select<T>(\n items: MenuItem<T>[],\n options: SelectOptions,\n): Promise<T | null> {\n if (!isTTY()) {\n throw new Error(\"Interactive select requires a TTY terminal\");\n }\n\n const enabledItems = items.filter((i) => !i.disabled && !i.separator);\n if (enabledItems.length === 0) {\n throw new Error(\"All items disabled\");\n }\n\n if (enabledItems.length === 1) {\n return enabledItems[0]!.value;\n }\n\n const { message, subtitle } = options;\n const { stdin, stdout } = process;\n\n let cursor = items.findIndex((i) => !i.disabled && !i.separator);\n if (cursor === -1) cursor = 0;\n let escapeTimeout: ReturnType<typeof setTimeout> | null = null;\n let isCleanedUp = false;\n let isFirstRender = true;\n\n const getTotalLines = (): number => {\n const subtitleLines = subtitle ? 3 : 0;\n return 1 + subtitleLines + items.length + 1 + 1;\n };\n\n const renderItemLabel = (item: MenuItem<T>, isSelected: boolean): string => {\n const colorCode = item.color ? (COLOR_MAP[item.color] ?? \"\") : \"\";\n\n if (item.disabled) {\n return `${ANSI.dim}${item.label} (unavailable)${ANSI.reset}`;\n }\n\n const hintSuffix = item.hint ? ` ${ANSI.dim}${item.hint}${ANSI.reset}` : \"\";\n\n if (isSelected) {\n const label = colorCode ? `${colorCode}${item.label}${ANSI.reset}` : item.label;\n return `${label}${hintSuffix}`;\n }\n\n const dimLabel = colorCode\n ? `${ANSI.dim}${colorCode}${item.label}${ANSI.reset}`\n : `${ANSI.dim}${item.label}${ANSI.reset}`;\n return `${dimLabel}${hintSuffix}`;\n };\n\n const render = () => {\n const totalLines = getTotalLines();\n\n if (!isFirstRender) {\n stdout.write(ANSI.up(totalLines) + \"\\r\");\n }\n isFirstRender = false;\n\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u250c ${ANSI.reset}${message}\\n`);\n\n if (subtitle) {\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u2502${ANSI.reset}\\n`);\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u25c6${ANSI.reset} ${subtitle}\\n`);\n stdout.write(`${ANSI.clearLine}\\n`);\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (!item) continue;\n\n if (item.separator) {\n stdout.write(`${ANSI.clearLine}${ANSI.dim}\\u2502${ANSI.reset}\\n`);\n continue;\n }\n\n const isSelected = i === cursor;\n const labelText = renderItemLabel(item, isSelected);\n const bullet = isSelected\n ? `${ANSI.green}\\u25cf${ANSI.reset}`\n : `${ANSI.dim}\\u25cb${ANSI.reset}`;\n\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2502${ANSI.reset} ${bullet} ${labelText}\\n`);\n }\n\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2502${ANSI.reset} ${ANSI.dim}\\u2191/\\u2193 to select \\u2022 Enter: confirm${ANSI.reset}\\n`);\n stdout.write(`${ANSI.clearLine}${ANSI.cyan}\\u2514${ANSI.reset}\\n`);\n };\n\n return new Promise((resolve) => {\n const wasRaw = stdin.isRaw ?? false;\n\n const cleanup = () => {\n if (isCleanedUp) return;\n isCleanedUp = true;\n\n if (escapeTimeout) {\n clearTimeout(escapeTimeout);\n escapeTimeout = null;\n }\n\n try {\n stdin.removeListener(\"data\", onKey);\n stdin.setRawMode(wasRaw);\n stdin.pause();\n stdout.write(ANSI.show);\n } catch {\n // best-effort cleanup\n }\n\n process.removeListener(\"SIGINT\", onSignal);\n process.removeListener(\"SIGTERM\", onSignal);\n };\n\n const onSignal = () => {\n cleanup();\n resolve(null);\n };\n\n const finishWithValue = (value: T | null) => {\n cleanup();\n resolve(value);\n };\n\n const findNextSelectable = (from: number, direction: 1 | -1): number => {\n if (items.length === 0) return from;\n let next = from;\n do {\n next = (next + direction + items.length) % items.length;\n } while (items[next]?.disabled || items[next]?.separator);\n return next;\n };\n\n const onKey = (data: Buffer) => {\n if (escapeTimeout) {\n clearTimeout(escapeTimeout);\n escapeTimeout = null;\n }\n\n const action = parseKey(data);\n\n switch (action) {\n case \"up\":\n cursor = findNextSelectable(cursor, -1);\n render();\n return;\n case \"down\":\n cursor = findNextSelectable(cursor, 1);\n render();\n return;\n case \"enter\":\n finishWithValue(items[cursor]?.value ?? null);\n return;\n case \"escape\":\n finishWithValue(null);\n return;\n case \"escape-start\":\n escapeTimeout = setTimeout(() => {\n finishWithValue(null);\n }, ESCAPE_TIMEOUT_MS);\n return;\n default:\n return;\n }\n };\n\n process.once(\"SIGINT\", onSignal);\n process.once(\"SIGTERM\", onSignal);\n\n try {\n stdin.setRawMode(true);\n } catch {\n cleanup();\n resolve(null);\n return;\n }\n\n stdin.resume();\n stdout.write(ANSI.hide);\n render();\n\n stdin.on(\"data\", onKey);\n });\n}\n","import { select } from \"./select\";\n\nexport async function confirm(message: string, defaultYes = false): Promise<boolean> {\n const items = defaultYes\n ? [\n { label: \"Yes\", value: true },\n { label: \"No\", value: false },\n ]\n : [\n { label: \"No\", value: false },\n { label: \"Yes\", value: true },\n ];\n\n const result = await select(items, { message });\n return result ?? false;\n}\n","import type { OAuthAdapter } from \"./types\";\n\nexport const anthropicOAuthAdapter: OAuthAdapter = {\n id: \"anthropic\",\n authProviderId: \"anthropic\",\n modelDisplayName: \"Claude\",\n statusToolName: \"claude_multiauth_status\",\n authMethodLabel: \"Claude Pro/Max (Multi-Auth)\",\n serviceLogName: \"claude-multiauth\",\n oauthClientId: \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\",\n tokenEndpoint: \"https://console.anthropic.com/v1/oauth/token\",\n usageEndpoint: \"https://api.anthropic.com/api/oauth/usage\",\n profileEndpoint: \"https://api.anthropic.com/api/oauth/profile\",\n oauthBetaHeader: \"oauth-2025-04-20\",\n requestBetaHeader: \"oauth-2025-04-20,interleaved-thinking-2025-05-14\",\n cliUserAgent: \"claude-cli/2.1.2 (external, cli)\",\n cliVersion: \"2.1.80\",\n billingSalt: \"59cf53e54c78\",\n toolPrefix: \"mcp_\",\n accountStorageFilename: \"anthropic-multi-account-accounts.json\",\n transform: {\n rewriteOpenCodeBranding: true,\n addToolPrefix: true,\n stripToolPrefixInResponse: true,\n enableMessagesBetaQuery: true,\n },\n planLabels: {\n max: \"Claude Max\",\n pro: \"Claude Pro\",\n free: \"Free\",\n },\n supported: true,\n};\n","import type { OAuthAdapter } from \"./types\";\n\nconst ISSUER = \"https://auth.openai.com\";\n\nexport const openAIOAuthAdapter: OAuthAdapter = {\n id: \"openai\",\n authProviderId: \"openai\",\n modelDisplayName: \"ChatGPT\",\n statusToolName: \"chatgpt_multiauth_status\",\n authMethodLabel: \"ChatGPT Plus/Pro (Multi-Auth)\",\n serviceLogName: \"chatgpt-multiauth\",\n oauthClientId: \"app_EMoamEEZ73f0CkXaXp7hrann\",\n tokenEndpoint: `${ISSUER}/oauth/token`,\n usageEndpoint: \"\",\n profileEndpoint: \"\",\n oauthBetaHeader: \"\",\n requestBetaHeader: \"\",\n cliUserAgent: \"opencode/1.1.53\",\n cliVersion: \"\",\n billingSalt: \"\",\n toolPrefix: \"mcp_\",\n accountStorageFilename: \"openai-multi-account-accounts.json\",\n transform: {\n rewriteOpenCodeBranding: false,\n addToolPrefix: false,\n stripToolPrefixInResponse: false,\n enableMessagesBetaQuery: false,\n },\n planLabels: {\n pro: \"ChatGPT Pro\",\n plus: \"ChatGPT Plus\",\n go: \"ChatGPT Go\",\n free: \"Free\",\n },\n supported: true,\n};\n","import * as v from \"valibot\";\n\n// ─── Valibot Schemas (disk-persisted config) ─────────────────────\n\nexport const PoolConfigSchema = v.object({\n name: v.string(),\n baseProvider: v.string(),\n members: v.array(v.string()),\n enabled: v.boolean(),\n});\n\nexport const ChainEntryConfigSchema = v.object({\n pool: v.string(),\n model: v.optional(v.string()),\n enabled: v.boolean(),\n});\n\nexport const ChainConfigSchema = v.object({\n name: v.string(),\n entries: v.array(ChainEntryConfigSchema),\n enabled: v.boolean(),\n});\n\nexport const PoolChainConfigSchema = v.object({\n pools: v.optional(v.array(PoolConfigSchema), []),\n chains: v.optional(v.array(ChainConfigSchema), []),\n});\n\n// ─── Inferred Types (from schemas) ───────────────────────────────\n\nexport type PoolConfig = v.InferOutput<typeof PoolConfigSchema>;\nexport type ChainEntryConfig = v.InferOutput<typeof ChainEntryConfigSchema>;\nexport type ChainConfig = v.InferOutput<typeof ChainConfigSchema>;\nexport type PoolChainConfig = v.InferOutput<typeof PoolChainConfigSchema>;\n\n// In-memory cascade state (NOT persisted)\nexport interface CascadeState {\n prompt: string;\n attemptedAccounts: Set<string>;\n visitedChainIndexes: Set<number>;\n}\n\n// Candidate for failover rotation\nexport interface FailoverCandidate {\n poolName: string;\n accountUuid: string;\n source: \"pool\" | \"chain\";\n chainIndex?: number;\n}\n\n// Skipped entry during failover planning\nexport interface FailoverSkip {\n type: \"pool_exhausted\" | \"chain_disabled\" | \"account_attempted\" | \"account_unavailable\";\n poolName: string;\n reason: string;\n detail?: string;\n}\n","import { promises as fs } from \"node:fs\";\nimport { randomBytes } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport * as v from \"valibot\";\nimport { withDirectoryLock } from \"./file-lock\";\nimport { getConfigDir, getErrorCode } from \"./utils\";\nimport { PoolChainConfigSchema } from \"./pool-types\";\nimport type { PoolChainConfig } from \"./pool-types\";\n\nconst POOL_CONFIG_FILENAME = \"multiauth-pools.json\";\nconst FILE_MODE = 0o600;\n\nfunction createEmptyConfig(): PoolChainConfig {\n return { pools: [], chains: [] };\n}\n\nfunction getGlobalConfigPath(): string {\n return join(getConfigDir(), POOL_CONFIG_FILENAME);\n}\n\nfunction buildTempPath(targetPath: string): string {\n return `${targetPath}.${randomBytes(8).toString(\"hex\")}.tmp`;\n}\n\nasync function resolveConfigPath(): Promise<string> {\n const projectPath = join(process.cwd(), \".opencode\", POOL_CONFIG_FILENAME);\n try {\n await fs.access(projectPath);\n return projectPath;\n } catch {\n }\n return getGlobalConfigPath();\n}\n\nasync function ensureConfigFileExists(targetPath: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const emptyContent = `${JSON.stringify(createEmptyConfig(), null, 2)}\\n`;\n try {\n await fs.writeFile(targetPath, emptyContent, { flag: \"wx\", mode: FILE_MODE });\n } catch (error) {\n if (getErrorCode(error) !== \"EEXIST\") throw error;\n }\n}\n\nasync function writeAtomicText(targetPath: string, content: string): Promise<void> {\n await fs.mkdir(dirname(targetPath), { recursive: true });\n const tempPath = buildTempPath(targetPath);\n try {\n await fs.writeFile(tempPath, content, { encoding: \"utf-8\", mode: FILE_MODE });\n await fs.chmod(tempPath, FILE_MODE);\n await fs.rename(tempPath, targetPath);\n await fs.chmod(targetPath, FILE_MODE);\n } catch (error) {\n try {\n await fs.unlink(tempPath);\n } catch {}\n throw error;\n }\n}\n\nasync function withConfigLock<T>(fn: (configPath: string) => Promise<T>): Promise<T> {\n const configPath = await resolveConfigPath();\n await ensureConfigFileExists(configPath);\n return await withDirectoryLock(configPath, () => fn(configPath));\n}\n\nfunction parsePoolChainConfig(content: string): PoolChainConfig | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch {\n return null;\n }\n\n const validation = v.safeParse(PoolChainConfigSchema, parsed);\n return validation.success ? validation.output : null;\n}\n\nexport async function loadPoolChainConfig(): Promise<PoolChainConfig> {\n const path = await resolveConfigPath();\n try {\n const content = await fs.readFile(path, \"utf-8\");\n return parsePoolChainConfig(content) ?? createEmptyConfig();\n } catch {\n return createEmptyConfig();\n }\n}\n\nexport async function savePoolChainConfig(config: PoolChainConfig): Promise<void> {\n await withConfigLock(async (configPath) => {\n const validation = v.safeParse(PoolChainConfigSchema, config);\n if (!validation.success) {\n throw new Error(\"Invalid pool/chain config payload\");\n }\n await writeAtomicText(configPath, `${JSON.stringify(validation.output, null, 2)}\\n`);\n });\n}\n","import type { ManagedAccount } from \"./types\";\nimport type { FailoverCandidate, FailoverSkip, PoolChainConfig, PoolConfig } from \"./pool-types\";\n\nconst DEFAULT_EXHAUSTED_COOLDOWN_MS = 5 * 60 * 1000;\n\ninterface PoolAwareAccountManager {\n getAccounts(): ManagedAccount[];\n isRateLimited(account: ManagedAccount): boolean;\n selectAccount(): Promise<ManagedAccount | null>;\n}\n\nexport interface BuildFailoverPlanOptions {\n attemptedAccounts?: Set<string>;\n visitedChainIndexes?: Set<number>;\n}\n\nexport interface FailoverPlan {\n candidates: FailoverCandidate[];\n skips: FailoverSkip[];\n}\n\nexport class PoolManager {\n private poolsByName = new Map<string, PoolConfig>();\n private exhaustedUntilByAccount = new Map<string, number>();\n private exhaustedCooldownMs: number;\n\n constructor(options?: { exhaustedCooldownMs?: number }) {\n this.exhaustedCooldownMs = options?.exhaustedCooldownMs ?? DEFAULT_EXHAUSTED_COOLDOWN_MS;\n }\n\n loadPools(configs: PoolConfig[]): void {\n this.poolsByName.clear();\n for (const pool of configs) {\n this.poolsByName.set(pool.name, pool);\n }\n }\n\n getPoolForAccount(accountUuid: string): PoolConfig | null {\n for (const pool of this.poolsByName.values()) {\n if (!pool.enabled) continue;\n if (pool.members.includes(accountUuid)) return pool;\n }\n return null;\n }\n\n getAvailableMembers(pool: PoolConfig, accountManager: PoolAwareAccountManager): string[] {\n if (!pool.enabled) return [];\n this.clearExpiredExhausted();\n\n const accountsByUuid = new Map<string, ManagedAccount>();\n for (const account of accountManager.getAccounts()) {\n if (!account.uuid) continue;\n accountsByUuid.set(account.uuid, account);\n }\n\n return pool.members.filter((accountUuid) => {\n const account = accountsByUuid.get(accountUuid);\n if (!account) return false;\n if (!account.enabled || account.isAuthDisabled) return false;\n if (this.isExhausted(accountUuid)) return false;\n if (accountManager.isRateLimited(account)) return false;\n return true;\n });\n }\n\n markExhausted(accountUuid: string): void {\n this.exhaustedUntilByAccount.set(accountUuid, Date.now() + this.exhaustedCooldownMs);\n }\n\n async getNextMember(\n pool: PoolConfig,\n currentUuid: string | undefined,\n accountManager: PoolAwareAccountManager,\n ): Promise<string | null> {\n const availableMembers = this.getAvailableMembers(pool, accountManager);\n if (availableMembers.length === 0) return null;\n\n const excluded = new Set<string>();\n if (currentUuid) excluded.add(currentUuid);\n\n const preferred = await this.selectPreferredMember(availableMembers, excluded, accountManager);\n if (preferred) return preferred;\n\n for (const candidate of availableMembers) {\n if (candidate !== currentUuid) return candidate;\n }\n\n return null;\n }\n\n async buildFailoverPlan(\n currentAccount: Pick<ManagedAccount, \"uuid\" | \"accountId\"> | null,\n config: PoolChainConfig,\n accountManager: PoolAwareAccountManager,\n options?: BuildFailoverPlanOptions,\n ): Promise<FailoverPlan> {\n this.loadPools(config.pools ?? []);\n\n if ((config.pools?.length ?? 0) === 0 && (config.chains?.length ?? 0) === 0) {\n return { candidates: [], skips: [] };\n }\n\n const attemptedAccounts = options?.attemptedAccounts ?? new Set<string>();\n const visitedChainIndexes = options?.visitedChainIndexes ?? new Set<number>();\n const currentUuid = currentAccount?.uuid;\n\n const candidates: FailoverCandidate[] = [];\n const skips: FailoverSkip[] = [];\n const addedCandidateUuids = new Set<string>();\n\n const appendPoolCandidates = async (\n poolName: string,\n source: \"pool\" | \"chain\",\n chainIndex?: number,\n ): Promise<void> => {\n const pool = this.poolsByName.get(poolName);\n if (!pool || !pool.enabled) {\n skips.push({\n type: \"chain_disabled\",\n poolName,\n reason: \"Pool is missing or disabled\",\n });\n return;\n }\n\n const available = this.getAvailableMembers(pool, accountManager);\n if (available.length === 0) {\n skips.push({\n type: \"pool_exhausted\",\n poolName,\n reason: \"No available members\",\n });\n return;\n }\n\n const poolExclusions = new Set<string>();\n if (currentUuid) poolExclusions.add(currentUuid);\n\n while (poolExclusions.size < available.length + (currentUuid ? 1 : 0)) {\n const nextMember = await this.selectPreferredMember(available, poolExclusions, accountManager);\n if (!nextMember) break;\n\n poolExclusions.add(nextMember);\n\n if (attemptedAccounts.has(nextMember)) {\n skips.push({\n type: \"account_attempted\",\n poolName,\n reason: \"Already attempted in this cascade\",\n detail: nextMember,\n });\n continue;\n }\n\n if (addedCandidateUuids.has(nextMember)) continue;\n\n candidates.push({\n poolName,\n accountUuid: nextMember,\n source,\n chainIndex,\n });\n addedCandidateUuids.add(nextMember);\n }\n\n for (const memberUuid of available) {\n if (poolExclusions.has(memberUuid)) continue;\n if (attemptedAccounts.has(memberUuid)) {\n skips.push({\n type: \"account_attempted\",\n poolName,\n reason: \"Already attempted in this cascade\",\n detail: memberUuid,\n });\n continue;\n }\n if (addedCandidateUuids.has(memberUuid)) continue;\n\n candidates.push({\n poolName,\n accountUuid: memberUuid,\n source,\n chainIndex,\n });\n addedCandidateUuids.add(memberUuid);\n }\n };\n\n if (currentUuid) {\n const currentPool = this.getPoolForAccount(currentUuid);\n if (currentPool) {\n await appendPoolCandidates(currentPool.name, \"pool\");\n }\n }\n\n let flattenedChainIndex = 0;\n for (const chain of config.chains ?? []) {\n if (!chain.enabled) {\n for (let i = 0; i < chain.entries.length; i++) {\n skips.push({\n type: \"chain_disabled\",\n poolName: chain.entries[i]?.pool ?? chain.name,\n reason: `Chain '${chain.name}' is disabled`,\n });\n flattenedChainIndex += 1;\n }\n continue;\n }\n\n for (const entry of chain.entries) {\n if (visitedChainIndexes.has(flattenedChainIndex)) {\n skips.push({\n type: \"chain_disabled\",\n poolName: entry.pool,\n reason: \"Chain entry already visited in this cascade\",\n detail: `${flattenedChainIndex}`,\n });\n flattenedChainIndex += 1;\n continue;\n }\n\n if (!entry.enabled) {\n skips.push({\n type: \"chain_disabled\",\n poolName: entry.pool,\n reason: \"Chain entry is disabled\",\n detail: `${flattenedChainIndex}`,\n });\n flattenedChainIndex += 1;\n continue;\n }\n\n await appendPoolCandidates(entry.pool, \"chain\", flattenedChainIndex);\n flattenedChainIndex += 1;\n }\n }\n\n return { candidates, skips };\n }\n\n private isExhausted(accountUuid: string): boolean {\n const exhaustedUntil = this.exhaustedUntilByAccount.get(accountUuid);\n if (!exhaustedUntil) return false;\n if (Date.now() >= exhaustedUntil) {\n this.exhaustedUntilByAccount.delete(accountUuid);\n return false;\n }\n return true;\n }\n\n private clearExpiredExhausted(): void {\n const now = Date.now();\n for (const [accountUuid, exhaustedUntil] of this.exhaustedUntilByAccount.entries()) {\n if (now >= exhaustedUntil) this.exhaustedUntilByAccount.delete(accountUuid);\n }\n }\n\n private async selectPreferredMember(\n availableMembers: string[],\n excludedMembers: Set<string>,\n accountManager: PoolAwareAccountManager,\n ): Promise<string | null> {\n const availableSet = new Set(availableMembers);\n const maxAttempts = Math.max(availableMembers.length * 2, 6);\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const selected = await accountManager.selectAccount();\n if (!selected?.uuid) continue;\n if (!availableSet.has(selected.uuid)) continue;\n if (excludedMembers.has(selected.uuid)) continue;\n return selected.uuid;\n }\n\n for (const memberUuid of availableMembers) {\n if (!excludedMembers.has(memberUuid)) return memberUuid;\n }\n return null;\n }\n}\n","import type { CascadeState } from \"./pool-types\";\n\nfunction createCascadeState(prompt: string, currentAccountUuid?: string): CascadeState {\n const attemptedAccounts = new Set<string>();\n if (currentAccountUuid) {\n attemptedAccounts.add(currentAccountUuid);\n }\n\n return {\n prompt,\n attemptedAccounts,\n visitedChainIndexes: new Set<number>(),\n };\n}\n\nexport class CascadeStateManager {\n public suppressNextStartTurn = false;\n private cascadeState: CascadeState | null = null;\n\n startTurn(prompt: string, currentAccountUuid?: string): CascadeState {\n if (this.suppressNextStartTurn) {\n this.suppressNextStartTurn = false;\n return this.ensureCascadeState(prompt, currentAccountUuid);\n }\n\n const shouldReset = !this.cascadeState || this.cascadeState.prompt !== prompt;\n if (shouldReset) {\n this.cascadeState = createCascadeState(prompt, currentAccountUuid);\n return this.cascadeState;\n }\n\n return this.ensureCascadeState(prompt, currentAccountUuid);\n }\n\n ensureCascadeState(prompt: string, currentAccountUuid?: string): CascadeState {\n if (!this.cascadeState || this.cascadeState.prompt !== prompt) {\n this.cascadeState = createCascadeState(prompt, currentAccountUuid);\n return this.cascadeState;\n }\n\n if (currentAccountUuid) {\n this.cascadeState.attemptedAccounts.add(currentAccountUuid);\n }\n\n return this.cascadeState;\n }\n\n markAttempted(accountUuid: string): void {\n if (!this.cascadeState) return;\n this.cascadeState.attemptedAccounts.add(accountUuid);\n }\n\n markVisitedChainIndex(index: number): void {\n if (!this.cascadeState) return;\n this.cascadeState.visitedChainIndexes.add(index);\n }\n\n clearCascadeState(): void {\n this.cascadeState = null;\n this.suppressNextStartTurn = false;\n }\n\n getSnapshot(): CascadeState | null {\n if (!this.cascadeState) return null;\n return {\n prompt: this.cascadeState.prompt,\n attemptedAccounts: new Set(this.cascadeState.attemptedAccounts),\n visitedChainIndexes: new Set(this.cascadeState.visitedChainIndexes),\n };\n }\n}\n"],"mappings":"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","names":["fs","randomBytes","dirname","join","join","homedir","v","content","getConfigDir","join","homedir","join","getConfigDir","randomBytes","fs","dirname","fs","randomBytes","dirname","join","v","fs","dirname","join","v","join","getConfigDir","fs","dirname","fs","dirname","sleep","join","getConfigDir","randomBytes","fs","dirname","formatWaitTime","sleep","showToast","getAccountLabel","getConfig","debugLog","getConfig","formatWaitTime","getAccountLabel","showToast","fs","join","join","getConfigDir","fs","v","fs","randomBytes","dirname","join","v","FILE_MODE","join","getConfigDir","buildTempPath","randomBytes","fs","dirname","writeAtomicText"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-multi-account-core",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Shared core for multi-account OpenCode plugins",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",