{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "vulnerability-scanner-report",
  "title": "Vulnerability Scanner Report",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/vulnerability-scanner-report/VulnerabilityScannerReport.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  AlertCircle,\n  AlertTriangle,\n  Check,\n  CheckCircle2,\n  Copy,\n  Download,\n  ExternalLink,\n  FileCode2,\n  GitPullRequest,\n  Info,\n  Package,\n  RefreshCw,\n  Search,\n  ShieldAlert,\n  ShieldCheck,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Input } from '@/components/ui/input'\nimport { Progress } from '@/components/ui/progress'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport {\n  Sheet,\n  SheetClose,\n  SheetContent,\n  SheetDescription,\n  SheetFooter,\n  SheetHeader,\n  SheetTitle,\n} from '@/components/ui/sheet'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\n\nexport type CveSeverity = 'critical' | 'high' | 'medium' | 'low'\nexport type ExploitStatus = 'poc' | 'none'\n\nexport interface CveItem {\n  id: string\n  title: string\n  cwe: string\n  severity: CveSeverity\n  cvssScore: number\n  cvssVector: string\n  pkgName: string\n  installedVersion: string\n  fixedVersion: string\n  exploitStatus: ExploitStatus\n  exploitLabel: string\n  attackVector: string\n  attackComplexity: string\n  privilegesRequired: string\n  userInteraction: string\n  description: string\n  impact: string\n  remediationDiff: {\n    removed: string\n    added: string\n  }\n  patchCommand: string\n  advisoryUrl: string\n}\n\nexport interface VulnerabilityScannerReportProps {\n  targetRepo?: string\n  targetBranch?: string\n  baseImage?: string\n  lastScanned?: string\n  grade?: string\n  gradeSummary?: string\n  totalDeps?: number\n  items?: CveItem[]\n  className?: string\n}\n\nconst defaultCveItems: CveItem[] = [\n  {\n    id: 'CVE-2026-38419',\n    title: 'Prototype Pollution via mergeCustomizer in lodash',\n    cwe: 'CWE-1321',\n    severity: 'high',\n    cvssScore: 8.4,\n    cvssVector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N',\n    pkgName: 'lodash',\n    installedVersion: '4.17.20',\n    fixedVersion: '4.17.22+',\n    exploitStatus: 'poc',\n    exploitLabel: 'Proof of Concept available',\n    attackVector: 'Network (Remote)',\n    attackComplexity: 'Low',\n    privilegesRequired: 'None',\n    userInteraction: 'None',\n    description:\n      'A prototype pollution vulnerability in lodash prior to 4.17.22 allows unauthenticated remote attackers to modify Object.prototype properties via crafted JSON payloads, leading to denial of service or potential remote code execution.',\n    impact: 'Critical data integrity failure and property tampering across server runtime objects.',\n    remediationDiff: {\n      removed: '  \"lodash\": \"^4.17.20\",',\n      added: '  \"lodash\": \"^4.17.22\",',\n    },\n    patchCommand: 'npm install lodash@^4.17.22 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-38419',\n  },\n  {\n    id: 'CVE-2026-29401',\n    title: 'Server-Side Request Forgery (SSRF) bypass in axios redirect handler',\n    cwe: 'CWE-918',\n    severity: 'high',\n    cvssScore: 7.8,\n    cvssVector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N',\n    pkgName: 'axios',\n    installedVersion: '1.6.2',\n    fixedVersion: '1.7.9+',\n    exploitStatus: 'poc',\n    exploitLabel: 'Proof of Concept available',\n    attackVector: 'Network (Remote)',\n    attackComplexity: 'Low',\n    privilegesRequired: 'None',\n    userInteraction: 'Required',\n    description:\n      'Axios versions <=1.6.8 improperly preserve sensitive Authorization and Cookie headers during cross-origin HTTP 302/307 redirects, exposing upstream credentials to untrusted third-party endpoints.',\n    impact: 'Authorization bearer token leakage to arbitrary redirect targets.',\n    remediationDiff: {\n      removed: '  \"axios\": \"^1.6.2\",',\n      added: '  \"axios\": \"^1.7.9\",',\n    },\n    patchCommand: 'npm install axios@^1.7.9 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-29401',\n  },\n  {\n    id: 'CVE-2026-10492',\n    title: 'Arbitrary File Overwrite via hardlink traversal in tar',\n    cwe: 'CWE-59',\n    severity: 'medium',\n    cvssScore: 6.5,\n    cvssVector: 'CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H',\n    pkgName: 'tar',\n    installedVersion: '6.1.11',\n    fixedVersion: '6.2.1+',\n    exploitStatus: 'none',\n    exploitLabel: 'No known exploit',\n    attackVector: 'Local Archive Extraction',\n    attackComplexity: 'Low',\n    privilegesRequired: 'None',\n    userInteraction: 'Required',\n    description:\n      'The tar package before 6.2.1 is vulnerable to arbitrary file write outside the extraction destination directory when untrusted tar archives contain hardlinks pointing to symlinked directories.',\n    impact: 'Arbitrary filesystem overwrite upon unpacking unvetted tarball artifacts.',\n    remediationDiff: {\n      removed: '  \"tar\": \"^6.1.11\",',\n      added: '  \"tar\": \"^6.2.1\",',\n    },\n    patchCommand: 'npm install tar@^6.2.1 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-10492',\n  },\n  {\n    id: 'CVE-2026-84920',\n    title: 'Signature verification bypass via algorithm confusion in jsonwebtoken',\n    cwe: 'CWE-347',\n    severity: 'medium',\n    cvssScore: 6.1,\n    cvssVector: 'CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N',\n    pkgName: 'jsonwebtoken',\n    installedVersion: '8.5.1',\n    fixedVersion: '9.0.2+',\n    exploitStatus: 'poc',\n    exploitLabel: 'Proof of Concept available',\n    attackVector: 'Network (Remote)',\n    attackComplexity: 'High',\n    privilegesRequired: 'None',\n    userInteraction: 'None',\n    description:\n      'When jwt.verify() is executed without explicit algorithms whitelisting, attackers can forge unsigned tokens or switch asymmetric RS256 keys to symmetric HMAC evaluation with public certs.',\n    impact: 'Unauthorized identity impersonation and claim forgery.',\n    remediationDiff: {\n      removed: '  \"jsonwebtoken\": \"^8.5.1\",',\n      added: '  \"jsonwebtoken\": \"^9.0.2\",',\n    },\n    patchCommand: 'npm install jsonwebtoken@^9.0.2 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-84920',\n  },\n  {\n    id: 'CVE-2026-18933',\n    title: 'Regular Expression Denial of Service (ReDoS) in micromatch',\n    cwe: 'CWE-1333',\n    severity: 'medium',\n    cvssScore: 5.3,\n    cvssVector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L',\n    pkgName: 'micromatch',\n    installedVersion: '4.0.5',\n    fixedVersion: '4.0.8+',\n    exploitStatus: 'none',\n    exploitLabel: 'No known exploit',\n    attackVector: 'Network (Remote)',\n    attackComplexity: 'Low',\n    privilegesRequired: 'None',\n    userInteraction: 'None',\n    description:\n      'A backtracking exponential regular expression in micromatch path globbing allows attackers sending crafted nested brace expressions to cause catastrophic CPU exhaustion and event loop freeze.',\n    impact: 'Node.js main thread event-loop starvation and service unresponsiveness.',\n    remediationDiff: {\n      removed: '  \"micromatch\": \"^4.0.5\",',\n      added: '  \"micromatch\": \"^4.0.8\",',\n    },\n    patchCommand: 'npm install micromatch@^4.0.8 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-18933',\n  },\n  {\n    id: 'CVE-2026-04192',\n    title: 'Information disclosure in child process error serialization in cross-spawn',\n    cwe: 'CWE-209',\n    severity: 'low',\n    cvssScore: 3.7,\n    cvssVector: 'CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N',\n    pkgName: 'cross-spawn',\n    installedVersion: '7.0.3',\n    fixedVersion: '7.0.6+',\n    exploitStatus: 'none',\n    exploitLabel: 'No known exploit',\n    attackVector: 'Local Environment',\n    attackComplexity: 'High',\n    privilegesRequired: 'Low',\n    userInteraction: 'None',\n    description:\n      'Under verbose debug logging configurations, command environment variables containing auth tokens may be included in uncaught spawn error stacks printed to stdout.',\n    impact: 'Accidental leakage of process environment credentials in CI runner logs.',\n    remediationDiff: {\n      removed: '  \"cross-spawn\": \"^7.0.3\",',\n      added: '  \"cross-spawn\": \"^7.0.6\",',\n    },\n    patchCommand: 'npm install cross-spawn@^7.0.6 --save-exact',\n    advisoryUrl: 'https://nvd.nist.gov/vuln/detail/CVE-2026-04192',\n  },\n]\n\nexport function VulnerabilityScannerReport({\n  targetRepo = 'uipkge / core-registry:v2.4',\n  targetBranch = 'main (git:a4f891b)',\n  baseImage = 'node:22-alpine3.20',\n  lastScanned = 'Scanned 12m ago via Trivy v0.52',\n  grade = 'Grade B+',\n  gradeSummary = '2 High CVEs',\n  totalDeps = 1284,\n  items = defaultCveItems,\n  className,\n}: VulnerabilityScannerReportProps) {\n  const [searchQuery, setSearchQuery] = React.useState('')\n  const [severityFilter, setSeverityFilter] = React.useState<string>('all')\n  const [exploitFilter, setExploitFilter] = React.useState<string>('all')\n  const [isScanning, setIsScanning] = React.useState(false)\n  const [scanProgress, setScanProgress] = React.useState(100)\n  const [currentLastScanned, setCurrentLastScanned] = React.useState(lastScanned)\n  const [selectedCve, setSelectedCve] = React.useState<CveItem | null>(null)\n  const [isDrawerOpen, setIsDrawerOpen] = React.useState(false)\n  const [copiedCveId, setCopiedCveId] = React.useState<string | null>(null)\n  const [fixedPrs, setFixedPrs] = React.useState<Record<string, boolean>>({})\n  const [exportSuccess, setExportSuccess] = React.useState(false)\n\n  const summaryCounts = React.useMemo(() => {\n    return {\n      critical: items.filter((i) => i.severity === 'critical').length,\n      high: items.filter((i) => i.severity === 'high').length,\n      medium: 5,\n      low: 12,\n      total: items.length,\n    }\n  }, [items])\n\n  const filteredItems = React.useMemo(() => {\n    const query = searchQuery.trim().toLowerCase()\n    return items.filter((item) => {\n      const matchesSeverity = severityFilter === 'all' || item.severity === severityFilter\n      const matchesExploit = exploitFilter === 'all' || item.exploitStatus === exploitFilter\n      const matchesSearch =\n        !query ||\n        item.id.toLowerCase().includes(query) ||\n        item.pkgName.toLowerCase().includes(query) ||\n        item.title.toLowerCase().includes(query) ||\n        item.cwe.toLowerCase().includes(query)\n\n      return matchesSeverity && matchesExploit && matchesSearch\n    })\n  }, [items, searchQuery, severityFilter, exploitFilter])\n\n  const triggerRescan = React.useCallback(() => {\n    if (isScanning) return\n    setIsScanning(true)\n    setScanProgress(15)\n\n    const interval = setInterval(() => {\n      setScanProgress((prev) => (prev < 90 ? prev + 25 : prev))\n    }, 150)\n\n    setTimeout(() => {\n      clearInterval(interval)\n      setScanProgress(100)\n      setIsScanning(false)\n      setCurrentLastScanned('Scanned just now via Trivy v0.52')\n    }, 800)\n  }, [isScanning])\n\n  const openAdvisory = React.useCallback((cve: CveItem) => {\n    setSelectedCve(cve)\n    setIsDrawerOpen(true)\n  }, [])\n\n  const handleAutoFix = React.useCallback((cveId: string) => {\n    setFixedPrs((prev) => ({ ...prev, [cveId]: true }))\n  }, [])\n\n  const copyCommand = React.useCallback((cveId: string, command: string) => {\n    if (typeof navigator !== 'undefined' && navigator.clipboard) {\n      navigator.clipboard.writeText(command)\n      setCopiedCveId(cveId)\n      setTimeout(() => {\n        setCopiedCveId((curr) => (curr === cveId ? null : curr))\n      }, 2000)\n    }\n  }, [])\n\n  const exportSbom = React.useCallback(() => {\n    const sbomData = {\n      spdxVersion: 'SPDX-2.3',\n      dataLicense: 'CC0-1.0',\n      SPDXID: 'SPDXRef-DOCUMENT',\n      name: 'uipkge-core-registry-sbom',\n      documentNamespace: 'https://uipkge.dev/spdxdocs/core-registry-v2.4',\n      creationInfo: {\n        created: new Date().toISOString(),\n        creators: ['Tool: Trivy-v0.52', 'Organization: UIPKGE Security Squad'],\n      },\n      packages: items.map((item) => ({\n        name: item.pkgName,\n        SPDXID: `SPDXRef-Package-${item.pkgName}`,\n        versionInfo: item.installedVersion,\n        downloadLocation: `https://registry.npmjs.org/${item.pkgName}/-/${item.pkgName}-${item.installedVersion}.tgz`,\n        filesAnalyzed: false,\n        securityVulnerabilities: [\n          {\n            id: item.id,\n            severity: item.severity.toUpperCase(),\n            cvssScore: item.cvssScore,\n            remediation: item.fixedVersion,\n          },\n        ],\n      })),\n    }\n\n    const jsonStr = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(sbomData, null, 2))\n    if (typeof document !== 'undefined') {\n      const downloadAnchor = document.createElement('a')\n      downloadAnchor.setAttribute('href', jsonStr)\n      downloadAnchor.setAttribute('download', `sbom-spdx-core-registry-${new Date().toISOString().slice(0, 10)}.json`)\n      document.body.appendChild(downloadAnchor)\n      downloadAnchor.click()\n      downloadAnchor.remove()\n\n      setExportSuccess(true)\n      setTimeout(() => {\n        setExportSuccess(false)\n      }, 2000)\n    }\n  }, [items])\n\n  const toggleSeverityFilter = React.useCallback((sev: string) => {\n    setSeverityFilter((prev) => (prev === sev ? 'all' : sev))\n  }, [])\n\n  return (\n    <div data-slot=\"vulnerability-scanner-report\" className={cn('w-full space-y-5', className)}>\n      {/* Header Section */}\n      <div className=\"border-border/80 bg-card text-card-foreground flex flex-col gap-4 rounded-xl border p-4 shadow-xs sm:p-5 lg:flex-row lg:items-center lg:justify-between\">\n        <div className=\"space-y-1.5\">\n          <div className=\"flex flex-wrap items-center gap-2.5\">\n            <div className=\"bg-muted text-muted-foreground flex size-8 shrink-0 items-center justify-center rounded-lg border\">\n              <ShieldAlert className=\"text-warning size-4.5\" />\n            </div>\n            <div>\n              <div className=\"flex flex-wrap items-center gap-2\">\n                <h1 className=\"text-foreground text-base font-semibold tracking-tight sm:text-lg\">{targetRepo}</h1>\n                <Badge variant=\"warning\" className=\"gap-1 text-xs font-medium\">\n                  <span className=\"bg-warning size-1.5 rounded-full\" />\n                  {grade} · {gradeSummary}\n                </Badge>\n              </div>\n              <div className=\"text-muted-foreground flex flex-wrap items-center gap-2 pt-0.5 text-xs\">\n                <span>{currentLastScanned}</span>\n                <span className=\"opacity-40\">·</span>\n                <span className=\"font-mono\">{targetBranch}</span>\n                <span className=\"opacity-40\">·</span>\n                <span className=\"font-mono\">{baseImage}</span>\n                <span className=\"opacity-40\">·</span>\n                <span>{totalDeps.toLocaleString()} dependencies audited</span>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div className=\"flex flex-wrap items-center gap-2 self-start sm:gap-2.5 lg:self-center\">\n          <Button\n            aria-label=\"Download attachment\"\n            variant=\"outline\"\n            size=\"sm\"\n            className=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n            onClick={exportSbom}\n          >\n            {exportSuccess ? <Check className=\"text-success size-3.5\" /> : <Download className=\"size-3.5\" />}\n            <span>{exportSuccess ? 'SBOM Exported' : 'Export SBOM (SPDX)'}</span>\n          </Button>\n\n          <Button\n            variant=\"default\"\n            size=\"sm\"\n            className=\"h-8 gap-1.5 text-xs font-medium shadow-xs\"\n            disabled={isScanning}\n            onClick={triggerRescan}\n          >\n            <RefreshCw className={cn('size-3.5', isScanning && 'animate-spin')} />\n            <span>{isScanning ? 'Scanning Container...' : 'Trigger Re-scan'}</span>\n          </Button>\n        </div>\n      </div>\n\n      {/* Active Scan Progress Track */}\n      {isScanning && (\n        <div className=\"border-primary/20 bg-primary/5 space-y-1.5 rounded-lg border p-3\">\n          <div className=\"flex items-center justify-between gap-x-2 text-xs font-medium\">\n            <span className=\"text-primary flex items-center gap-1.5\">\n              <Search className=\"size-3.5\" />\n              Running AST & SBOM vulnerability correlation against NVD & OSV databases...\n            </span>\n            <span className=\"text-muted-foreground font-mono\">{scanProgress}%</span>\n          </div>\n          <Progress value={scanProgress} className=\"h-1.5\" />\n        </div>\n      )}\n\n      {/* 4 CVE Severity Summary Cards */}\n      <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4\">\n        {/* Critical Card */}\n        <Card\n          className={cn(\n            'border-border/80 bg-card text-card-foreground hover:border-border cursor-pointer shadow-xs transition-colors',\n            severityFilter === 'critical' && 'border-success/50 ring-success ring-2',\n          )}\n          onClick={() => toggleSeverityFilter('critical')}\n        >\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-start justify-between\">\n              <div className=\"space-y-1\">\n                <p className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Critical Severity</p>\n                <div className=\"flex items-baseline gap-2\">\n                  <span className=\"text-foreground font-mono text-2xl font-bold tracking-tight\">\n                    {summaryCounts.critical}\n                  </span>\n                  <span className=\"text-success text-xs font-medium\">0 CVEs</span>\n                </div>\n              </div>\n              <div className=\"border-success/20 bg-success/10 text-success flex size-8 items-center justify-center rounded-lg border\">\n                <ShieldCheck className=\"size-4.5\" />\n              </div>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground mt-3 flex items-center justify-between gap-x-2 border-t pt-2 text-xs\">\n              <span className=\"text-success font-medium\">Zero critical exposures</span>\n              <span className=\"font-mono text-xs\">CVSS 9.0–10.0</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* High Card */}\n        <Card\n          className={cn(\n            'border-border/80 bg-card text-card-foreground hover:border-border cursor-pointer shadow-xs transition-colors',\n            severityFilter === 'high' && 'border-destructive/50 ring-destructive ring-2',\n          )}\n          onClick={() => toggleSeverityFilter('high')}\n        >\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-start justify-between\">\n              <div className=\"space-y-1\">\n                <p className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">High Severity</p>\n                <div className=\"flex items-baseline gap-2\">\n                  <span className=\"text-foreground font-mono text-2xl font-bold tracking-tight\">\n                    {summaryCounts.high}\n                  </span>\n                  <span className=\"text-destructive text-xs font-medium\">2 CVEs</span>\n                </div>\n              </div>\n              <div className=\"border-destructive/20 bg-destructive/10 text-destructive flex size-8 items-center justify-center rounded-lg border\">\n                <AlertTriangle className=\"size-4.5\" />\n              </div>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground mt-3 flex items-center justify-between gap-x-2 border-t pt-2 text-xs\">\n              <span className=\"text-destructive font-medium\">Actionable patches ready</span>\n              <span className=\"font-mono text-xs\">CVSS 7.0–8.9</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Medium Card */}\n        <Card\n          className={cn(\n            'border-border/80 bg-card text-card-foreground hover:border-border cursor-pointer shadow-xs transition-colors',\n            severityFilter === 'medium' && 'border-warning/50 ring-warning ring-2',\n          )}\n          onClick={() => toggleSeverityFilter('medium')}\n        >\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-start justify-between\">\n              <div className=\"space-y-1\">\n                <p className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Medium Severity</p>\n                <div className=\"flex items-baseline gap-2\">\n                  <span className=\"text-foreground font-mono text-2xl font-bold tracking-tight\">\n                    {summaryCounts.medium}\n                  </span>\n                  <span className=\"text-warning text-xs font-medium\">5 CVEs</span>\n                </div>\n              </div>\n              <div className=\"border-warning/20 bg-warning/10 text-warning flex size-8 items-center justify-center rounded-lg border\">\n                <AlertCircle className=\"size-4.5\" />\n              </div>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground mt-3 flex items-center justify-between gap-x-2 border-t pt-2 text-xs\">\n              <span className=\"text-warning font-medium\">3 in direct dependencies</span>\n              <span className=\"font-mono text-xs\">CVSS 4.0–6.9</span>\n            </div>\n          </CardContent>\n        </Card>\n\n        {/* Low Card */}\n        <Card\n          className={cn(\n            'border-border/80 bg-card text-card-foreground hover:border-border cursor-pointer shadow-xs transition-colors',\n            severityFilter === 'low' && 'border-info/50 ring-info ring-2',\n          )}\n          onClick={() => toggleSeverityFilter('low')}\n        >\n          <CardContent className=\"p-4\">\n            <div className=\"flex items-start justify-between\">\n              <div className=\"space-y-1\">\n                <p className=\"text-muted-foreground text-xs font-medium tracking-wider uppercase\">Low Severity</p>\n                <div className=\"flex items-baseline gap-2\">\n                  <span className=\"text-foreground font-mono text-2xl font-bold tracking-tight\">\n                    {summaryCounts.low}\n                  </span>\n                  <span className=\"text-info text-xs font-medium\">12 CVEs</span>\n                </div>\n              </div>\n              <div className=\"border-info/20 bg-info/10 text-info flex size-8 items-center justify-center rounded-lg border\">\n                <Info className=\"size-4.5\" />\n              </div>\n            </div>\n            <div className=\"border-border/50 text-muted-foreground mt-3 flex items-center justify-between gap-x-2 border-t pt-2 text-xs\">\n              <span className=\"text-info font-medium\">Informational & debug</span>\n              <span className=\"font-mono text-xs\">CVSS 0.1–3.9</span>\n            </div>\n          </CardContent>\n        </Card>\n      </div>\n\n      {/* Filter & Search Toolbar */}\n      <div className=\"flex flex-col gap-2.5 sm:flex-row sm:items-center sm:justify-between\">\n        <div className=\"flex flex-1 flex-wrap items-center gap-2\">\n          <div className=\"relative w-full sm:w-72\">\n            <Search className=\"text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n            <Input\n              value={searchQuery}\n              onChange={(e) => setSearchQuery(e.target.value)}\n              placeholder=\"Search CVE, package, or CWE...\"\n              className=\"h-8 pl-8 text-xs\"\n            />\n          </div>\n\n          {/* Severity Filter Select */}\n          <Select value={severityFilter} onValueChange={setSeverityFilter}>\n            <SelectTrigger className=\"h-8 w-36 text-xs capitalize\">\n              <SelectValue placeholder=\"All Severities\" />\n            </SelectTrigger>\n            <SelectContent align=\"start\">\n              <SelectItem value=\"all\">All Severities</SelectItem>\n              <SelectItem value=\"critical\">Critical (0)</SelectItem>\n              <SelectItem value=\"high\">High (2)</SelectItem>\n              <SelectItem value=\"medium\">Medium (5)</SelectItem>\n              <SelectItem value=\"low\">Low (12)</SelectItem>\n            </SelectContent>\n          </Select>\n\n          {/* Exploitability Filter Select */}\n          <Select value={exploitFilter} onValueChange={setExploitFilter}>\n            <SelectTrigger className=\"h-8 w-44 text-xs\">\n              <SelectValue placeholder=\"All Exploit Status\" />\n            </SelectTrigger>\n            <SelectContent align=\"start\">\n              <SelectItem value=\"all\">All Exploit Status</SelectItem>\n              <SelectItem value=\"poc\">PoC Available</SelectItem>\n              <SelectItem value=\"none\">No Known Exploit</SelectItem>\n            </SelectContent>\n          </Select>\n\n          {(severityFilter !== 'all' || exploitFilter !== 'all' || searchQuery) && (\n            <Button\n              variant=\"ghost\"\n              size=\"sm\"\n              className=\"text-muted-foreground hover:text-foreground h-8 px-2 text-xs\"\n              onClick={() => {\n                setSeverityFilter('all')\n                setExploitFilter('all')\n                setSearchQuery('')\n              }}\n            >\n              Reset filters\n            </Button>\n          )}\n        </div>\n\n        <div className=\"text-muted-foreground flex items-center gap-2 text-xs\">\n          <span>\n            Showing <strong className=\"text-foreground font-mono\">{filteredItems.length}</strong> of {items.length}{' '}\n            audited vulnerabilities\n          </span>\n        </div>\n      </div>\n\n      {/* Vulnerability Table Card */}\n      <Card className=\"border-border/80 bg-card text-card-foreground overflow-hidden shadow-xs\">\n        <div className=\"overflow-x-auto\">\n          <Table>\n            <TableHeader>\n              <TableRow className=\"hover:bg-transparent\">\n                <TableHead className=\"min-w-[220px]\">Vulnerability / CVE</TableHead>\n                <TableHead className=\"min-w-[130px]\">Severity</TableHead>\n                <TableHead className=\"min-w-[160px]\">Affected Package</TableHead>\n                <TableHead className=\"min-w-[170px]\">Remediation Fixed</TableHead>\n                <TableHead className=\"min-w-[180px]\">Exploitability</TableHead>\n                <TableHead className=\"min-w-[180px] text-right\">Actions</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {filteredItems.map((item) => (\n                <TableRow\n                  key={item.id}\n                  className=\"hover:bg-muted/40 cursor-pointer transition-colors\"\n                  onClick={() => openAdvisory(item)}\n                >\n                  {/* Vulnerability / CVE */}\n                  <TableCell className=\"py-3 align-top\">\n                    <div className=\"space-y-1\">\n                      <div className=\"flex items-center gap-2\">\n                        <span className=\"text-foreground font-mono text-xs font-semibold hover:underline\">\n                          {item.id}\n                        </span>\n                        <Badge variant=\"outline\" className=\"px-1.5 py-0 font-mono text-xs\">\n                          {item.cwe}\n                        </Badge>\n                      </div>\n                      <p className=\"text-muted-foreground line-clamp-1 max-w-[220px] text-xs\">{item.title}</p>\n                    </div>\n                  </TableCell>\n\n                  {/* Severity & CVSS Score */}\n                  <TableCell className=\"py-3 align-top\">\n                    <div className=\"space-y-1\">\n                      {item.severity === 'critical' ? (\n                        <Badge variant=\"destructive\" className=\"gap-1 font-mono text-xs font-medium\">\n                          <AlertCircle className=\"size-3\" />\n                          CVSS {item.cvssScore} Critical\n                        </Badge>\n                      ) : item.severity === 'high' ? (\n                        <Badge className=\"border-destructive/20 bg-destructive/10 text-destructive gap-1 font-mono text-xs font-medium\">\n                          <AlertTriangle className=\"size-3\" />\n                          CVSS {item.cvssScore} High\n                        </Badge>\n                      ) : item.severity === 'medium' ? (\n                        <Badge variant=\"warning\" className=\"gap-1 font-mono text-xs font-medium\">\n                          <AlertCircle className=\"size-3\" />\n                          CVSS {item.cvssScore} Med\n                        </Badge>\n                      ) : (\n                        <Badge variant=\"info\" className=\"gap-1 font-mono text-xs font-medium\">\n                          <Info className=\"size-3\" />\n                          CVSS {item.cvssScore} Low\n                        </Badge>\n                      )}\n                      <p className=\"text-muted-foreground font-mono text-xs\">v3.1 Vector</p>\n                    </div>\n                  </TableCell>\n\n                  {/* Affected Package & Version */}\n                  <TableCell className=\"py-3 align-top\">\n                    <div className=\"flex items-center gap-2\">\n                      <Package className=\"text-muted-foreground size-3.5 shrink-0\" />\n                      <div className=\"min-w-0\">\n                        <p className=\"text-foreground truncate font-mono text-xs font-medium\">{item.pkgName}</p>\n                        <p className=\"text-muted-foreground font-mono text-xs\">v{item.installedVersion}</p>\n                      </div>\n                    </div>\n                  </TableCell>\n\n                  {/* Remediation Fixed Version */}\n                  <TableCell className=\"py-3 align-top\">\n                    <div className=\"space-y-1\">\n                      <div className=\"border-success/20 bg-success/10 text-success inline-flex items-center gap-1 rounded-md border px-2 py-0.5 font-mono text-xs font-medium\">\n                        <CheckCircle2 className=\"text-success size-3\" />\n                        {item.fixedVersion}\n                      </div>\n                      <p className=\"text-muted-foreground text-xs\">Upgrade ready</p>\n                    </div>\n                  </TableCell>\n\n                  {/* Exploitability Status */}\n                  <TableCell className=\"py-3 align-top\">\n                    <div className=\"flex items-center gap-1.5\">\n                      <span\n                        className={cn(\n                          'size-2 shrink-0 rounded-full',\n                          item.exploitStatus === 'poc' ? 'bg-warning animate-pulse' : 'bg-muted-foreground/50',\n                        )}\n                      />\n                      <span\n                        className={cn(\n                          'text-xs font-medium',\n                          item.exploitStatus === 'poc' ? 'text-warning' : 'text-muted-foreground',\n                        )}\n                      >\n                        {item.exploitLabel}\n                      </span>\n                    </div>\n                  </TableCell>\n\n                  {/* Row Action Buttons */}\n                  <TableCell className=\"py-3 text-right align-top\" onClick={(e) => e.stopPropagation()}>\n                    <div className=\"flex items-center justify-end gap-1.5\">\n                      <Button\n                        variant=\"ghost\"\n                        size=\"sm\"\n                        className=\"text-muted-foreground hover:text-foreground h-7 px-2.5 text-xs\"\n                        onClick={() => openAdvisory(item)}\n                      >\n                        View Advisory\n                      </Button>\n\n                      {!fixedPrs[item.id] ? (\n                        <Button\n                          variant=\"outline\"\n                          size=\"sm\"\n                          className=\"h-7 gap-1 px-2.5 text-xs font-medium shadow-xs\"\n                          onClick={() => handleAutoFix(item.id)}\n                        >\n                          <GitPullRequest className=\"size-3\" />\n                          Auto-Fix PR\n                        </Button>\n                      ) : (\n                        <Badge variant=\"success\" className=\"h-7 gap-1 px-2.5 text-xs font-medium\">\n                          <Check className=\"size-3\" />\n                          PR #849 Opened\n                        </Badge>\n                      )}\n                    </div>\n                  </TableCell>\n                </TableRow>\n              ))}\n\n              {filteredItems.length === 0 && (\n                <TableRow>\n                  <TableCell colSpan={6} className=\"h-32 text-center\">\n                    <div className=\"flex flex-col items-center justify-center gap-1.5\">\n                      <ShieldCheck className=\"text-success size-7\" />\n                      <p className=\"text-foreground text-sm font-medium\">No matching vulnerabilities found</p>\n                      <p className=\"text-muted-foreground text-xs\">\n                        All packages satisfy the active filter constraints.\n                      </p>\n                    </div>\n                  </TableCell>\n                </TableRow>\n              )}\n            </TableBody>\n          </Table>\n        </div>\n\n        {/* Table Footer Metadata */}\n        <div className=\"border-border/60 bg-muted/20 text-muted-foreground flex flex-col gap-2 border-t px-4 py-2.5 text-xs sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"flex items-center gap-3\">\n            <span className=\"flex items-center gap-1\">\n              <span className=\"bg-success size-2 rounded-full\" />\n              NVD Sync Live\n            </span>\n            <span className=\"opacity-40\">·</span>\n            <span>CVSS Score Engine: v3.1 Specification</span>\n          </div>\n          <div className=\"flex items-center gap-2 font-mono\">\n            <span>Target hash: 9a20bf183</span>\n          </div>\n        </div>\n      </Card>\n\n      {/* Detailed CVE Advisory Drawer / Sheet */}\n      <Sheet open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>\n        <SheetContent className=\"w-full space-y-6 overflow-y-auto p-6 sm:max-w-xl md:max-w-2xl\">\n          {selectedCve && (\n            <>\n              <SheetHeader className=\"space-y-2 p-0 text-left\">\n                <div className=\"flex items-center justify-between gap-3 pr-6\">\n                  <div className=\"flex items-center gap-2\">\n                    {selectedCve.severity === 'critical' ? (\n                      <Badge variant=\"destructive\" className=\"font-mono text-xs font-semibold\">\n                        CRITICAL {selectedCve.cvssScore}\n                      </Badge>\n                    ) : selectedCve.severity === 'high' ? (\n                      <Badge className=\"border-destructive/20 bg-destructive/10 text-destructive font-mono text-xs font-semibold\">\n                        HIGH {selectedCve.cvssScore}\n                      </Badge>\n                    ) : selectedCve.severity === 'medium' ? (\n                      <Badge variant=\"warning\" className=\"font-mono text-xs font-semibold\">\n                        MEDIUM {selectedCve.cvssScore}\n                      </Badge>\n                    ) : (\n                      <Badge variant=\"info\" className=\"font-mono text-xs font-semibold\">\n                        LOW {selectedCve.cvssScore}\n                      </Badge>\n                    )}\n\n                    <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                      {selectedCve.cwe}\n                    </Badge>\n                  </div>\n\n                  <a\n                    href={selectedCve.advisoryUrl}\n                    target=\"_blank\"\n                    rel=\"noopener noreferrer\"\n                    className=\"text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-xs\"\n                  >\n                    <span>NVD Source</span>\n                    <ExternalLink className=\"size-3\" />\n                  </a>\n                </div>\n\n                <SheetTitle className=\"text-lg font-bold tracking-tight\">{selectedCve.id}</SheetTitle>\n                <SheetDescription className=\"text-foreground/80 text-xs font-medium\">\n                  {selectedCve.title}\n                </SheetDescription>\n              </SheetHeader>\n\n              <div className=\"space-y-5 text-xs\">\n                {/* CVSS 3.1 Metrics Grid */}\n                <div className=\"border-border/80 bg-muted/30 space-y-3 rounded-lg border p-3.5\">\n                  <div className=\"flex items-center justify-between gap-x-2\">\n                    <span className=\"text-muted-foreground font-medium\">CVSS v3.1 Base Score</span>\n                    <span className=\"text-foreground font-mono text-sm font-bold\">{selectedCve.cvssScore} / 10.0</span>\n                  </div>\n                  <Progress value={selectedCve.cvssScore * 10} className=\"h-2\" />\n\n                  <div className=\"grid grid-cols-2 gap-2.5 pt-1 text-xs sm:grid-cols-4\">\n                    <div className=\"bg-card border-border/60 rounded-md border p-2\">\n                      <p className=\"text-muted-foreground text-xs\">Attack Vector</p>\n                      <p className=\"text-foreground mt-0.5 truncate font-medium\">{selectedCve.attackVector}</p>\n                    </div>\n                    <div className=\"bg-card border-border/60 rounded-md border p-2\">\n                      <p className=\"text-muted-foreground text-xs\">Complexity</p>\n                      <p className=\"text-foreground mt-0.5 font-medium\">{selectedCve.attackComplexity}</p>\n                    </div>\n                    <div className=\"bg-card border-border/60 rounded-md border p-2\">\n                      <p className=\"text-muted-foreground text-xs\">Privileges</p>\n                      <p className=\"text-foreground mt-0.5 font-medium\">{selectedCve.privilegesRequired}</p>\n                    </div>\n                    <div className=\"bg-card border-border/60 rounded-md border p-2\">\n                      <p className=\"text-muted-foreground text-xs\">Interaction</p>\n                      <p className=\"text-foreground mt-0.5 font-medium\">{selectedCve.userInteraction}</p>\n                    </div>\n                  </div>\n\n                  {/* CVSS Vector String */}\n                  <div className=\"border-border/50 text-muted-foreground flex items-center justify-between gap-x-2 border-t pt-2 font-mono text-xs\">\n                    <span className=\"truncate\">{selectedCve.cvssVector}</span>\n                  </div>\n                </div>\n\n                {/* Description & Technical Impact */}\n                <div className=\"space-y-2\">\n                  <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                    Vulnerability Overview\n                  </h3>\n                  <p className=\"text-foreground text-xs leading-relaxed\">{selectedCve.description}</p>\n                </div>\n\n                <div className=\"space-y-2\">\n                  <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                    Technical Impact\n                  </h3>\n                  <div className=\"bg-card border-border/80 text-foreground/90 rounded-md border p-3 text-xs\">\n                    {selectedCve.impact}\n                  </div>\n                </div>\n\n                {/* Package Path & Version Comparison */}\n                <div className=\"space-y-2\">\n                  <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                    Dependency State\n                  </h3>\n                  <div className=\"grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n                    <div className=\"border-destructive/30 bg-destructive/5 rounded-md border p-3\">\n                      <p className=\"text-destructive text-xs font-medium\">Installed Version</p>\n                      <p className=\"text-foreground mt-0.5 font-mono font-bold\">\n                        {selectedCve.pkgName}@{selectedCve.installedVersion}\n                      </p>\n                      <p className=\"text-muted-foreground mt-1 text-xs\">Direct dependency in package.json</p>\n                    </div>\n\n                    <div className=\"border-success/30 bg-success/5 rounded-md border p-3\">\n                      <p className=\"text-success text-xs font-medium\">Remediation Target</p>\n                      <p className=\"text-foreground mt-0.5 font-mono font-bold\">\n                        {selectedCve.pkgName}@{selectedCve.fixedVersion}\n                      </p>\n                      <p className=\"text-muted-foreground mt-1 text-xs\">Non-breaking patch update</p>\n                    </div>\n                  </div>\n                </div>\n\n                {/* Remediation Code Diff */}\n                <div className=\"space-y-2\">\n                  <div className=\"flex items-center justify-between gap-x-2\">\n                    <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                      package.json Patch Diff\n                    </h3>\n                    <span className=\"text-muted-foreground font-mono text-xs\">package.json</span>\n                  </div>\n                  <div className=\"overflow-hidden rounded-md border bg-zinc-950 font-mono text-xs text-zinc-100 shadow-inner\">\n                    <div className=\"text-muted-foreground flex items-center gap-2 border-b border-zinc-800 bg-zinc-900/90 px-3 py-1.5 text-xs\">\n                      <FileCode2 className=\"size-3.5\" />\n                      <span>dependencies</span>\n                    </div>\n                    <div className=\"space-y-1 p-3 text-xs leading-relaxed select-text\">\n                      <div className=\"bg-destructive/15 text-destructive rounded-xs px-1.5 py-0.5\">\n                        - {selectedCve.remediationDiff.removed}\n                      </div>\n                      <div className=\"bg-success/15 text-success rounded-xs px-1.5 py-0.5\">\n                        + {selectedCve.remediationDiff.added}\n                      </div>\n                    </div>\n                  </div>\n                </div>\n\n                {/* Remediation CLI Command Box */}\n                <div className=\"space-y-2\">\n                  <div className=\"flex items-center justify-between gap-x-2\">\n                    <h3 className=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                      CLI Remediation Command\n                    </h3>\n                    <Button\n                      variant=\"ghost\"\n                      size=\"xs\"\n                      className=\"h-6 gap-1 px-2 text-xs\"\n                      onClick={() => copyCommand(selectedCve.id, selectedCve.patchCommand)}\n                    >\n                      {copiedCveId === selectedCve.id ? (\n                        <Check className=\"text-success size-3\" />\n                      ) : (\n                        <Copy className=\"size-3\" />\n                      )}\n                      <span>{copiedCveId === selectedCve.id ? 'Copied' : 'Copy command'}</span>\n                    </Button>\n                  </div>\n                  <div className=\"border-border bg-muted/60 flex items-center justify-between gap-x-2 rounded-md border px-3 py-2 font-mono text-xs\">\n                    <span className=\"text-foreground truncate\">{selectedCve.patchCommand}</span>\n                  </div>\n                </div>\n              </div>\n\n              <SheetFooter className=\"border-border/80 flex flex-row items-center justify-end gap-2 border-t pt-4\">\n                <SheetClose asChild>\n                  <Button variant=\"outline\" size=\"sm\" className=\"text-xs\">\n                    Close\n                  </Button>\n                </SheetClose>\n\n                {!fixedPrs[selectedCve.id] ? (\n                  <Button\n                    variant=\"default\"\n                    size=\"sm\"\n                    className=\"gap-1.5 text-xs font-medium\"\n                    onClick={() => handleAutoFix(selectedCve.id)}\n                  >\n                    <GitPullRequest className=\"size-3.5\" />\n                    Open Auto-Fix Pull Request\n                  </Button>\n                ) : (\n                  <Badge variant=\"success\" className=\"h-8 gap-1.5 px-3 text-xs font-medium\">\n                    <Check className=\"size-3.5\" />\n                    PR #849 Created & Assigned\n                  </Badge>\n                )}\n              </SheetFooter>\n            </>\n          )}\n        </SheetContent>\n      </Sheet>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/VulnerabilityScannerReport.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/progress.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/sheet.json",
    "https://uipkge.dev/r/react/table.json"
  ],
  "description": "Snyk and Trivy style CVE vulnerability scanner report and dependency security audit with severity breakdown cards, CVSS metrics, package version diffs, advisory inspection drawer, and automated remediation PR actions.",
  "categories": [
    "security",
    "dashboard",
    "devops"
  ]
}