import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { SkeletonPulse } from '@/components/ui/skeleton'; import { Spinner } from '@/components/ui/spinner'; import { CheckCircle2, AlertCircle, RefreshCw, Bot, Cloud } from 'lucide-react'; import { cn } from '@/lib/utils'; import type { CliStatus } from '../shared/types'; import { OpenCodeIcon } from '@/components/ui/provider-icon'; export interface OpenCodeProviderInfo { id: string; name: string; authenticated: boolean; authMethod?: 'oauth' | 'api_key'; } /** * Provider display configuration */ const PROVIDER_DISPLAY: Record = { copilot: 'GitHub Copilot', 'github-copilot': 'GitHub Copilot', anthropic: 'Anthropic', openai: 'OpenAI', openrouter: 'OpenRouter', google: 'Google AI', 'amazon-bedrock': 'AWS Bedrock', azure: 'Azure OpenAI', ollama: 'Ollama', lmstudio: 'LM Studio', opencode: 'OpenCode', xai: 'xAI', deepseek: 'DeepSeek', }; function getProviderDisplayName(provider: OpenCodeProviderInfo): string { return PROVIDER_DISPLAY[provider.id] || provider.name || provider.id; } export type OpencodeAuthMethod = | 'api_key_env' // ANTHROPIC_API_KEY or other provider env vars | 'api_key' // Manually stored API key | 'oauth' // OAuth authentication | 'config_file' // Config file with credentials | 'none'; export interface OpencodeAuthStatus { authenticated: boolean; method: OpencodeAuthMethod; hasApiKey?: boolean; hasEnvApiKey?: boolean; hasOAuthToken?: boolean; error?: string; } function getAuthMethodLabel(method: OpencodeAuthMethod): string { switch (method) { case 'api_key': return 'API Key'; case 'api_key_env': return 'API Key (Environment)'; case 'oauth': return 'OAuth Authentication'; case 'config_file': return 'Configuration File'; default: return method || 'Unknown'; } } interface OpencodeCliStatusProps { status: CliStatus | null; authStatus?: OpencodeAuthStatus | null; providers?: OpenCodeProviderInfo[]; isChecking: boolean; onRefresh: () => void; } export function OpencodeCliStatusSkeleton() { return (
{/* Installation status skeleton */}
{/* Auth status skeleton */}
); } export function OpencodeModelConfigSkeleton() { return (
{/* Default Model skeleton */}
{/* Available Models skeleton */}
{/* Provider group skeleton */}
{[1, 2, 3].map((i) => (
))}
); } export function OpencodeCliStatus({ status, authStatus, providers = [], isChecking, onRefresh, }: OpencodeCliStatusProps) { const authenticatedProviders = providers.filter((p) => p.authenticated); if (!status) return ; return (

OpenCode CLI

OpenCode CLI provides multi-provider AI support with Claude, GPT, and Gemini models.

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

OpenCode CLI Installed

{status.method && (

Method: {status.method}

)} {status.version && (

Version: {status.version}

)} {status.path && (

Path: {status.path}

)}
{/* Authentication Status - consider both direct auth and provider auth */} {authStatus?.authenticated || authenticatedProviders.length > 0 ? (

Authenticated

{authStatus?.authenticated && authStatus.method !== 'none' ? (

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

) : authenticatedProviders.length > 0 ? (

Via {authenticatedProviders.length} connected provider {authenticatedProviders.length !== 1 ? 's' : ''}

) : null}
) : (

OpenCode Free Tier Ready

Free OpenCode models work without login. Run{' '} opencode auth login {' '} to connect providers like GitHub Copilot, Google AI, etc.

)} {/* Dynamic Providers Connected */} {authenticatedProviders.length > 0 && (

{authenticatedProviders.length} Dynamic Provider {authenticatedProviders.length !== 1 ? 's' : ''} Connected

{authenticatedProviders.map((provider) => ( {getProviderDisplayName(provider)} {provider.authMethod && ( ({provider.authMethod === 'oauth' ? 'OAuth' : 'Key'}) )} ))}

Use{' '} opencode auth login {' '} to add more providers.

)} {status.recommendation && (

{status.recommendation}

)}
) : (

OpenCode CLI Not Detected

{status.recommendation || 'Install OpenCode CLI to use multi-provider AI models.'}

{status.installCommands && (

Installation Commands:

{status.installCommands.npm && (

npm

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

macOS/Linux

{status.installCommands.macos}
)}
)}
)}
); }