import { useState } from 'react'; import { Coins, MessageSquare, Database, Zap, Loader2, Brain, ShieldCheck, FileEdit, ChevronDown } from 'lucide-react'; // Permission mode definitions with display info const PERMISSION_MODES = [ { value: 'default', label: 'Default', icon: ShieldCheck, color: 'text-blue-400', description: 'Prompts for dangerous tools' }, { value: 'acceptEdits', label: 'Accept Edits', icon: FileEdit, color: 'text-green-400', description: 'Auto-accept file edits' }, { value: 'plan', label: 'Plan', icon: Brain, color: 'text-purple-400', description: 'Planning mode only' }, { value: 'bypassPermissions', label: 'Bypass', icon: Zap, color: 'text-orange-400', description: 'Allow all tools (careful!)' }, ]; export function StatusBar({ sessionStats, isProcessing, connected, permissionMode = 'default', controlInitialized, onChangeMode }) { const [showModeMenu, setShowModeMenu] = useState(false); const { totalCost = 0, inputTokens = 0, outputTokens = 0, cacheReadTokens = 0, cacheCreationTokens = 0, numTurns = 0, contextWindow = 200000, contextLeftPercent = null, // Live context tracking from message_delta events tokensUsed = 0, isCompacting = false, } = sessionStats || {}; // Get current mode info const currentMode = PERMISSION_MODES.find(m => m.value === permissionMode) || PERMISSION_MODES[0]; const ModeIcon = currentMode.icon; // Context used percentage (0-100) - bar fills up as context is consumed const contextRemaining = contextLeftPercent; const contextUsedPercent = contextRemaining !== null ? (100 - contextRemaining) : 0; // Determine color based on usage (higher usage = more warning) const getContextColor = (usedPercent) => { if (usedPercent === null) return 'bg-dark-600'; if (usedPercent >= 95) return 'bg-red-500'; if (usedPercent >= 85) return 'bg-red-400'; if (usedPercent >= 70) return 'bg-yellow-400'; if (usedPercent >= 50) return 'bg-yellow-300'; return 'bg-green-400'; }; const getContextTextColor = (usedPercent) => { if (usedPercent === null) return 'text-dark-500'; if (usedPercent >= 95) return 'text-red-400 font-medium animate-pulse'; if (usedPercent >= 85) return 'text-red-400'; if (usedPercent >= 70) return 'text-yellow-400'; return 'text-green-400'; }; // Format cost const formatCost = (cost) => { if (cost < 0.01) return `$${cost.toFixed(4)}`; if (cost < 1) return `$${cost.toFixed(3)}`; return `$${cost.toFixed(2)}`; }; // Format token count const formatTokens = (tokens) => { if (tokens >= 1000000) return `${(tokens / 1000000).toFixed(1)}M`; if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}k`; return tokens.toString(); }; return (
{/* Left side: Stats */}
{/* Connection status */}
{connected ? 'Connected' : 'Disconnected'}
{/* Processing indicator */} {isProcessing && (
Processing...
)} {/* Compacting indicator */} {isCompacting && (
Compacting context...
)} {/* Turns */} {numTurns > 0 && (
{numTurns} turns
)} {/* Cost */} {totalCost > 0 && (
{formatCost(totalCost)}
)} {/* Permission Mode Toggle - show always for debugging, just disabled when not initialized */} {(
{showModeMenu && (
{PERMISSION_MODES.map((mode) => { const Icon = mode.icon; const isActive = mode.value === permissionMode; return ( ); })}
)}
)}
{/* Right side: Context usage with progress bar */}
{/* Context progress bar - always visible when we have data */} {contextRemaining !== null && (
{/* Progress bar container - fills up as context is used */}
{/* Percentage text - shows how full the context is */} {contextUsedPercent}%
)} {/* Show "waiting" state if no context data yet */} {contextRemaining === null && connected && (
Context: --
)}
); }