spool-memory 0.2.3

Local-first developer memory system — persistent, structured knowledge for AI coding tools
Documentation
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import type { DesktopErrorEnvelope } from '@/lib/types/desktop'

const kindLabel: Record<DesktopErrorEnvelope['kind'], string> = {
  input: '输入校验失败',
  config: '配置错误',
  routing: '项目路由错误',
  scan: '库扫描错误',
  runtime: '运行时错误',
}

const kindVariant: Record<
  DesktopErrorEnvelope['kind'],
  'destructive' | 'secondary' | 'default'
> = {
  input: 'secondary',
  config: 'secondary',
  routing: 'secondary',
  scan: 'secondary',
  runtime: 'destructive',
}

export function ErrorBanner({ envelope }: { envelope: DesktopErrorEnvelope }) {
  return (
    <Card className="border-destructive/40 bg-destructive/5">
      <CardContent className="space-y-2 p-4">
        <div className="flex items-center gap-2">
          <Badge variant={kindVariant[envelope.kind]}>
            {kindLabel[envelope.kind]}
          </Badge>
          <span className="text-sm font-medium text-destructive">
            {envelope.message}
          </span>
        </div>
        {envelope.hint && (
          <p className="text-xs text-muted-foreground">{envelope.hint}</p>
        )}
        {envelope.explain && envelope.explain !== envelope.message && (
          <pre className="max-h-48 overflow-auto rounded-md bg-muted/50 p-2 text-xs">
            {envelope.explain}
          </pre>
        )}
      </CardContent>
    </Card>
  )
}