From fec5f88d91896ee40407b89282d493a052854e89 Mon Sep 17 00:00:00 2001 From: Manuel Grillo Date: Wed, 14 Jan 2026 21:44:33 +0100 Subject: [PATCH] feat: add GitHub Copilot support for OAuth token validation --- libs/platform/src/system-paths.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/libs/platform/src/system-paths.ts b/libs/platform/src/system-paths.ts index 31382a33..8c212561 100644 --- a/libs/platform/src/system-paths.ts +++ b/libs/platform/src/system-paths.ts @@ -1214,7 +1214,16 @@ const OPENCODE_OAUTH_KEYS = ['access_token', 'oauth_token'] as const; const OPENCODE_API_KEY_KEYS = ['api_key', 'OPENAI_API_KEY', 'ANTHROPIC_API_KEY'] as const; // Provider names that OpenCode uses for provider-specific auth entries -const OPENCODE_PROVIDERS = ['anthropic', 'openai', 'google', 'bedrock', 'amazon-bedrock'] as const; +// NOTE: github-copilot uses refresh tokens, so 'access' may be empty but 'refresh' is valid +const OPENCODE_PROVIDERS = [ + 'anthropic', + 'openai', + 'google', + 'bedrock', + 'amazon-bedrock', + 'github-copilot', + 'copilot', +] as const; function getOpenCodeNestedTokens(record: Record): Record | null { const tokens = record[OPENCODE_TOKENS_KEY]; @@ -1227,20 +1236,30 @@ function getOpenCodeNestedTokens(record: Record): Record): boolean { for (const provider of OPENCODE_PROVIDERS) { const providerAuth = authJson[provider]; if (providerAuth && typeof providerAuth === 'object' && !Array.isArray(providerAuth)) { const auth = providerAuth as Record; - // Check for OAuth type with access token - if (auth.type === 'oauth' && typeof auth.access === 'string' && auth.access) { - return true; + // Check for OAuth type with access token OR refresh token (GitHub Copilot uses refresh tokens) + if (auth.type === 'oauth') { + if ( + (typeof auth.access === 'string' && auth.access) || + (typeof auth.refresh === 'string' && auth.refresh) + ) { + return true; + } } // Also check for access_token field directly if (typeof auth.access_token === 'string' && auth.access_token) { return true; } + // Check for refresh_token field directly + if (typeof auth.refresh_token === 'string' && auth.refresh_token) { + return true; + } } } return false;