/** * OAuth credential management for AI providers. * * This module handles login, token refresh, and credential storage * for OAuth-based providers: * - Anthropic (Claude Pro/Max) * - GitHub Copilot * - Google Cloud Code Assist (Gemini CLI) * - Antigravity (Gemini 3, Claude, GPT-OSS via Google Cloud) */ // Anthropic export { anthropicOAuthProvider, loginAnthropic, refreshAnthropicToken } from "./anthropic.js"; // GitHub Copilot export { getGitHubCopilotBaseUrl, githubCopilotOAuthProvider, loginGitHubCopilot, normalizeDomain, refreshGitHubCopilotToken, } from "./github-copilot.js"; // Google Antigravity export { antigravityOAuthProvider, loginAntigravity, refreshAntigravityToken } from "./google-antigravity.js"; // Google Gemini CLI export { geminiCliOAuthProvider, loginGeminiCli, refreshGoogleCloudToken } from "./google-gemini-cli.js"; // OpenAI Codex (ChatGPT OAuth) export { loginOpenAICodex, openaiCodexOAuthProvider, refreshOpenAICodexToken } from "./openai-codex.js"; export * from "./types.js"; // ============================================================================ // Provider Registry // ============================================================================ import { anthropicOAuthProvider } from "./anthropic.js"; import { githubCopilotOAuthProvider } from "./github-copilot.js"; import { antigravityOAuthProvider } from "./google-antigravity.js"; import { geminiCliOAuthProvider } from "./google-gemini-cli.js"; import { openaiCodexOAuthProvider } from "./openai-codex.js"; import type { OAuthCredentials, OAuthProviderId, OAuthProviderInfo, OAuthProviderInterface } from "./types.js"; const oauthProviderRegistry = new Map([ [anthropicOAuthProvider.id, anthropicOAuthProvider], [githubCopilotOAuthProvider.id, githubCopilotOAuthProvider], [geminiCliOAuthProvider.id, geminiCliOAuthProvider], [antigravityOAuthProvider.id, antigravityOAuthProvider], [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider], ]); /** * Get an OAuth provider by ID */ export function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined { return oauthProviderRegistry.get(id); } /** * Register a custom OAuth provider */ export function registerOAuthProvider(provider: OAuthProviderInterface): void { oauthProviderRegistry.set(provider.id, provider); } /** * Get all registered OAuth providers */ export function getOAuthProviders(): OAuthProviderInterface[] { return Array.from(oauthProviderRegistry.values()); } /** * @deprecated Use getOAuthProviders() which returns OAuthProviderInterface[] */ export function getOAuthProviderInfoList(): OAuthProviderInfo[] { return getOAuthProviders().map((p) => ({ id: p.id, name: p.name, available: true, })); } // ============================================================================ // High-level API (uses provider registry) // ============================================================================ /** * Refresh token for any OAuth provider. * @deprecated Use getOAuthProvider(id).refreshToken() instead */ export async function refreshOAuthToken( providerId: OAuthProviderId, credentials: OAuthCredentials, ): Promise { const provider = getOAuthProvider(providerId); if (!provider) { throw new Error(`Unknown OAuth provider: ${providerId}`); } return provider.refreshToken(credentials); } /** * Get API key for a provider from OAuth credentials. * Automatically refreshes expired tokens. * * @returns API key string and updated credentials, or null if no credentials * @throws Error if refresh fails */ export async function getOAuthApiKey( providerId: OAuthProviderId, credentials: Record, ): Promise<{ newCredentials: OAuthCredentials; apiKey: string } | null> { const provider = getOAuthProvider(providerId); if (!provider) { throw new Error(`Unknown OAuth provider: ${providerId}`); } let creds = credentials[providerId]; if (!creds) { return null; } // Refresh if expired if (Date.now() >= creds.expires) { try { creds = await provider.refreshToken(creds); } catch (_error) { throw new Error(`Failed to refresh OAuth token for ${providerId}`); } } const apiKey = provider.getApiKey(creds); return { newCredentials: creds, apiKey }; }