()
| 1447 | * (which don't hit the keychain), and only uses async for storage reads. |
| 1448 | */ |
| 1449 | export async function getClaudeAIOAuthTokensAsync(): Promise<OAuthTokens | null> { |
| 1450 | if (isBareMode()) return null |
| 1451 | |
| 1452 | // Env var and FD tokens are sync and don't hit the keychain |
| 1453 | if ( |
| 1454 | process.env.CLAUDE_CODE_OAUTH_TOKEN || |
| 1455 | getOAuthTokenFromFileDescriptor() |
| 1456 | ) { |
| 1457 | return getClaudeAIOAuthTokens() |
| 1458 | } |
| 1459 | |
| 1460 | try { |
| 1461 | const secureStorage = getSecureStorage() |
| 1462 | const storageData = await secureStorage.readAsync() |
| 1463 | const oauthData = storageData?.claudeAiOauth |
| 1464 | if (!oauthData?.accessToken) { |
| 1465 | return null |
| 1466 | } |
| 1467 | return oauthData |
| 1468 | } catch (error) { |
| 1469 | logError(error) |
| 1470 | return null |
| 1471 | } |
| 1472 | } |
| 1473 | |
| 1474 | // In-flight promise for deduplicating concurrent calls |
| 1475 | let pendingRefreshCheck: Promise<boolean> | null = null |
no test coverage detected