import { type ReactNode, useEffect, useState } from 'react'; import { RefreshCw, TerminalSquare } from 'lucide-react'; import { motion } from 'motion/react'; import { TextMorph } from 'torph/react'; import spinners from 'unicode-animations'; import type { BrailleSpinnerName } from 'unicode-animations'; import type { InstalledSkillsScopeState, UpdateSkillsResponse } from '../../features/skills/state'; import type { SkillScope } from '../../features/skills/types'; import { Badge } from '../components/ui/badge'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; import { cn } from '../lib/utils'; import type { InstallOutcome, RemoveOutcome } from './types'; import { scopeLabel } from './utils'; export function SummaryCard(props: { title: string; subtitle: string; icon: ReactNode; count: number; }) { return ( {props.icon} {props.title} {props.count} {props.subtitle} ); } export function StatusBanner(props: { icon: ReactNode; className: string; message: string }) { return ( {props.icon}

{props.message}

); } export function RemoveOperationCard(props: { outcome: RemoveOutcome }) { const { command, names, scope, status } = props.outcome; return ( Remove Command Output Removed {names.length} skill{names.length === 1 ? '' : 's'} from {scopeLabel(scope)}{' '} scope
{command.command.join(' ')} {status === 'success' ? 'Succeeded' : 'Failed'}
{command.stdout.trim() ? ( ) : (

No stdout output.

)} {command.stderr.trim() ? : null}
); } export function InstallOperationCard(props: { outcome: InstallOutcome }) { const { command, source, scope, status } = props.outcome; return ( Install Command Output Installed {source} in {scopeLabel(scope)} scope
{command.command.join(' ')} {status === 'success' ? 'Succeeded' : 'Failed'}
{command.stdout.trim() ? ( ) : (

No stdout output.

)} {command.stderr.trim() ? : null}
); } export function UpdateOperationCard(props: { results: UpdateSkillsResponse[] }) { return ( Update Command Output Latest `npx skills update` output {props.results.map((result, index) => (
{scopeLabel(result.scope)} {result.command.command.join(' ')}
{result.command.ok ? 'Succeeded' : 'Failed'}
{result.command.stdout.trim() ? ( ) : (

No stdout output.

)} {result.command.stderr.trim() ? ( ) : null}
))}
); } export function CommandOutputCard(props: { scope: SkillScope; scopeState: InstalledSkillsScopeState; }) { const { scope, scopeState } = props; const command = scopeState.command; return ( {scopeLabel(scope)} Command Output Latest `npx skills` output for this scope {command ? ( <>
{command.command.join(' ')} {command.ok ? 'Succeeded' : 'Failed'}
{command.stdout.trim() ? ( ) : (

No stdout output.

)} {command.stderr.trim() ? : null} {scopeState.error ? (

{scopeState.error}

) : null} {scopeState.stale ? (

Showing stale data from previous successful load.

) : null} ) : (

No command output available yet.

)}
); } export function OutputBlock(props: { label: string; value: string }) { return (

{props.label}

        {props.value.trim()}
      
); } export function AnimatedText(props: { children: string; className?: string; as?: 'span' | 'p' }) { return ( {props.children} ); } export function Spinner(props: { label?: string; className?: string; name?: BrailleSpinnerName; size?: number; }) { const name = props.name ?? 'braille'; const [frame, setFrame] = useState(0); useEffect(() => { const s = spinners[name]; const timer = setInterval(() => setFrame((f) => (f + 1) % s.frames.length), s.interval); return () => clearInterval(timer); }, [name]); return ( {spinners[name].frames[frame]} ); } export function LoadingIndicator(props: { label: string; className?: string }) { return (
{props.label}
); } export function PageLoadingState() { return (
); } export function MetadataRow(props: { label: string; value: string; mono?: boolean }) { return (
{props.label}
{props.value}
); }