import { useEffect, useRef, useCallback } from 'react'; import { useSetupStore, type ClaudeAuthMethod, type CodexAuthMethod } from '@/store/setup-store'; import { getHttpApiClient } from '@/lib/http-api-client'; import { createLogger } from '@automaker/utils/logger'; const logger = createLogger('ProviderAuthInit'); /** * Hook to initialize Claude and Codex authentication statuses on app startup. * This ensures that usage tracking information is available in the board header * without needing to visit the settings page first. */ export function useProviderAuthInit() { const { setClaudeAuthStatus, setCodexAuthStatus, claudeAuthStatus, codexAuthStatus } = useSetupStore(); const initialized = useRef(false); const refreshStatuses = useCallback(async () => { const api = getHttpApiClient(); // 1. Claude Auth Status try { const result = await api.setup.getClaudeStatus(); if (result.success && result.auth) { // Cast to extended type that includes server-added fields const auth = result.auth as typeof result.auth & { oauthTokenValid?: boolean; apiKeyValid?: boolean; }; const validMethods: ClaudeAuthMethod[] = [ 'oauth_token_env', 'oauth_token', 'api_key', 'api_key_env', 'credentials_file', 'cli_authenticated', 'none', ]; const method = validMethods.includes(auth.method as ClaudeAuthMethod) ? (auth.method as ClaudeAuthMethod) : ((auth.authenticated ? 'api_key' : 'none') as ClaudeAuthMethod); setClaudeAuthStatus({ authenticated: auth.authenticated, method, hasCredentialsFile: auth.hasCredentialsFile ?? false, oauthTokenValid: !!( auth.oauthTokenValid || auth.hasStoredOAuthToken || auth.hasEnvOAuthToken ), apiKeyValid: !!(auth.apiKeyValid || auth.hasStoredApiKey || auth.hasEnvApiKey), hasEnvOAuthToken: !!auth.hasEnvOAuthToken, hasEnvApiKey: !!auth.hasEnvApiKey, }); } } catch (error) { logger.error('Failed to init Claude auth status:', error); } // 2. Codex Auth Status try { const result = await api.setup.getCodexStatus(); if (result.success && result.auth) { const auth = result.auth; const validMethods: CodexAuthMethod[] = [ 'api_key_env', 'api_key', 'cli_authenticated', 'none', ]; const method = validMethods.includes(auth.method as CodexAuthMethod) ? (auth.method as CodexAuthMethod) : ((auth.authenticated ? 'api_key' : 'none') as CodexAuthMethod); setCodexAuthStatus({ authenticated: auth.authenticated, method, hasAuthFile: auth.hasAuthFile ?? false, hasApiKey: auth.hasApiKey ?? false, hasEnvApiKey: auth.hasEnvApiKey ?? false, }); } } catch (error) { logger.error('Failed to init Codex auth status:', error); } }, [setClaudeAuthStatus, setCodexAuthStatus]); useEffect(() => { // Only initialize once per session if not already set if (initialized.current || (claudeAuthStatus !== null && codexAuthStatus !== null)) { return; } initialized.current = true; void refreshStatuses(); }, [refreshStatuses, claudeAuthStatus, codexAuthStatus]); }