{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "stack-trace",
  "title": "Stack Trace",
  "description": "Readable errors: your frames highlighted, library frames folded.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/stack-trace.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ChevronDownIcon, CopyIcon, XCircleIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype StackTraceProps = React.ComponentProps<\"div\"> & {\n  /** The raw error text: first line is the message, following \"at …\" lines are frames. */\n  trace: string;\n  /** Collapse frames from node_modules and node: internals. */\n  hideInternal?: boolean;\n};\n\n/**\n * An error and its stack, readable: the message up top in red, your frames highlighted with file and line, library\n * and runtime frames folded away, and the raw text one click from your clipboard.\n */\nfunction StackTrace({ trace, hideInternal = true, className, ...props }: StackTraceProps) {\n  const [message, ...rest] = trace.trim().split(\"\\n\");\n  const frames = rest.map((l) => l.trim()).filter(Boolean).map((l) => {\n    const m = /at (?:(.+?) \\()?(.+?):(\\d+):(\\d+)\\)?$/.exec(l);\n    return { raw: l, fn: m?.[1] ?? \"(anonymous)\", file: m?.[2] ?? l, line: m?.[3], internal: /node_modules|node:|internal\\//.test(l) };\n  });\n  const [showAll, setShowAll] = React.useState(!hideInternal);\n  const shown = showAll ? frames : frames.filter((f) => !f.internal);\n  const hidden = frames.length - shown.length;\n\n  return (\n    <div data-slot=\"stack-trace\" className={cn(\"overflow-hidden rounded-xl border border-destructive/30 bg-card text-sm\", className)} {...props}>\n      <div className=\"flex items-start gap-2.5 border-b border-destructive/20 bg-destructive/5 px-3 py-2.5\">\n        <XCircleIcon className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n        <p className=\"flex-1 font-mono text-xs leading-relaxed font-medium text-destructive\">{message}</p>\n        <button type=\"button\" aria-label=\"Copy stack trace\" onClick={() => navigator.clipboard.writeText(trace)} className=\"-m-1 grid size-8 shrink-0 place-items-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground\">\n          <CopyIcon className=\"size-3.5\" />\n        </button>\n      </div>\n      <ol className=\"grid font-mono text-xs\">\n        {shown.map((f, i) => (\n          <li key={i} className={cn(\"flex items-baseline gap-3 border-b border-border/60 px-3 py-1.5 last:border-b-0\", f.internal ? \"text-muted-foreground/70\" : \"text-foreground\")}>\n            <span className=\"w-20 shrink-0 truncate sm:w-28\">{f.fn}</span>\n            {/* The path truncates from its start; the line number never does. */}\n            <span className=\"flex min-w-0 text-muted-foreground\">\n              <span className=\"truncate [direction:rtl]\">\n                <bdi>{f.file}</bdi>\n              </span>\n              {f.line && <span className={cn(\"shrink-0\", !f.internal && \"text-foreground\")}>:{f.line}</span>}\n            </span>\n          </li>\n        ))}\n      </ol>\n      {hidden > 0 || showAll ? (\n        <button type=\"button\" onClick={() => setShowAll((s) => !s)} className=\"flex w-full items-center justify-center gap-1 border-t border-border py-1.5 text-[0.6875rem] text-muted-foreground hover:bg-muted hover:text-foreground\">\n          <ChevronDownIcon className={cn(\"size-3.5 transition-transform\", showAll && \"rotate-180\")} />\n          {showAll ? \"Hide library frames\" : `${hidden} library frames`}\n        </button>\n      ) : null}\n    </div>\n  );\n}\n\nexport { StackTrace };\nexport type { StackTraceProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/stack-trace",
  "categories": [
    "agents"
  ],
  "type": "registry:ui"
}