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 { CursorIcon } from '@/components/ui/provider-icon'; import { getElectronAPI } from '@/lib/electron'; import { toast } from 'sonner'; interface CursorStatus { installed: boolean; version?: string; authenticated: boolean; method?: string; } interface CursorCliStatusProps { status: CursorStatus | null; isChecking: boolean; onRefresh: () => void; } export function CursorCliStatusSkeleton() { return (
{/* Installation status skeleton */}
{/* Auth status skeleton */}
); } export function CursorPermissionsSkeleton() { return (
{/* Security Warning skeleton */}
{/* Permission Profiles skeleton */}
{[1, 2].map((i) => (
))}
{/* Config File Locations skeleton */}
); } export function ModelConfigSkeleton() { return (
{/* Default Model skeleton */}
{/* Available Models skeleton */}
{[1, 2, 3, 4].map((i) => (
))}
); } export function CursorCliStatus({ status, isChecking, onRefresh }: CursorCliStatusProps) { const [isAuthenticating, setIsAuthenticating] = useState(false); const [isDeauthenticating, setIsDeauthenticating] = useState(false); const handleSignIn = useCallback(async () => { setIsAuthenticating(true); try { const api = getElectronAPI(); // Check if authCursor method exists on the API const authCursor = (api?.setup as Record | undefined)?.authCursor as | (() => Promise<{ success: boolean; error?: string }>) | undefined; if (!authCursor) { toast.error('Authentication Failed', { description: 'Cursor authentication is not available', }); return; } const result = await authCursor(); if (result.success) { toast.success('Signed In', { description: 'Successfully authenticated Cursor 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 deauthCursor method exists on the API const deauthCursor = (api?.setup as Record | undefined)?.deauthCursor as | (() => Promise<{ success: boolean; error?: string }>) | undefined; if (!deauthCursor) { toast.error('Sign Out Failed', { description: 'Cursor sign out is not available', }); return; } const result = await deauthCursor(); if (result.success) { toast.success('Signed Out', { description: 'Successfully signed out from Cursor 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 (

Cursor CLI

Cursor CLI enables AI-powered code editing using Cursor's models.

{status.installed ? (
{/* Installation Status - Success */}

Cursor CLI Installed

{status.version && (

Version: {status.version}

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

Authenticated

Method:{' '} {status.method === 'api_key' ? 'API Key' : 'Browser Login'}

) : (

Not Authenticated

Click Sign In below to get authentication instructions.

)}
) : (

Cursor CLI Not Detected

Install Cursor CLI to use Cursor models in AutoMaker.

)}
); }