import { useState, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { SkeletonPulse } from '@/components/ui/skeleton'; import { Spinner } from '@/components/ui/spinner'; import { CheckCircle2, AlertCircle, RefreshCw, XCircle } from 'lucide-react'; import { cn } from '@/lib/utils'; import type { CliStatus } from '../shared/types'; import type { CodexAuthStatus } from '@/store/setup-store'; import { OpenAIIcon } from '@/components/ui/provider-icon'; import { getElectronAPI } from '@/lib/electron'; import { toast } from 'sonner'; interface CliStatusProps { status: CliStatus | null; authStatus?: CodexAuthStatus | null; isChecking: boolean; onRefresh: () => void; } function getAuthMethodLabel(method: string): string { switch (method) { case 'api_key': return 'API Key'; case 'api_key_env': return 'API Key (Environment)'; case 'cli_authenticated': case 'oauth': return 'CLI Authentication'; default: return method || 'Unknown'; } } function CodexCliStatusSkeleton() { return (
{/* Installation status skeleton */}
{/* Auth status skeleton */}
); } export function CodexCliStatus({ status, authStatus, isChecking, onRefresh }: CliStatusProps) { const [isAuthenticating, setIsAuthenticating] = useState(false); const [isDeauthenticating, setIsDeauthenticating] = useState(false); const handleSignIn = useCallback(async () => { setIsAuthenticating(true); try { const api = getElectronAPI(); // Check if authCodex method exists on the API const authCodex = (api.setup as Record | undefined)?.authCodex as | (() => Promise<{ success: boolean; error?: string }>) | undefined; if (!authCodex) { toast.error('Authentication Failed', { description: 'Codex authentication is not available', }); return; } const result = await authCodex(); if (result.success) { toast.success('Signed In', { description: 'Successfully authenticated Codex CLI', }); onRefresh(); } else if (result.error) { toast.error('Authentication Failed', { description: result.error, }); } } catch (error) { toast.error('Authentication Failed', { description: error instanceof Error ? error.message : 'Unknown error', }); } finally { setIsAuthenticating(false); } }, [onRefresh]); const handleSignOut = useCallback(async () => { setIsDeauthenticating(true); try { const api = getElectronAPI(); // Check if deauthCodex method exists on the API const deauthCodex = (api.setup as Record | undefined)?.deauthCodex as | (() => Promise<{ success: boolean; error?: string }>) | undefined; if (!deauthCodex) { toast.error('Sign Out Failed', { description: 'Codex sign out is not available', }); return; } const result = await deauthCodex(); if (result.success) { toast.success('Signed Out', { description: 'Successfully signed out from Codex CLI', }); // Refresh status after successful logout onRefresh(); } else if (result.error) { toast.error('Sign Out Failed', { description: result.error, }); } } catch (error) { toast.error('Sign Out Failed', { description: error instanceof Error ? error.message : 'Unknown error', }); } finally { setIsDeauthenticating(false); } }, [onRefresh]); if (!status) return ; return (

Codex CLI

Codex CLI powers OpenAI models for coding and automation workflows.

{status.success && status.status === 'installed' ? (

Codex CLI Installed

{status.method && (

Method: {status.method}

)} {status.version && (

Version: {status.version}

)} {status.path && (

Path: {status.path}

)}
{/* Authentication Status */} {authStatus?.authenticated ? (

Authenticated

Method:{' '} {getAuthMethodLabel(authStatus.method)}

) : (

Not Authenticated

Click Sign In below to get authentication instructions.

)} {status.recommendation && (

{status.recommendation}

)}
) : (

Codex CLI Not Detected

{status.recommendation || 'Install Codex CLI to unlock OpenAI models with tool support.'}

{status.installCommands && (

Installation Commands:

{status.installCommands.npm && (

npm

{status.installCommands.npm}
)} {status.installCommands.macos && (

macOS/Linux

{status.installCommands.macos}
)} {status.installCommands.windows && (

Windows (PowerShell)

{status.installCommands.windows}
)}
)}
)}
); }