{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-ai-elements",
  "title": "Aurora AI Elements",
  "author": "jmagar <https://github.com/jmagar>",
  "description": "Aurora-native AI Elements parity block covering chat, code, voice, workflow, media, and utility surfaces.",
  "dependencies": [
    "lucide-react@^0.487.0"
  ],
  "registryDependencies": [
    "@aurora/aurora-tokens",
    "@aurora/aurora-avatar",
    "@aurora/aurora-badge",
    "@aurora/aurora-button",
    "@aurora/aurora-select",
    "@aurora/aurora-separator",
    "@aurora/aurora-spinner",
    "@aurora/aurora-textarea",
    "@aurora/aurora-clipboard",
    "@aurora/aurora-safe-url"
  ],
  "files": [
    {
      "path": "registry/aurora/blocks/ai/elements/ai-elements.tsx",
      "content": "\"use client\"\n\n// ---------------------------------------------------------------------------\n// ai-elements.tsx — explicit re-export barrel\n//\n// Previously this file was `export * from \"./core\"` which caused tsc\n// duplicate-export errors when core.tsx and the reskinned standalone files\n// both defined the same name (Canvas/Node, Action/Actions, Source/SourceItem/\n// SourceProps). This barrel uses a named list so TypeScript sees exactly one\n// owner per export.\n//\n// Owner map (one canonical file per conflicting name):\n//   Canvas, Node              → canvas.tsx   (CD-parity reskin)\n//   Action, Actions,\n//   ActionProps, ActionsProps → action.tsx / actions.tsx\n//   Source, SourceItem,\n//   SourceProps               → source.tsx   (CD-parity reskin)\n//   Sources                  → sources.tsx\n//   Everything else           → core.tsx\n//\n// Queue lives in core.tsx because the two barrel-consuming demos\n// (ai-element-page.tsx, parity-demo.tsx) pass `tasks: AgentTask[]`, which\n// is the core.tsx API. The standalone queue.tsx uses `items: QueueItem[]`\n// and is consumed only by its own demo (ai-queue-demo.tsx).\n// ---------------------------------------------------------------------------\n\n// ── Canvas + Node (canvas.tsx owns both) ────────────────────────────────────\nexport { Canvas, Node } from \"./canvas\"\nexport type { CanvasProps, CanvasEdge, NodeProps } from \"./canvas\"\n\n// ── Action + Actions (standalone reskins) ───────────────────────────────────\nexport { Action } from \"./action\"\nexport type { ActionProps } from \"./action\"\nexport { Actions } from \"./actions\"\nexport type { ActionsProps } from \"./actions\"\n\n// ── Source + SourceItem + SourceProps (source.tsx is canonical) ─────────────\nexport { Source } from \"./source\"\nexport type { SourceItem, SourceProps } from \"./source\"\n\n// ── Sources (sources.tsx is canonical) ──────────────────────────────────────\nexport { Sources } from \"./sources\"\nexport type { SourcesProps } from \"./sources\"\n\n// ── Everything else from core.tsx ───────────────────────────────────────────\n// Excludes the four collision groups above. core.tsx still owns:\n//   Message, MessageAvatar, MessageContent, InlineCitation,\n//   Conversation, ModelSelector, Queue (tasks API), TaskList,\n//   TestResults, StackTrace, EnvironmentVariables, Checkpoint,\n//   Confirmation, ContextPanel / Context, Shimmer, Suggestion,\n//   Agent, Commit, JsxPreview, PackageInfo, Sandbox, SchemaDisplay,\n//   Snippet, Image, OpenInChat, AudioPlayer, MicSelector, Persona,\n//   SpeechInput, Transcription, VoiceSelector, Connection, Controls,\n//   Edge, Panel\n// and all their prop interfaces.\nexport {\n  Agent,\n  AudioPlayer,\n  Checkpoint,\n  Commit,\n  Confirmation,\n  Connection,\n  ContextPanel,\n  ContextPanel as Context,\n  Controls,\n  Conversation,\n  Edge,\n  EnvironmentVariables,\n  Image,\n  InlineCitation,\n  JsxPreview,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MicSelector,\n  ModelSelector,\n  OpenInChat,\n  PackageInfo,\n  Panel,\n  Persona,\n  Queue,\n  Sandbox,\n  SchemaDisplay,\n  Shimmer,\n  Snippet,\n  SpeechInput,\n  StackTrace,\n  Suggestion,\n  TaskList,\n  TestResults,\n  Transcription,\n  VoiceSelector,\n} from \"./core\"\n\nexport type {\n  AgentProps,\n  AgentTask,\n  AudioPlayerProps,\n  CheckpointProps,\n  CommitProps,\n  ConfirmationProps,\n  ConnectionProps,\n  ContextPanelProps,\n  ConversationProps,\n  EdgeProps,\n  EnvironmentVariable,\n  EnvironmentVariablesProps,\n  AuroraImageProps,\n  InlineCitationProps,\n  JsxPreviewProps,\n  MessageAvatarProps,\n  MessageProps,\n  MicSelectorProps,\n  ModelSelectorProps,\n  OpenInChatProps,\n  PackageInfoProps,\n  PanelProps,\n  PersonaProps,\n  QueueProps,\n  SandboxProps,\n  SchemaDisplayProps,\n  SnippetProps,\n  SpeechInputProps,\n  StackFrame,\n  StackTraceProps,\n  SuggestionOption,\n  SuggestionProps,\n  TaskListProps,\n  TestResult,\n  TestResultsProps,\n  TranscriptionProps,\n  TranscriptionSegment,\n  VoiceSelectorProps,\n  // ControlsProps lives only in core.tsx — no collision\n  ControlsProps,\n} from \"./core\"\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/ai-elements.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/core.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n  Bot,\n  Boxes,\n  Check,\n  Copy,\n  CircleCheck,\n  CircleAlert,\n  CircleDashed,\n  ExternalLink,\n  FileCode,\n  FileText,\n  FlaskConical,\n  GitCommitHorizontal,\n  KeyRound,\n  Layers2,\n  ListChecks,\n  Mic,\n  Network,\n  Package,\n  Play,\n  Route,\n  Save,\n  Send,\n  Sparkles,\n  UserRound,\n  Workflow,\n  X,\n  CircleX,\n} from \"lucide-react\"\nimport { Avatar as AuroraAvatar } from \"@/registry/aurora/ui/avatar\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\nimport { Button } from \"@/registry/aurora/ui/button\"\nimport { useClipboard } from \"@/registry/aurora/lib/use-clipboard\"\nimport { safeHttpUrl } from \"@/registry/aurora/lib/safe-url\"\nimport { Separator } from \"@/registry/aurora/ui/separator\"\nimport { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from \"@/registry/aurora/ui/select\"\nimport { Spinner } from \"@/registry/aurora/ui/spinner\"\nimport { Textarea } from \"@/registry/aurora/ui/textarea\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface MessageProps extends React.HTMLAttributes<HTMLElement> {\n  role?: \"assistant\" | \"user\" | \"system\"\n}\n\nexport interface MessageAvatarProps extends React.HTMLAttributes<HTMLDivElement> {\n  label: string\n  tone?: \"cyan\" | \"rose\" | \"muted\" | \"orange\"\n}\n\nexport interface SourcesProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title?: React.ReactNode\n}\n\nexport interface SourceItem {\n  title: string\n  href?: string\n  description?: string\n  badge?: string\n}\n\nexport interface SourceProps extends React.HTMLAttributes<HTMLAnchorElement> {\n  source: SourceItem\n}\n\nexport interface InlineCitationProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n  index: number\n}\n\nexport interface AgentTask {\n  id: string\n  title: string\n  description?: string\n  status: \"queued\" | \"running\" | \"completed\" | \"failed\"\n}\n\nexport interface TaskListProps extends React.HTMLAttributes<HTMLDivElement> {\n  tasks: AgentTask[]\n}\n\nexport interface TestResult {\n  name: string\n  status: \"passed\" | \"failed\" | \"skipped\" | \"running\"\n  duration?: string\n  message?: string\n}\n\nexport interface TestResultsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"results\"> {\n  results: TestResult[]\n}\n\nexport interface StackFrame {\n  file: string\n  line?: number\n  column?: number\n  label?: string\n}\n\nexport interface StackTraceProps extends React.HTMLAttributes<HTMLDivElement> {\n  title?: string\n  frames: StackFrame[]\n}\n\nexport interface EnvironmentVariable {\n  key: string\n  value?: string\n  secret?: boolean\n  required?: boolean\n}\n\nexport interface EnvironmentVariablesProps extends React.HTMLAttributes<HTMLDivElement> {\n  variables: EnvironmentVariable[]\n}\n\nexport interface CheckpointProps extends React.HTMLAttributes<HTMLDivElement> {\n  label: string\n  description?: string\n}\n\nexport interface ConfirmationProps extends React.HTMLAttributes<HTMLDivElement> {\n  title: string\n  description?: string\n  confirmLabel?: string\n  cancelLabel?: string\n}\n\nexport interface ContextPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n  used?: number\n  limit?: number\n  label?: string\n}\n\nexport type ConversationProps = React.HTMLAttributes<HTMLDivElement>\n\nexport interface ModelSelectorProps extends React.HTMLAttributes<HTMLDivElement> {\n  models: string[]\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n  label?: string\n  name?: string\n  disabled?: boolean\n  required?: boolean\n  triggerId?: string\n  triggerLabel?: string\n}\n\nexport interface QueueProps extends React.HTMLAttributes<HTMLDivElement> {\n  tasks: AgentTask[]\n}\n\nexport interface SuggestionOption {\n  id: string\n  title: string\n  description?: string\n  badge?: string\n}\n\nexport interface SuggestionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"onClick\"> {\n  options?: SuggestionOption[]\n  disabled?: boolean\n  onClick?: React.MouseEventHandler<HTMLButtonElement>\n}\n\nexport interface AgentProps extends React.HTMLAttributes<HTMLDivElement> {\n  name: string\n  role?: string\n  status?: \"idle\" | \"running\" | \"blocked\"\n}\n\nexport interface CommitProps extends React.HTMLAttributes<HTMLDivElement> {\n  hash: string\n  message: string\n  author?: string\n}\n\nexport interface JsxPreviewProps extends React.HTMLAttributes<HTMLDivElement> {\n  code: string\n}\n\nexport interface PackageInfoProps extends React.HTMLAttributes<HTMLDivElement> {\n  name: string\n  version: string\n  description?: string\n}\n\nexport interface SandboxProps extends React.HTMLAttributes<HTMLDivElement> {\n  title?: string\n  command?: string\n  status?: \"ready\" | \"running\" | \"idle\"\n  runtime?: string\n  paths?: string[]\n  envCount?: number\n}\n\nexport interface SchemaDisplayProps extends React.HTMLAttributes<HTMLPreElement> {\n  schema: unknown\n}\n\nexport interface SnippetProps extends React.HTMLAttributes<HTMLPreElement> {\n  code: string\n  language?: string\n}\n\nexport interface AuroraImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n  caption?: string\n}\n\nexport type OpenInChatProps = React.ButtonHTMLAttributes<HTMLButtonElement>\n\nexport interface AudioPlayerProps extends React.HTMLAttributes<HTMLDivElement> {\n  title?: string\n  duration?: string\n}\n\nexport interface MicSelectorProps extends React.HTMLAttributes<HTMLDivElement> {\n  devices: string[]\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n  name?: string\n  disabled?: boolean\n  required?: boolean\n  triggerId?: string\n  triggerLabel?: string\n}\n\nexport interface PersonaProps extends React.HTMLAttributes<HTMLDivElement> {\n  name: string\n  description?: string\n}\n\nexport type SpeechInputProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>\n\nexport interface TranscriptionSegment {\n  speaker: string\n  timecode: string\n  text: string\n  confidence?: number\n}\n\nexport interface TranscriptionProps extends React.HTMLAttributes<HTMLDivElement> {\n  segments: TranscriptionSegment[]\n}\n\nexport interface VoiceSelectorProps extends React.HTMLAttributes<HTMLDivElement> {\n  voices: string[]\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n  name?: string\n  disabled?: boolean\n  required?: boolean\n  triggerId?: string\n  triggerLabel?: string\n}\n\nexport type CanvasProps = React.HTMLAttributes<HTMLDivElement>\nexport interface ConnectionProps extends React.HTMLAttributes<HTMLDivElement> {\n  from: string\n  to: string\n}\nexport type ControlsProps = React.HTMLAttributes<HTMLDivElement>\nexport interface EdgeProps extends React.HTMLAttributes<HTMLDivElement> {\n  label?: string\n}\nexport interface NodeProps extends React.HTMLAttributes<HTMLDivElement> {\n  title: string\n  description?: string\n}\nexport interface PanelProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title?: React.ReactNode\n}\n\nconst taskTone = {\n  queued: { color: \"var(--aurora-text-muted)\", icon: <CircleDashed className=\"size-4\" aria-hidden /> },\n  running: { color: \"var(--axon-orange)\", icon: <Spinner size=\"sm\" /> },\n  completed: { color: \"var(--aurora-success)\", icon: <CircleCheck className=\"size-4\" aria-hidden /> },\n  failed: { color: \"var(--aurora-error)\", icon: <CircleX className=\"size-4\" aria-hidden /> },\n}\n\nconst resultVariant = {\n  passed: \"success\",\n  failed: \"error\",\n  skipped: \"neutral\",\n  running: \"neutral\",\n} as const\n\nfunction formatStatusLabel(value: string) {\n  return value\n    .split(/[-_\\s]+/)\n    .filter(Boolean)\n    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n    .join(\" \")\n}\n\nfunction panelStyle(style?: React.CSSProperties): React.CSSProperties {\n  return {\n    background: \"var(--aurora-surface-raised)\",\n    border: \"1px solid var(--aurora-border-strong)\",\n    borderRadius: \"var(--aurora-radius-1)\",\n    boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n    ...style,\n  }\n}\n\nfunction previewValue(value?: string, secret?: boolean) {\n  if (!value) return \"Unset\"\n  if (secret) {\n    const visible = value.slice(0, 6)\n    return `${visible}${value.length > 6 ? \"••••\" : \"\"}`\n  }\n  return value.length > 18 ? `${value.slice(0, 18)}…` : value\n}\n\nfunction formatTokenCount(value: number) {\n  if (value >= 1000) return `${(value / 1000).toFixed(value >= 10000 ? 0 : 1)}k`\n  return `${value}`\n}\n\nfunction stringifyWithOrder(value: unknown) {\n  return JSON.stringify(value, null, 2)\n}\n\nfunction renderJsonValue(value: unknown, depth = 0): React.ReactNode {\n  const indent = \"  \".repeat(depth)\n\n  if (Array.isArray(value)) {\n    if (value.length === 0) return <span style={{ color: \"var(--aurora-text-muted)\" }}>[]</span>\n    return (\n      <>\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>[</span>\n        {\"\\n\"}\n        {value.map((item, index) => (\n          <React.Fragment key={index}>\n            {indent}\n            {\"  \"}\n            {renderJsonValue(item, depth + 1)}\n            {index < value.length - 1 ? <span style={{ color: \"var(--aurora-text-muted)\" }}>,</span> : null}\n            {\"\\n\"}\n          </React.Fragment>\n        ))}\n        {indent}\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>]</span>\n      </>\n    )\n  }\n\n  if (value && typeof value === \"object\") {\n    const entries = Object.entries(value)\n    if (entries.length === 0) return <span style={{ color: \"var(--aurora-text-muted)\" }}>{`{}`}</span>\n    return (\n      <>\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>{`{`}</span>\n        {\"\\n\"}\n        {entries.map(([key, entryValue], index) => (\n          <React.Fragment key={key}>\n            {indent}\n            {\"  \"}\n            <span style={{ color: \"var(--aurora-accent-primary)\" }}>{`\"${key}\"`}</span>\n            <span style={{ color: \"var(--aurora-text-muted)\" }}>: </span>\n            {renderJsonValue(entryValue, depth + 1)}\n            {index < entries.length - 1 ? <span style={{ color: \"var(--aurora-text-muted)\" }}>,</span> : null}\n            {\"\\n\"}\n          </React.Fragment>\n        ))}\n        {indent}\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>{`}`}</span>\n      </>\n    )\n  }\n\n  if (typeof value === \"string\") return <span style={{ color: \"var(--aurora-accent-pink)\" }}>{`\"${value}\"`}</span>\n  if (typeof value === \"number\") return <span style={{ color: \"var(--aurora-warn)\" }}>{value}</span>\n  if (typeof value === \"boolean\") return <span style={{ color: \"var(--aurora-success)\" }}>{String(value)}</span>\n  if (value === null) return <span style={{ color: \"var(--aurora-text-muted)\" }}>null</span>\n  return <span style={{ color: \"var(--aurora-text-primary)\" }}>{String(value)}</span>\n}\n\nfunction CopyButton({ value, label = \"Copy\" }: { value: string; label?: string }) {\n  const { copied, error, copy } = useClipboard(1200)\n  const handleCopy = React.useCallback(() => void copy(value), [copy, value])\n\n  return (\n    <Button\n      type=\"button\"\n      variant=\"ghost\"\n      size=\"sm\"\n      onClick={handleCopy}\n      aria-label={copied ? \"Copied to clipboard\" : error ? \"Unable to copy\" : label}\n    >\n      {copied ? (\n        <Check className=\"size-3.5\" data-icon=\"inline-start\" aria-hidden />\n      ) : (\n        <Copy className=\"size-3.5\" data-icon=\"inline-start\" aria-hidden />\n      )}\n      <span aria-live=\"polite\" aria-atomic=\"true\">{copied ? \"Copied\" : error ? \"Unable to copy\" : label}</span>\n    </Button>\n  )\n}\n\nfunction CodeSurface({\n  icon,\n  title,\n  value,\n  children,\n}: {\n  icon: React.ReactNode\n  title: string\n  value: string\n  children: React.ReactNode\n}) {\n  return (\n    <div className=\"grid gap-3 rounded-[8px] border p-3\" style={panelStyle()}>\n      <div className=\"flex items-center justify-between gap-3\">\n        <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n          {icon}\n          {title}\n        </div>\n        <CopyButton value={value} />\n      </div>\n      {children}\n    </div>\n  )\n}\n\nfunction SelectorCard({\n  icon,\n  title,\n  description,\n  values,\n  value,\n  defaultValue,\n  onValueChange,\n  name,\n  disabled,\n  required,\n  triggerId,\n  triggerLabel,\n  placeholder,\n}: {\n  icon: React.ReactNode\n  title: string\n  description: string\n  values: string[]\n  value?: string\n  defaultValue?: string\n  onValueChange?: (value: string) => void\n  name?: string\n  disabled?: boolean\n  required?: boolean\n  triggerId?: string\n  triggerLabel?: string\n  placeholder?: string\n}) {\n  return (\n    <div className=\"grid gap-3 rounded-[8px] border p-3\" style={panelStyle()}>\n      <div className=\"grid gap-1\">\n        <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n          {icon}\n          {title}\n        </div>\n        <p className=\"aurora-text-meta\" style={{ margin: 0 }}>\n          {description}\n        </p>\n      </div>\n      <Select value={value} defaultValue={defaultValue ?? values[0]} onValueChange={onValueChange} name={name} disabled={disabled} required={required}>\n        <SelectTrigger id={triggerId} aria-label={triggerLabel ?? title} className=\"h-10 rounded-[10px]\">\n          <SelectValue placeholder={placeholder ?? values[0]} />\n        </SelectTrigger>\n        <SelectContent>\n          <SelectGroup>\n            {values.map((item) => (\n              <SelectItem key={item} value={item}>\n                {item}\n              </SelectItem>\n            ))}\n          </SelectGroup>\n        </SelectContent>\n      </Select>\n    </div>\n  )\n}\n\nconst Message = ({ ref, className, role = \"assistant\", style, ...props }: MessageProps & { ref?: React.Ref<HTMLElement> }) => (\n  <article\n    ref={ref}\n    className={cn(\n      \"grid grid-cols-[auto_minmax(0,1fr)] gap-3\",\n      className\n    )}\n    data-role={role}\n    style={{\n      color: \"var(--aurora-text-primary)\",\n      alignItems: \"start\",\n      ...style,\n    }}\n    {...props}\n  />\n)\nMessage.displayName = \"Message\"\n\nconst MessageAvatar = ({ ref, className, label, tone = \"orange\", style, ...props }: MessageAvatarProps & { ref?: React.Ref<React.ElementRef<typeof AuroraAvatar>> }) => {\n    const color =\n      tone === \"rose\"\n        ? \"var(--aurora-accent-pink)\"\n        : tone === \"muted\"\n          ? \"var(--aurora-text-muted)\"\n          : tone === \"cyan\"\n            ? \"var(--aurora-accent-primary)\"\n            : \"var(--axon-orange)\"\n\n    return (\n      <AuroraAvatar\n        ref={ref}\n        variant=\"bot\"\n        size={34}\n        alt={label}\n        fallback={label.slice(0, 2).toUpperCase()}\n        className={className}\n        style={{\n          borderColor: `color-mix(in srgb, ${color} 35%, var(--aurora-border-default))`,\n          background: `color-mix(in srgb, ${color} 13%, var(--aurora-panel-medium))`,\n          boxShadow: `0 0 0 3px color-mix(in srgb, ${color} 8%, transparent), var(--aurora-highlight-medium)`,\n          color,\n          fontFamily: \"var(--aurora-font-display)\",\n          fontSize: 12,\n          fontWeight: 800,\n          ...style,\n        }}\n        {...props}\n      />\n    )\n  }\nMessageAvatar.displayName = \"MessageAvatar\"\n\nconst bubbleTone = {\n  assistant: {\n    background: \"linear-gradient(180deg, color-mix(in srgb, var(--axon-orange) 10%, var(--aurora-panel-medium)), color-mix(in srgb, var(--axon-orange) 5%, var(--aurora-panel-medium)))\",\n    borderColor: \"color-mix(in srgb, var(--axon-orange) 30%, var(--aurora-border-default))\",\n    shadow: \"0 14px 30px color-mix(in srgb, var(--axon-orange) 7%, transparent), var(--aurora-highlight-medium)\",\n  },\n  user: {\n    background: \"linear-gradient(180deg, color-mix(in srgb, var(--aurora-accent-primary) 13%, var(--aurora-panel-medium)), color-mix(in srgb, var(--aurora-accent-primary) 7%, var(--aurora-panel-medium)))\",\n    borderColor: \"color-mix(in srgb, var(--aurora-accent-primary) 36%, var(--aurora-border-default))\",\n    shadow: \"0 14px 30px color-mix(in srgb, var(--aurora-accent-primary) 7%, transparent), var(--aurora-highlight-medium)\",\n  },\n  system: {\n    background: \"color-mix(in srgb, var(--aurora-text-muted) 8%, var(--aurora-panel-medium))\",\n    borderColor: \"var(--aurora-border-default)\",\n    shadow: \"var(--aurora-highlight-medium)\",\n  },\n} as const\n\nconst MessageContent = ({ ref, className, style, tone = \"assistant\", ...props }: React.HTMLAttributes<HTMLDivElement> & { tone?: MessageProps[\"role\"] } & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div\n      ref={ref}\n      className={cn(\n        \"min-w-0 border px-4 py-3 aurora-text-body\",\n        tone === \"user\" ? \"rounded-[16px_16px_6px_16px]\" : \"rounded-[16px_16px_16px_6px]\",\n        className\n      )}\n      style={{\n        background: bubbleTone[tone].background,\n        borderColor: bubbleTone[tone].borderColor,\n        boxShadow: bubbleTone[tone].shadow,\n        lineHeight: \"var(--aurora-line-body)\",\n        ...style,\n      }}\n      {...props}\n    />\n  )\nMessageContent.displayName = \"MessageContent\"\n\n// LEARNED: umbrella registry exports need the same URL boundary as standalone blocks.\nconst InlineCitation = ({ ref, className, index, style, children, href, ...props }: InlineCitationProps & { ref?: React.Ref<HTMLAnchorElement> }) => (\n    <a\n      ref={ref}\n      className={cn(\n        \"inline-flex items-center rounded-[4px] border px-1.5 py-0.5 align-baseline no-underline\",\n        \"transition-colors hover:bg-[var(--aurora-hover-bg)]\",\n        \"outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--aurora-focus-ring)] focus-visible:ring-offset-0\",\n        className\n      )}\n      style={{\n        borderColor: \"color-mix(in srgb, var(--aurora-accent-primary) 34%, transparent)\",\n        color: \"var(--aurora-accent-strong)\",\n        fontFamily: \"var(--aurora-font-sans)\",\n        fontSize: 11,\n        fontWeight: 700,\n        letterSpacing: \"var(--aurora-letter-label)\",\n        lineHeight: 1,\n        ...style,\n      }}\n      {...props}\n      href={safeHttpUrl(href)}\n    >\n      {children ?? index}\n    </a>\n  )\nInlineCitation.displayName = \"InlineCitation\"\n\nconst Sources = ({ ref, className, title = \"Sources\", style, children, ...props }: SourcesProps & { ref?: React.Ref<HTMLDivElement> }) => (\n  <div ref={ref} className={cn(\"grid gap-2 border p-3\", className)} style={panelStyle(style)} {...props}>\n    <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n      <FileText className=\"size-3.5\" aria-hidden />\n      {title}\n    </div>\n    <div className=\"grid gap-2\">{children}</div>\n  </div>\n)\nSources.displayName = \"Sources\"\n\nconst Source = ({ ref, className, source, style, ...props }: SourceProps & { ref?: React.Ref<HTMLAnchorElement> }) => (\n  <a\n    ref={ref}\n    className={cn(\n      \"grid gap-1 rounded-[7px] border px-3 py-2 no-underline transition-colors hover:bg-[var(--aurora-hover-bg)]\",\n      \"outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--aurora-focus-ring)] focus-visible:ring-offset-0\",\n      className\n    )}\n    style={{\n      borderColor: \"var(--aurora-border-default)\",\n      color: \"var(--aurora-text-primary)\",\n      ...style,\n    }}\n    {...props}\n    href={safeHttpUrl(source.href)}\n  >\n    <span className=\"flex min-w-0 items-center gap-2\">\n      <span className=\"truncate aurora-text-control\">{source.title}</span>\n      {source.badge ? <Badge shape=\"tag\">{source.badge}</Badge> : null}\n      <ExternalLink className=\"ml-auto size-3.5 shrink-0\" aria-hidden style={{ color: \"var(--aurora-text-muted)\" }} />\n    </span>\n    {source.description ? <span className=\"aurora-text-meta\">{source.description}</span> : null}\n  </a>\n)\nSource.displayName = \"Source\"\n\nconst TaskList = ({ ref, className, tasks, style, ...props }: TaskListProps & { ref?: React.Ref<HTMLDivElement> }) => (\n  <div ref={ref} className={cn(\"grid gap-2 border p-3\", className)} style={panelStyle(style)} {...props}>\n    <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n      <ListChecks className=\"size-3.5\" aria-hidden />\n      Tasks\n    </div>\n    <Separator />\n    <div className=\"grid gap-2\">\n      {tasks.map((task) => {\n        const tone = taskTone[task.status]\n        return (\n          <div\n            key={task.id}\n            className=\"grid grid-cols-[auto_minmax(0,1fr)_auto] gap-3 rounded-[10px] border px-2 py-2\"\n            style={{\n              color: tone.color,\n              borderColor: task.status === \"running\" ? \"color-mix(in srgb, var(--axon-orange) 30%, transparent)\" : \"transparent\",\n              background: task.status === \"running\" ? \"color-mix(in srgb, var(--axon-orange) 10%, var(--aurora-panel-medium))\" : \"transparent\",\n            }}\n          >\n            <span className=\"mt-0.5\">{tone.icon}</span>\n            <span className=\"min-w-0\">\n              <span className=\"block truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{task.title}</span>\n              {task.description ? <span className=\"block aurora-text-meta\">{task.description}</span> : null}\n            </span>\n            <Badge tone={task.status === \"failed\" ? \"error\" : task.status === \"completed\" ? \"success\" : task.status === \"running\" ? \"warn\" : \"neutral\"}>\n              {formatStatusLabel(task.status)}\n            </Badge>\n          </div>\n        )\n      })}\n    </div>\n  </div>\n)\nTaskList.displayName = \"TaskList\"\n\nconst TestResults = ({ ref, className, results, style, ...props }: TestResultsProps & { ref?: React.Ref<HTMLDivElement> }) => (\n  <div ref={ref} className={cn(\"grid gap-2 border p-3\", className)} style={panelStyle(style)} {...props}>\n    <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n      <FlaskConical className=\"size-3.5\" aria-hidden />\n      Test Results\n    </div>\n    <Separator />\n    <div className=\"grid gap-1\">\n      {results.map((result) => (\n        <div\n          key={result.name}\n          className=\"grid grid-cols-[minmax(0,1fr)_72px_96px] items-start gap-3 rounded-[10px] border px-2 py-1.5\"\n          style={{\n            borderColor: result.status === \"running\" ? \"color-mix(in srgb, var(--axon-orange) 30%, transparent)\" : \"transparent\",\n            background: result.status === \"running\" ? \"color-mix(in srgb, var(--axon-orange) 10%, var(--aurora-panel-medium))\" : \"transparent\",\n          }}\n        >\n          <span className=\"truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\", paddingTop: 4 }}>{result.name}</span>\n          <span className=\"aurora-text-meta\" style={{ justifySelf: \"end\", minHeight: 20, paddingTop: 4 }}>{result.duration ?? \"\"}</span>\n          <div style={{ display: \"flex\", justifyContent: \"flex-end\", minHeight: 24 }}>\n            <Badge tone={resultVariant[result.status]} dot={result.status === \"running\"}>\n              {formatStatusLabel(result.status)}\n            </Badge>\n          </div>\n          {result.message ? <span className=\"col-span-3 aurora-text-meta\" style={{ paddingTop: 2 }}>{result.message}</span> : null}\n        </div>\n      ))}\n    </div>\n  </div>\n)\nTestResults.displayName = \"TestResults\"\n\nconst StackTrace = ({ ref, className, title = \"Stack Trace\", frames, style, ...props }: StackTraceProps & { ref?: React.Ref<HTMLDivElement> }) => (\n  <div ref={ref} className={cn(\"grid gap-2 border p-3\", className)} style={panelStyle(style)} {...props}>\n    <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-error)\" }}>\n      <CircleAlert className=\"size-3.5\" aria-hidden />\n      {title}\n    </div>\n    <div className=\"overflow-hidden rounded-[7px] border\" style={{ borderColor: \"var(--aurora-border-default)\" }}>\n      {frames.map((frame, index) => (\n        <div key={`${frame.file}-${index}`} className=\"grid grid-cols-[auto_minmax(0,1fr)] gap-3 border-b px-3 py-2 last:border-b-0\" style={{ borderColor: \"var(--aurora-border-default)\" }}>\n          <span className=\"aurora-text-code\" style={{ color: \"var(--aurora-text-muted)\" }}>{index + 1}</span>\n          <span className=\"min-w-0\">\n            <span className=\"block truncate aurora-text-code\" style={{ color: \"var(--aurora-text-primary)\" }}>\n              {frame.file}{frame.line ? `:${frame.line}` : \"\"}{frame.column ? `:${frame.column}` : \"\"}\n            </span>\n            {frame.label ? <span className=\"block aurora-text-meta\">{frame.label}</span> : null}\n          </span>\n        </div>\n      ))}\n    </div>\n  </div>\n)\nStackTrace.displayName = \"StackTrace\"\n\nconst EnvironmentVariables = ({ ref, className, variables, style, ...props }: EnvironmentVariablesProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid gap-2 rounded-[8px] border p-3\", className)} style={panelStyle(style)} {...props}>\n      <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n        <KeyRound className=\"size-3.5\" aria-hidden />\n        Environment\n      </div>\n      <Separator />\n      <div className=\"grid gap-1\">\n        {variables.map((item) => (\n          <div key={item.key} className=\"grid grid-cols-[minmax(0,1fr)_minmax(0,168px)_auto] items-center gap-3 rounded-[6px] px-2 py-1.5\">\n            <span className=\"truncate aurora-text-code\" style={{ color: \"var(--aurora-text-primary)\" }}>{item.key}</span>\n            <span className=\"truncate aurora-text-code\" style={{ color: item.secret ? \"var(--aurora-accent-pink)\" : \"var(--aurora-text-muted)\", justifySelf: \"end\" }}>\n              {previewValue(item.value, item.secret)}\n            </span>\n            <span className=\"flex items-center gap-2 justify-self-end\">\n              {item.required ? <Badge tone=\"warn\">Required</Badge> : null}\n              {item.secret ? <Badge tone=\"rose\">Secret</Badge> : null}\n            </span>\n          </div>\n        ))}\n      </div>\n    </div>\n  )\nEnvironmentVariables.displayName = \"EnvironmentVariables\"\n\nconst Checkpoint = ({ ref, label, description, className, style, ...props }: CheckpointProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)] gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <Save className=\"mt-0.5 size-4\" aria-hidden style={{ color: \"var(--axon-orange)\" }} />\n      <div className=\"min-w-0\">\n        <div className=\"aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{label}</div>\n        {description ? <div className=\"aurora-text-meta\">{description}</div> : null}\n      </div>\n    </div>\n  )\nCheckpoint.displayName = \"Checkpoint\"\n\nconst Confirmation = ({ ref, title, description, confirmLabel = \"Approve\", cancelLabel = \"Cancel\", className, style, ...props }: ConfirmationProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid gap-3 border p-4\", className)} style={panelStyle(style)} {...props}>\n      <div className=\"flex items-center gap-2 aurora-text-section\" style={{ color: \"var(--aurora-text-primary)\" }}>\n        <CircleAlert className=\"size-4\" aria-hidden style={{ color: \"var(--aurora-warn)\" }} />\n        {title}\n      </div>\n      {description ? <p className=\"aurora-text-body\" style={{ margin: 0 }}>{description}</p> : null}\n      <div className=\"flex justify-end gap-2\">\n        <Button type=\"button\" variant=\"neutral\" size=\"sm\">\n          <X className=\"size-3.5\" data-icon=\"inline-start\" aria-hidden />\n          {cancelLabel}\n        </Button>\n        <Button type=\"button\" variant=\"rose\" size=\"sm\">\n          <Check className=\"size-3.5\" data-icon=\"inline-start\" aria-hidden />\n          {confirmLabel}\n        </Button>\n      </div>\n    </div>\n  )\nConfirmation.displayName = \"Confirmation\"\n\nconst ContextPanel = ({ ref, used = 42100, limit = 128000, label = \"Context\", className, style, ...props }: ContextPanelProps & { ref?: React.Ref<HTMLDivElement> }) => {\n    const percent = limit > 0 ? Math.min(Math.max((used / limit) * 100, 0), 100) : 0\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\"grid gap-2 border p-3\", className)}\n        style={{\n          ...panelStyle(style),\n          width: \"min(520px, 100%)\",\n        }}\n        {...props}\n      >\n        <div className=\"flex items-center justify-between gap-3\">\n          <div className=\"flex min-w-0 items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n            <Layers2 className=\"size-3.5 shrink-0\" aria-hidden />\n            <span>{label}</span>\n          </div>\n          <div className=\"shrink-0\" style={{ color: \"var(--aurora-text-muted)\", fontSize: 10, lineHeight: \"14px\" }}>\n            {formatTokenCount(used)} / {formatTokenCount(limit)}\n          </div>\n        </div>\n        <div\n          role=\"meter\"\n          aria-label={label}\n          aria-valuemin={0}\n          aria-valuemax={limit}\n          aria-valuenow={used}\n          aria-valuetext={`${formatTokenCount(used)} of ${formatTokenCount(limit)} tokens used`}\n          style={{\n            height: 18,\n            borderRadius: 999,\n            background: \"var(--aurora-control-surface)\",\n            overflow: \"hidden\",\n            position: \"relative\",\n          }}\n        >\n          <div\n            style={{\n              width: `${percent}%`,\n              height: \"100%\",\n              borderRadius: 999,\n              background: \"linear-gradient(90deg, var(--axon-orange), var(--aurora-accent-primary))\",\n            }}\n          />\n          <span\n            aria-hidden=\"true\"\n            style={{\n              position: \"absolute\",\n              insetInlineStart: 6,\n              top: \"50%\",\n              transform: \"translateY(-50%)\",\n              borderRadius: 999,\n              background: \"var(--aurora-overlay)\",\n              color: \"var(--aurora-text-primary)\",\n              fontSize: 10,\n              fontWeight: 700,\n              lineHeight: 1,\n              padding: \"2px 5px\",\n            }}\n          >\n            {Math.round(percent)}%\n          </span>\n        </div>\n      </div>\n    )\n  }\nContextPanel.displayName = \"ContextPanel\"\n\nconst Conversation = ({ ref, className, style, ...props }: ConversationProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div\n      ref={ref}\n      role=\"log\"\n      aria-live=\"polite\"\n      aria-label=\"Conversation\"\n      className={cn(\"grid gap-4 border p-4\", className)}\n      style={{\n        ...panelStyle(style),\n        background: [\n          \"radial-gradient(circle at 10% 0%, color-mix(in srgb, var(--axon-orange) 10%, transparent), transparent 34%)\",\n          \"linear-gradient(180deg, color-mix(in srgb, var(--aurora-panel-strong) 96%, transparent), var(--aurora-panel-medium))\",\n        ].join(\", \"),\n        maxHeight: 520,\n        overflowY: \"auto\",\n      }}\n      {...props}\n    />\n  )\nConversation.displayName = \"Conversation\"\n\nconst ModelSelector = ({ ref, models, value, defaultValue, onValueChange, label = \"Model\", name, disabled, required, triggerId, triggerLabel, className, style, ...props }: ModelSelectorProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={className} style={style} {...props}>\n      <SelectorCard\n        icon={<Sparkles className=\"size-3.5\" aria-hidden style={{ color: \"var(--axon-orange)\" }} />}\n        title={label}\n        description=\"Select a model for this conversation.\"\n        values={models}\n        value={value}\n        defaultValue={defaultValue}\n        onValueChange={onValueChange}\n        name={name}\n        disabled={disabled}\n        required={required}\n        triggerId={triggerId}\n        triggerLabel={triggerLabel ?? label}\n      />\n    </div>\n  )\nModelSelector.displayName = \"ModelSelector\"\n\nconst Queue = ({ ref, tasks, ...props }: QueueProps & { ref?: React.Ref<HTMLDivElement> }) => <TaskList ref={ref} tasks={tasks} {...props} />\nQueue.displayName = \"Queue\"\n\nconst Shimmer = ({ ref, className, style, ...props }: React.HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div\n      ref={ref}\n      className={cn(\"h-3 overflow-hidden rounded-full\", className)}\n      style={{\n        background: \"linear-gradient(90deg, var(--aurora-control-surface), color-mix(in srgb, var(--axon-orange) 18%, transparent), var(--aurora-control-surface))\",\n        backgroundSize: \"220% 100%\",\n        animation: \"aurora-shimmer 1.4s linear infinite\",\n        ...style,\n      }}\n      {...props}\n    />\n  )\nShimmer.displayName = \"Shimmer\"\n\nconst Suggestion = ({ ref, className, style, options, children, onClick, disabled, ...props }: SuggestionProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid gap-2\", className)} style={{ width: \"100%\", minWidth: 0, ...style }} {...props}>\n      {(options ?? [{ id: \"default\", title: typeof children === \"string\" ? children : \"Suggested next step\" }]).map((option) => (\n        <Button\n          key={option.id}\n          type=\"button\"\n          variant=\"neutral\"\n          disabled={disabled}\n          onClick={onClick}\n          className=\"h-auto min-w-0 justify-start whitespace-normal rounded-[10px] border px-3 py-3 text-left\"\n          style={{\n            borderColor: \"color-mix(in srgb, var(--axon-orange) 18%, var(--aurora-border-default))\",\n            background: \"color-mix(in srgb, var(--axon-orange) 4%, var(--aurora-panel-medium))\",\n          }}\n        >\n          <span className=\"grid min-w-0 gap-1\">\n            <span className=\"flex min-w-0 flex-wrap items-center gap-2\">\n              <span className=\"aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{option.title}</span>\n              {option.badge ? <Badge shape=\"tag\">{option.badge}</Badge> : null}\n            </span>\n            {option.description ? <span className=\"aurora-text-meta\" style={{ minWidth: 0 }}>{option.description}</span> : null}\n          </span>\n        </Button>\n      ))}\n    </div>\n  )\nSuggestion.displayName = \"Suggestion\"\n\nconst Agent = ({ ref, name, role, status = \"idle\", className, style, ...props }: AgentProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <Bot className=\"size-[18px]\" aria-hidden style={{ color: \"var(--axon-orange)\" }} />\n      <span className=\"min-w-0\">\n        <span className=\"block truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{name}</span>\n        {role ? <span className=\"block aurora-text-meta\">{role}</span> : null}\n      </span>\n      <Badge tone={status === \"blocked\" ? \"warn\" : status === \"running\" ? \"success\" : \"neutral\"} dot={status === \"running\"}>\n        {formatStatusLabel(status)}\n      </Badge>\n    </div>\n  )\nAgent.displayName = \"Agent\"\n\nconst Commit = ({ ref, hash, message, author, className, style, ...props }: CommitProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)] gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <GitCommitHorizontal className=\"size-4\" aria-hidden style={{ color: \"var(--aurora-accent-primary)\" }} />\n      <span className=\"min-w-0\">\n        <span className=\"block truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{message}</span>\n        <span className=\"block aurora-text-meta\">{hash}{author ? ` by ${author}` : \"\"}</span>\n      </span>\n    </div>\n  )\nCommit.displayName = \"Commit\"\n\nconst JsxPreview = ({ ref, code, className, style, ...props }: JsxPreviewProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={className} style={style} {...props}>\n      <CodeSurface icon={<FileCode className=\"size-3.5\" aria-hidden />} title=\"JSX Preview\" value={code}>\n        <pre className=\"overflow-auto rounded-[7px] border p-3 aurora-text-code\" style={{ borderColor: \"var(--aurora-border-default)\", background: \"var(--aurora-panel-strong)\" }}>{code}</pre>\n      </CodeSurface>\n    </div>\n  )\nJsxPreview.displayName = \"JsxPreview\"\n\nconst PackageInfo = ({ ref, name, version, description, className, style, ...props }: PackageInfoProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)] gap-3 rounded-[8px] border p-3\", className)} style={panelStyle(style)} {...props}>\n      <Package className=\"size-5\" aria-hidden style={{ color: \"var(--aurora-accent-primary)\" }} />\n      <span className=\"min-w-0\">\n        <span className=\"block truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{name}</span>\n        <span className=\"block aurora-text-meta\" style={{ color: \"var(--aurora-accent-strong)\" }}>{version}</span>\n        {description ? <span className=\"block aurora-text-meta\">{description}</span> : null}\n      </span>\n    </div>\n  )\nPackageInfo.displayName = \"PackageInfo\"\n\nconst Sandbox = ({ ref, title = \"Sandbox\", command = \"pnpm dev\", status = \"running\", runtime = \"Node 20\", paths = [\"/workdir/app\", \"/workdir/.next\"], envCount = 8, className, style, children, ...props }: SandboxProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <div className=\"flex items-center justify-between gap-2\">\n        <span className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}><Boxes className=\"size-3.5\" aria-hidden />{title}</span>\n        <Badge tone={status === \"running\" ? \"success\" : \"neutral\"} dot={status === \"running\"}>\n          {formatStatusLabel(status)}\n        </Badge>\n      </div>\n      <div className=\"grid gap-3 rounded-[8px] border p-3\" style={{ borderColor: \"var(--aurora-border-default)\", background: \"var(--aurora-panel-strong)\" }}>\n        <div className=\"flex flex-wrap items-center gap-2\">\n          <Badge>{command}</Badge>\n          <Badge tone=\"neutral\" shape=\"tag\">{runtime}</Badge>\n          <Badge tone=\"neutral\" shape=\"tag\">{envCount} Env Vars</Badge>\n        </div>\n        <div className=\"grid gap-2\">\n          {paths.map((path) => (\n            <div key={path} className=\"flex items-center gap-2 rounded-[7px] border px-3 py-2\" style={{ borderColor: \"var(--aurora-border-default)\" }}>\n              <FileText className=\"size-3.5\" aria-hidden style={{ color: \"var(--aurora-text-muted)\" }} />\n              <span className=\"truncate aurora-text-meta\" style={{ color: \"var(--aurora-text-primary)\" }}>{path}</span>\n            </div>\n          ))}\n        </div>\n        <div className=\"flex flex-wrap gap-2\">\n          <Button type=\"button\" variant=\"neutral\" size=\"sm\">Open Logs</Button>\n          <Button type=\"button\" variant=\"ghost\" size=\"sm\">Attach Shell</Button>\n        </div>\n      </div>\n      {children}\n    </div>\n  )\nSandbox.displayName = \"Sandbox\"\n\nconst SchemaDisplay = ({ ref, schema, className, style, ...props }: SchemaDisplayProps & { ref?: React.Ref<HTMLPreElement> }) => (\n    <div className={className} style={style}>\n      <CodeSurface icon={<FileCode className=\"size-3.5\" aria-hidden />} title=\"Schema Display\" value={stringifyWithOrder(schema)}>\n        <pre\n          ref={ref}\n          className=\"overflow-auto rounded-[7px] border p-3 aurora-text-code\"\n          style={{ borderColor: \"var(--aurora-border-default)\", background: \"var(--aurora-panel-strong)\" }}\n          {...props}\n        >\n          {renderJsonValue(schema)}\n        </pre>\n      </CodeSurface>\n    </div>\n  )\nSchemaDisplay.displayName = \"SchemaDisplay\"\n\nconst Snippet = ({ ref, code, language = \"tsx\", className, style, ...props }: SnippetProps & { ref?: React.Ref<HTMLPreElement> }) => (\n    <div className={className} style={style}>\n      <CodeSurface icon={<FileCode className=\"size-3.5\" aria-hidden />} title=\"Snippet\" value={code}>\n        <pre\n          ref={ref}\n          className=\"overflow-auto rounded-[7px] border p-3 aurora-text-code\"\n          style={{ borderColor: \"var(--aurora-border-default)\", background: \"var(--aurora-panel-strong)\" }}\n          {...props}\n        >\n          <span style={{ color: \"var(--aurora-text-muted)\" }}>{language}</span>\n          {\"\\n\"}\n          {code}\n        </pre>\n      </CodeSurface>\n    </div>\n  )\nSnippet.displayName = \"Snippet\"\n\nconst Image = ({ ref, caption, className, style, alt = \"\", ...props }: AuroraImageProps & { ref?: React.Ref<HTMLImageElement> }) => (\n    <figure className={cn(\"grid gap-2\", className)} style={{ margin: 0 }}>\n      <img ref={ref} alt={alt} className=\"w-full rounded-[8px] border object-cover\" style={{ borderColor: \"var(--aurora-border-default)\", ...style }} {...props} />\n      {caption ? <figcaption className=\"aurora-text-meta\">{caption}</figcaption> : null}\n    </figure>\n  )\nImage.displayName = \"Image\"\n\nconst OpenInChat = ({ ref, children = \"Open in Chat\", ...props }: OpenInChatProps & { ref?: React.Ref<HTMLButtonElement> }) => (\n    <Button ref={ref} type=\"button\" variant=\"neutral\" size=\"sm\" {...props}>\n      <Send className=\"size-3.5\" data-icon=\"inline-start\" aria-hidden />\n      {children}\n    </Button>\n  )\nOpenInChat.displayName = \"OpenInChat\"\n\nconst AudioPlayer = ({ ref, title = \"Voice Response\", duration = \"00:42\", className, style, ...props }: AudioPlayerProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <Button type=\"button\" size=\"icon\" variant=\"neutral\" aria-label={`Play ${title}`}>\n        <Play className=\"size-4\" data-icon=\"inline-start\" aria-hidden />\n      </Button>\n      <span className=\"min-w-0\">\n        <span className=\"block truncate aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{title}</span>\n        <span className=\"block h-1.5 rounded-full\" style={{ background: \"linear-gradient(90deg, var(--aurora-accent-primary) 48%, var(--aurora-control-surface) 48%)\" }} />\n      </span>\n      <span className=\"aurora-text-meta\">{duration}</span>\n    </div>\n  )\nAudioPlayer.displayName = \"AudioPlayer\"\n\nconst MicSelector = ({ ref, devices, value, defaultValue, onValueChange, name, disabled, required, triggerId, triggerLabel, ...props }: MicSelectorProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} {...props}>\n      <SelectorCard\n        icon={<Mic className=\"size-3.5\" aria-hidden />}\n        title=\"Microphone\"\n        description=\"Swap inputs without dropping back to a native control.\"\n        values={devices}\n        value={value}\n        defaultValue={defaultValue}\n        onValueChange={onValueChange}\n        name={name}\n        disabled={disabled}\n        required={required}\n        triggerId={triggerId}\n        triggerLabel={triggerLabel ?? \"Microphone\"}\n      />\n    </div>\n  )\nMicSelector.displayName = \"MicSelector\"\n\nconst Persona = ({ ref, name, description, className, style, ...props }: PersonaProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid grid-cols-[auto_minmax(0,1fr)] gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <UserRound className=\"size-5\" aria-hidden style={{ color: \"var(--aurora-accent-pink)\" }} />\n      <span className=\"min-w-0\">\n        <span className=\"block aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{name}</span>\n        {description ? <span className=\"block aurora-text-meta\">{description}</span> : null}\n      </span>\n    </div>\n  )\nPersona.displayName = \"Persona\"\n\nconst SpeechInput = ({ ref, className, style, ...props }: SpeechInputProps & { ref?: React.Ref<HTMLTextAreaElement> }) => (\n    <div className=\"grid gap-2 border p-3\" style={panelStyle()}>\n      <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}><Mic className=\"size-3.5\" aria-hidden />Speech Input</div>\n      <Textarea ref={ref} className={cn(\"min-h-20 resize-none rounded-[8px] p-3 aurora-text-body\", className)} style={{ ...style }} {...props} />\n    </div>\n  )\nSpeechInput.displayName = \"SpeechInput\"\n\nconst Transcription = ({ ref, segments, className, style, ...props }: TranscriptionProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"grid gap-2 rounded-[8px] border p-3\", className)} style={panelStyle(style)} {...props}>\n      <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}>\n        <Mic className=\"size-3.5\" aria-hidden />\n        Transcription\n      </div>\n      <div className=\"grid gap-2\">\n        {segments.map((segment) => (\n          <div\n            key={`${segment.speaker}-${segment.timecode}`}\n            className=\"grid grid-cols-[72px_minmax(0,1fr)_auto] gap-3 rounded-[7px] border px-3 py-2\"\n            style={{ borderColor: \"var(--aurora-border-default)\", background: \"var(--aurora-panel-strong)\" }}\n          >\n            <span className=\"aurora-text-meta\" style={{ color: \"var(--aurora-accent-strong)\" }}>{segment.timecode}</span>\n            <span className=\"min-w-0\">\n              <span className=\"block aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}>{segment.speaker}</span>\n              <span className=\"block aurora-text-body\" style={{ marginTop: 4 }}>{segment.text}</span>\n            </span>\n            <Badge tone=\"neutral\" shape=\"tag\">{segment.confidence ? `${segment.confidence}%` : \"Live\"}</Badge>\n          </div>\n        ))}\n      </div>\n    </div>\n  )\nTranscription.displayName = \"Transcription\"\n\nconst VoiceSelector = ({ ref, voices, value, defaultValue, onValueChange, name, disabled, required, triggerId, triggerLabel, ...props }: VoiceSelectorProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} {...props}>\n      <SelectorCard\n        icon={<Sparkles className=\"size-3.5\" aria-hidden style={{ color: \"var(--axon-orange)\" }} />}\n        title=\"Voice\"\n        description=\"Select a voice for audio output.\"\n        values={voices}\n        value={value}\n        defaultValue={defaultValue}\n        onValueChange={onValueChange}\n        name={name}\n        disabled={disabled}\n        required={required}\n        triggerId={triggerId}\n        triggerLabel={triggerLabel ?? \"Voice\"}\n      />\n    </div>\n  )\nVoiceSelector.displayName = \"VoiceSelector\"\n\nconst Canvas = ({ ref, className, style, ...props }: CanvasProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"relative min-h-64 border p-4\", className)} style={{ ...panelStyle(style), backgroundImage: \"linear-gradient(var(--aurora-border-default) 1px, transparent 1px), linear-gradient(90deg, var(--aurora-border-default) 1px, transparent 1px)\", backgroundSize: \"24px 24px\" }} {...props} />\n  )\nCanvas.displayName = \"Canvas\"\n\nconst Connection = ({ ref, from, to, className, style, ...props }: ConnectionProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"flex items-center gap-2 aurora-text-control\", className)} style={{ color: \"var(--aurora-text-primary)\", ...style }} {...props}>\n      <Network className=\"size-4\" aria-hidden style={{ color: \"var(--aurora-accent-primary)\" }} />{from}<Route className=\"size-4\" aria-hidden />{to}\n    </div>\n  )\nConnection.displayName = \"Connection\"\n\nconst Controls = ({ ref, className, style, ...props }: ControlsProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"flex items-center gap-2 border p-2\", className)} style={panelStyle(style)} {...props} />\n  )\nControls.displayName = \"Controls\"\n\nconst Edge = ({ ref, label = \"Edge\", className, style, ...props }: EdgeProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"flex items-center gap-2 aurora-text-meta\", className)} style={style} {...props}>\n      <span className=\"h-px flex-1\" style={{ background: \"var(--aurora-accent-primary)\" }} />\n      {label}\n      <span className=\"h-px flex-1\" style={{ background: \"var(--aurora-accent-primary)\" }} />\n    </div>\n  )\nEdge.displayName = \"Edge\"\n\nconst Node = ({ ref, title, description, className, style, ...props }: NodeProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div ref={ref} className={cn(\"w-56 border p-3\", className)} style={panelStyle(style)} {...props}>\n      <div className=\"flex items-center gap-2 aurora-text-control\" style={{ color: \"var(--aurora-text-primary)\" }}><Workflow className=\"size-4\" aria-hidden style={{ color: \"var(--aurora-accent-primary)\" }} />{title}</div>\n      {description ? <div className=\"aurora-text-meta\">{description}</div> : null}\n    </div>\n  )\nNode.displayName = \"Node\"\n\nconst Panel = ({ ref, title, className, children, style, ...props }: PanelProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <aside ref={ref} className={cn(\"grid gap-3 border p-3\", className)} style={panelStyle(style)} {...props}>\n      {title ? <div className=\"flex items-center gap-2 aurora-text-label\" style={{ color: \"var(--aurora-text-muted)\" }}><Sparkles className=\"size-3.5 shrink-0\" aria-hidden style={{ color: \"var(--axon-orange)\" }} />{title}</div> : null}\n      {children}\n    </aside>\n  )\nPanel.displayName = \"Panel\"\n\nexport {\n  Agent,\n  AudioPlayer,\n  Canvas,\n  Checkpoint,\n  Commit,\n  Confirmation,\n  Connection,\n  ContextPanel,\n  ContextPanel as Context,\n  Controls,\n  Conversation,\n  Edge,\n  EnvironmentVariables,\n  Image,\n  InlineCitation,\n  JsxPreview,\n  MicSelector,\n  Message,\n  MessageAvatar,\n  MessageContent,\n  ModelSelector,\n  Node,\n  OpenInChat,\n  PackageInfo,\n  Panel,\n  Persona,\n  Queue,\n  Sandbox,\n  SchemaDisplay,\n  Shimmer,\n  Snippet,\n  Source,\n  Sources,\n  SpeechInput,\n  StackTrace,\n  Suggestion,\n  TaskList,\n  TestResults,\n  Transcription,\n  VoiceSelector,\n}\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/core.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/canvas.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Minus, Plus } from \"lucide-react\"\nimport { Action } from \"./action\"\nimport { cn } from \"@/lib/utils\"\n\n/* ------------------------------------------------------------------ *\n * Aurora · Canvas (AI element)\n *\n * A flow canvas with a header chip (status dot + title), a node-count\n * badge, a dotted-grid surface, absolutely-positioned nodes carrying\n * cyan input ports (left) + rose output ports (right), cyan bezier\n * edges that follow the nodes, and a zoom toolbar.\n *\n * Architecture (forwardRef, displayName, compound Node, HTMLAttributes\n * passthrough) is kept from the Aurora registry, while controls and typography\n * follow Aurora tokens and primitives.\n * ------------------------------------------------------------------ */\n\ntype CanvasStatus = \"running\" | \"idle\" | \"blocked\"\n\nexport interface CanvasEdge {\n  /** index of the source Node child */\n  from: number\n  /** index of the target Node child */\n  to: number\n}\n\nexport interface CanvasProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title?: React.ReactNode\n  status?: CanvasStatus\n  /** edges drawn between Node children, by child index */\n  edges?: CanvasEdge[]\n}\n\nexport interface NodeProps extends React.HTMLAttributes<HTMLDivElement> {\n  title: string\n  description?: string\n}\n\nconst statusGlow: Record<CanvasStatus, { dot: string; glow: string }> = {\n  running: {\n    dot: \"var(--aurora-accent-primary)\",\n    glow: \"0 0 0 3px color-mix(in srgb, var(--aurora-accent-primary) 22%, transparent), 0 0 12px color-mix(in srgb, var(--aurora-accent-primary) 60%, transparent)\",\n  },\n  idle: {\n    dot: \"var(--aurora-text-muted)\",\n    glow: \"0 0 0 3px color-mix(in srgb, var(--aurora-text-muted) 18%, transparent)\",\n  },\n  blocked: {\n    dot: \"var(--axon-orange)\",\n    glow: \"0 0 0 3px color-mix(in srgb, var(--axon-orange) 22%, transparent), 0 0 12px color-mix(in srgb, var(--axon-orange) 55%, transparent)\",\n  },\n}\n\n/* Geometry parsed from a Node child's inline style. Nodes are positioned with\n * absolute left/top + a fixed width; height is estimated from the node card\n * chrome so edges can anchor to the vertical port center. */\ntype NodeBox = { left: number; top: number; width: number; height: number }\n\nconst NODE_HEIGHT = 64\nconst PORT = 12\n\nfunction parseLen(value: string | number | undefined, fallback: number): number {\n  if (typeof value === \"number\") return value\n  if (typeof value === \"string\") {\n    const n = parseFloat(value)\n    if (!Number.isNaN(n)) return n\n  }\n  return fallback\n}\n\nfunction nodeBox(style: React.CSSProperties | undefined): NodeBox {\n  return {\n    left: parseLen(style?.left as string | number | undefined, 0),\n    top: parseLen(style?.top as string | number | undefined, 0),\n    width: parseLen(style?.width as string | number | undefined, 128),\n    height: parseLen(style?.height as string | number | undefined, NODE_HEIGHT),\n  }\n}\n\n/* Horizontal-tangent cubic bezier from a source right-port to a target\n * left-port so edges follow the nodes. */\nfunction edgePath(a: NodeBox, b: NodeBox): string {\n  const x1 = a.left + a.width\n  const y1 = a.top + a.height / 2\n  const x2 = b.left\n  const y2 = b.top + b.height / 2\n  const dx = Math.max(40, Math.abs(x2 - x1) * 0.6)\n  return `M ${x1} ${y1} C ${x1 + dx} ${y1}, ${x2 - dx} ${y2}, ${x2} ${y2}`\n}\n\nconst Node = ({ ref, title, description, className, style, ...props }: NodeProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div\n      ref={ref}\n      className={cn(\"group/node\", className)}\n      style={{\n        position: \"absolute\",\n        boxSizing: \"border-box\",\n        padding: \"10px 14px\",\n        background: \"var(--aurora-surface-raised)\",\n        border: \"1px solid var(--aurora-border-strong)\",\n        borderRadius: \"var(--aurora-radius-1)\",\n        boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n        cursor: \"grab\",\n        ...style,\n      }}\n      {...props}\n    >\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          gap: 8,\n          fontFamily: \"var(--aurora-font-display)\",\n          fontWeight: 700,\n          fontSize: 15,\n          lineHeight: 1.2,\n          color: \"var(--aurora-text-primary)\",\n        }}\n      >\n        <span\n          aria-hidden\n          style={{\n            width: 8,\n            height: 8,\n            borderRadius: 9999,\n            flexShrink: 0,\n            background: \"var(--aurora-accent-primary)\",\n            boxShadow: \"0 0 8px color-mix(in srgb, var(--aurora-accent-primary) 60%, transparent)\",\n          }}\n        />\n        {title}\n      </div>\n      {description ? (\n        <div\n          style={{\n            marginTop: 4,\n            fontFamily: \"var(--aurora-font-sans)\",\n            fontSize: 13,\n            color: \"var(--aurora-text-muted)\",\n          }}\n        >\n          {description}\n        </div>\n      ) : null}\n\n      {/* input port (cyan, filled) — left edge */}\n      <span\n        aria-hidden\n        style={{\n          position: \"absolute\",\n          left: -PORT / 2,\n          top: \"50%\",\n          transform: \"translateY(-50%)\",\n          width: PORT,\n          height: PORT,\n          borderRadius: 9999,\n          background: \"var(--aurora-accent-primary)\",\n          border: \"2px solid var(--aurora-page-bg)\",\n          boxShadow: \"0 0 8px color-mix(in srgb, var(--aurora-accent-primary) 55%, transparent)\",\n        }}\n      />\n      {/* output port (rose, hollow) — right edge */}\n      <span\n        aria-hidden\n        style={{\n          position: \"absolute\",\n          right: -PORT / 2,\n          top: \"50%\",\n          transform: \"translateY(-50%)\",\n          width: PORT,\n          height: PORT,\n          borderRadius: 9999,\n          background: \"var(--aurora-page-bg)\",\n          border: \"2px solid var(--aurora-accent-pink)\",\n          boxShadow: \"0 0 8px color-mix(in srgb, var(--aurora-accent-pink) 45%, transparent)\",\n        }}\n      />\n    </div>\n  )\nNode.displayName = \"Node\"\n\nconst Canvas = ({ ref, title, status = \"idle\", edges = [], className, style, children, ...props }: CanvasProps & { ref?: React.Ref<HTMLDivElement> }) => {\n    const nodes = React.Children.toArray(children).filter(\n      (c): c is React.ReactElement<NodeProps> => React.isValidElement(c)\n    )\n    const boxes = nodes.map((n) => nodeBox((n.props as NodeProps).style))\n    const glow = statusGlow[status] ?? statusGlow.idle\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\"relative overflow-hidden\", className)}\n        style={{\n          minHeight: 250,\n          boxSizing: \"border-box\",\n          padding: 16,\n          background: \"var(--aurora-surface-raised)\",\n          border: \"1px solid var(--aurora-border-strong)\",\n          borderRadius: \"var(--aurora-radius-2)\",\n          boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n          backgroundImage:\n            \"radial-gradient(circle, color-mix(in srgb, var(--aurora-border-default) 70%, transparent) 1px, transparent 1px)\",\n          backgroundSize: \"22px 22px\",\n          backgroundPosition: \"10px 10px\",\n          ...style,\n        }}\n        {...props}\n      >\n        {/* edges layer */}\n        <svg\n          aria-hidden\n          style={{ position: \"absolute\", inset: 0, width: \"100%\", height: \"100%\", pointerEvents: \"none\", overflow: \"visible\" }}\n        >\n          {edges.map((e, i) => {\n            const a = boxes[e.from]\n            const b = boxes[e.to]\n            if (!a || !b) return null\n            return (\n              <path\n                key={i}\n                d={edgePath(a, b)}\n                fill=\"none\"\n                stroke=\"var(--aurora-accent-primary)\"\n                strokeWidth={2}\n                strokeLinecap=\"round\"\n                style={{ filter: \"drop-shadow(0 0 4px color-mix(in srgb, var(--aurora-accent-primary) 45%, transparent))\" }}\n              />\n            )\n          })}\n        </svg>\n\n        {/* header: status chip + node count */}\n        {(title != null || nodes.length > 0) && (\n          <div style={{ position: \"absolute\", top: 16, left: 16, right: 16, display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", pointerEvents: \"none\", zIndex: 2 }}>\n            {title != null ? (\n              <div\n                style={{\n                  display: \"inline-flex\",\n                  alignItems: \"center\",\n                  gap: 9,\n                  padding: \"8px 14px\",\n                  background: \"var(--aurora-surface-raised)\",\n                  border: \"1px solid var(--aurora-border-strong)\",\n                  borderRadius: 9999,\n                  boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n                  pointerEvents: \"auto\",\n                }}\n              >\n                <span\n                  aria-hidden\n                  style={{ width: 9, height: 9, borderRadius: 9999, background: glow.dot, boxShadow: glow.glow }}\n                />\n                <span\n                  style={{\n                    fontFamily: \"var(--aurora-font-display)\",\n                    fontWeight: 700,\n                    fontSize: 15,\n                    color: \"var(--aurora-text-primary)\",\n                  }}\n                >\n                  {title}\n                </span>\n              </div>\n            ) : (\n              <span />\n            )}\n            <div\n              style={{\n                display: \"inline-flex\",\n                alignItems: \"center\",\n                padding: \"6px 12px\",\n                fontFamily: \"var(--aurora-font-sans)\",\n                fontSize: 13,\n                fontWeight: 560,\n                color: \"var(--aurora-text-muted)\",\n                background: \"color-mix(in srgb, var(--aurora-control-surface) 60%, transparent)\",\n                border: \"1px solid var(--aurora-border-default)\",\n                borderRadius: 9999,\n                pointerEvents: \"auto\",\n              }}\n            >\n              {nodes.length} {nodes.length === 1 ? \"node\" : \"nodes\"}\n            </div>\n          </div>\n        )}\n\n        {/* nodes layer */}\n        <div style={{ position: \"relative\", zIndex: 1 }}>{children}</div>\n\n        {/* zoom toolbar */}\n        <div\n          style={{\n            position: \"absolute\",\n            bottom: 16,\n            right: 16,\n            display: \"inline-flex\",\n            alignItems: \"center\",\n            gap: 4,\n            padding: 4,\n            background: \"var(--aurora-surface-raised)\",\n            border: \"1px solid var(--aurora-border-strong)\",\n            borderRadius: \"var(--aurora-radius-1)\",\n            boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n            zIndex: 2,\n          }}\n        >\n          <Action size=\"sm\" aria-label=\"Zoom out\">\n            <Minus aria-hidden width={16} height={16} strokeWidth={1.65} />\n          </Action>\n          <span\n            style={{\n              fontFamily: \"var(--aurora-font-sans)\",\n              fontSize: 13,\n              fontWeight: 560,\n              color: \"var(--aurora-text-primary)\",\n              minWidth: 44,\n              textAlign: \"center\",\n              fontVariantNumeric: \"tabular-nums\",\n            }}\n          >\n            100%\n          </span>\n          <Action size=\"sm\" aria-label=\"Zoom in\">\n            <Plus aria-hidden width={16} height={16} strokeWidth={1.65} />\n          </Action>\n        </div>\n      </div>\n    )\n  }\nCanvas.displayName = \"Canvas\"\n\nexport { Canvas, Node }\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/canvas.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/action.tsx",
      "content": "\"use client\"\n\n/**\n * Aurora Action — a quiet, icon-first action button for AI message affordances\n * (copy / retry / thumbs-up, etc.).\n *\n * Architecture stays shadcn-compatible: typed props, `forwardRef`,\n * `displayName`, `React.memo`, a real `<button>` with proper a11y\n * (`aria-pressed` mirrors the `pressed` toggle; `label` becomes the visible\n * text, otherwise consumers pass `aria-label`). Styling reads `--aurora-*`\n * tokens through stable data attributes so the registry stays config-free\n * (Tailwind v4) and tokens drive every value.\n */\n\n// Styles: registry/aurora/styles/aurora-components.css (@layer aurora-components).\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\n\nexport interface ActionProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  /** Optional visible label, rendered after the icon (icon + text variant). */\n  label?: React.ReactNode\n  /** Toggled / affirmative state — applies the rose-tinted styling + aria-pressed. */\n  pressed?: boolean\n  /** Size scale. */\n  size?: \"default\" | \"sm\"\n}\n\nconst Action = (\n    { ref,\n      className,\n      children,\n      label,\n      pressed,\n      size = \"default\",\n      style,\n      type = \"button\",\n      ...props\n    }: ActionProps & { ref?: React.Ref<HTMLButtonElement> }\n  ) => {\n    const hasLabel = label != null && label !== false\n    const shape = hasLabel ? \"text\" : \"icon\"\n    const sizeStyle: React.CSSProperties | undefined =\n      size === \"sm\"\n        ? hasLabel\n          ? { height: 30, paddingInline: 6, borderRadius: 7 }\n          : { width: 30, height: 30, borderRadius: 9 }\n        : undefined\n\n    return (\n      <button\n        ref={ref}\n        type={type}\n        data-shape={shape}\n        data-size={size}\n        data-has-label={hasLabel ? \"true\" : undefined}\n        data-pressed={pressed ? \"true\" : undefined}\n        aria-pressed={pressed != null ? pressed : undefined}\n        className={cn(\"aurora-action\", className)}\n        style={{ ...sizeStyle, ...style }}\n        {...props}\n      >\n        {children}\n        {hasLabel ? <span className=\"aurora-action__label\">{label}</span> : null}\n      </button>\n    )\n  }\nAction.displayName = \"Action\"\n\nconst MemoAction = React.memo(Action)\nMemoAction.displayName = \"Action\"\n\nexport { MemoAction as Action }\nexport default MemoAction\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/action.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/actions.tsx",
      "content": "\"use client\"\n\n/**\n * Aurora Actions — a horizontal row of message/turn action buttons.\n *\n * `Actions` is the row container (flex, 8px gap). Import `Action` from\n * `./action` or from the `ai-elements` barrel so the registry has one\n * canonical action button implementation.\n *\n * Architecture stays shadcn-compatible: compound `Actions` + `Action` parts, `forwardRef`,\n * `displayName`, `React.memo`, native button props (`onClick`, `disabled`,\n * `type`), and full a11y (`aria-label` for icon-only, `aria-pressed` for\n * toggles, focus-visible ring). No `violet`.\n */\n\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\nexport { Action } from \"./action\"\nexport type { ActionProps } from \"./action\"\n\n// Styles: registry/aurora/styles/aurora-components.css (@layer aurora-components).\n\nexport type ActionsProps = React.HTMLAttributes<HTMLDivElement>\n\nconst Actions = ({ ref, className, children, ...props }: ActionsProps & { ref?: React.Ref<HTMLDivElement> }) => (\n    <div\n      ref={ref}\n      role=\"group\"\n      className={cn(\"aurora-actions\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  )\nActions.displayName = \"Actions\"\n\nconst MemoActions = React.memo(Actions)\nMemoActions.displayName = \"Actions\"\n\nexport { MemoActions as Actions }\nexport default MemoActions\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/actions.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/source.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ExternalLink, Globe } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\nimport { safeHttpUrl } from \"@/registry/aurora/lib/safe-url\"\n\n// ---------------------------------------------------------------------------\n// Types (architecture source of truth — preserve the existing registry API)\n// ---------------------------------------------------------------------------\n\nexport interface SourceItem {\n  title: string\n  href?: string\n  description?: string\n  badge?: string\n}\n\nexport interface SourceProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {\n  /** Source descriptor rendered in the citation row. */\n  source: SourceItem\n  /** Optional 1-based ordinal rendered in the rose numbered chip. */\n  index?: number\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction hostname(href?: string): string | null {\n  if (!href) return null\n  try {\n    return new URL(href).hostname.replace(/^www\\./, \"\")\n  } catch {\n    return href.replace(/^https?:\\/\\//, \"\").replace(/^www\\./, \"\").split(\"/\")[0] || null\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Source — standalone citation row: rose index chip, domain, badge, hover lit.\n// Visual spec ported 1:1 from the Claude Design dsCard (control-surface card,\n// rose numbered chip, bold title, neutral uppercase badge, globe + host,\n// external-link arrow). Hover lifts the surface and border.\n// ---------------------------------------------------------------------------\n\nconst Source = ({ ref, className, source, index, style, href, target, rel, tabIndex, ...props }: SourceProps & { ref?: React.Ref<HTMLAnchorElement> }) => {\n    const safeHref = safeHttpUrl(href ?? source.href)\n    const host = hostname(safeHref)\n    const isLinked = Boolean(safeHref)\n\n    return (\n      <a\n        ref={ref}\n        {...props}\n        href={safeHref}\n        target={target ?? (isLinked ? \"_blank\" : undefined)}\n        rel={rel ?? (isLinked ? \"noreferrer noopener\" : undefined)}\n        tabIndex={tabIndex ?? (isLinked ? undefined : -1)}\n        aria-disabled={isLinked ? undefined : true}\n        aria-label={host ? `${source.title}, ${host}` : source.title}\n        className={cn(\n          \"group grid grid-cols-[auto_minmax(0,1fr)_auto] items-start gap-3 p-3.5 no-underline\",\n          \"transition-[background,border-color,box-shadow,transform] duration-150 ease-out\",\n          \"outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--aurora-focus-ring)] focus-visible:ring-offset-0\",\n          isLinked &&\n            \"hover:-translate-y-px hover:border-[color:var(--aurora-border-strong)] hover:bg-[var(--aurora-hover-bg)]\",\n          className\n        )}\n        style={{\n          background: \"var(--aurora-control-surface)\",\n          border: \"1px solid var(--aurora-border-default)\",\n          borderRadius: \"calc(var(--aurora-radius-1) - 4px)\",\n          color: \"var(--aurora-text-primary)\",\n          boxShadow: \"var(--aurora-highlight-medium)\",\n          ...style,\n        }}\n      >\n        {index != null ? (\n          <span\n            className=\"inline-flex size-7 shrink-0 items-center justify-center aurora-text-control\"\n            aria-hidden\n            style={{\n              borderRadius: \"calc(var(--aurora-radius-1) - 6px)\",\n              background: \"var(--aurora-accent-pink-surface)\",\n              border: \"1px solid var(--aurora-accent-pink-border)\",\n              color: \"var(--aurora-accent-pink-strong)\",\n              fontWeight: 700,\n              fontVariantNumeric: \"tabular-nums\",\n            }}\n          >\n            {index}\n          </span>\n        ) : (\n          <span className=\"shrink-0\" aria-hidden style={{ width: 0 }} />\n        )}\n\n        <span className=\"grid min-w-0 gap-1.5\">\n          <span className=\"flex min-w-0 items-center gap-2\">\n            <span\n              className=\"truncate aurora-text-control\"\n              style={{ color: \"var(--aurora-text-primary)\", fontSize: 16, fontWeight: 700 }}\n            >\n              {source.title}\n            </span>\n            {source.badge ? (\n              <Badge\n                tone=\"neutral\"\n                fill=\"outline\"\n                className=\"shrink-0\"\n              >\n                {source.badge}\n              </Badge>\n            ) : null}\n          </span>\n          {host ? (\n            <span\n              className=\"flex min-w-0 items-center gap-1.5 aurora-text-meta\"\n              style={{ color: \"var(--aurora-text-muted)\" }}\n            >\n              <Globe className=\"size-3.5 shrink-0\" aria-hidden />\n              <span className=\"truncate\">{host}</span>\n            </span>\n          ) : null}\n          {source.description ? <span className=\"aurora-text-meta\">{source.description}</span> : null}\n        </span>\n\n        {isLinked ? (\n          <ExternalLink\n            className=\"size-[18px] shrink-0 self-center text-[var(--aurora-text-muted)] transition-colors group-hover:text-[var(--aurora-accent-primary)]\"\n            aria-hidden\n          />\n        ) : (\n          <span aria-hidden className=\"size-[18px] shrink-0\" />\n        )}\n      </a>\n    )\n  }\nSource.displayName = \"Source\"\n\nexport { Source }\nexport default Source\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/source.tsx"
    },
    {
      "path": "registry/aurora/blocks/ai/elements/sources.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDown, FileText } from \"lucide-react\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\nimport { Button } from \"@/registry/aurora/ui/button\"\nimport { Source, type SourceItem, type SourceProps } from \"@/registry/aurora/blocks/ai/elements/source\"\n\n// ---------------------------------------------------------------------------\n// Types (architecture source of truth — keep the existing registry API)\n// ---------------------------------------------------------------------------\n\nexport interface SourcesProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title?: React.ReactNode\n  /** Render the count badge + chevron and allow the body to collapse. */\n  collapsible?: boolean\n  /** Control the collapsed state (uncontrolled defaults to expanded). */\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport type { SourceItem, SourceProps }\n\n// ---------------------------------------------------------------------------\n// Shared surface helpers (ported from CD injected CSS)\n// ---------------------------------------------------------------------------\n\nfunction panelStyle(style?: React.CSSProperties): React.CSSProperties {\n  return {\n    background: \"var(--aurora-surface-raised)\",\n    border: \"1px solid var(--aurora-border-strong)\",\n    borderRadius: \"var(--aurora-radius-1)\",\n    boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n    ...style,\n  }\n}\n\n\n// ---------------------------------------------------------------------------\n// Count badge — small neutral pill next to the title\n// ---------------------------------------------------------------------------\n\nfunction CountBadge({ count }: { count: number }) {\n  return (\n    <Badge\n      tone=\"neutral\"\n      fill=\"outline\"\n      className=\"min-w-[22px] justify-center px-1.5 tabular-nums\"\n    >\n      {count}\n    </Badge>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// Sources — bordered panel with file icon, title, count badge, collapsible body\n// ---------------------------------------------------------------------------\n\nconst Sources = (\n    { ref,\n      className,\n      title = \"Sources\",\n      collapsible = false,\n      open: openProp,\n      defaultOpen = true,\n      onOpenChange,\n      style,\n      children,\n      ...props\n    }: SourcesProps & { ref?: React.Ref<HTMLDivElement> }\n  ) => {\n    const isControlled = openProp !== undefined\n    const [openState, setOpenState] = React.useState(defaultOpen)\n    const open = isControlled ? openProp : openState\n\n    const count = React.Children.toArray(children).filter(React.isValidElement).length\n\n    const toggle = React.useCallback(() => {\n      const next = !open\n      if (!isControlled) setOpenState(next)\n      onOpenChange?.(next)\n    }, [open, isControlled, onOpenChange])\n\n    const headerInner = (\n      <>\n        <FileText className=\"size-[18px] shrink-0\" aria-hidden style={{ color: \"var(--aurora-accent-pink)\" }} />\n        <span\n          className=\"aurora-text-label\"\n          style={{ color: \"var(--aurora-text-primary)\", fontSize: 16, fontWeight: 700 }}\n        >\n          {title}\n        </span>\n        {collapsible ? <CountBadge count={count} /> : null}\n        {collapsible ? (\n          <ChevronDown\n            className=\"ml-auto size-[18px] shrink-0 transition-transform\"\n            aria-hidden\n            style={{\n              color: \"var(--aurora-text-muted)\",\n              transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n            }}\n          />\n        ) : null}\n      </>\n    )\n\n    return (\n      <div\n        ref={ref}\n        className={[\"grid gap-3 p-4\", className].filter(Boolean).join(\" \")}\n        style={panelStyle(style)}\n        {...props}\n      >\n        {collapsible ? (\n          <Button\n            type=\"button\"\n            variant=\"plain\"\n            size=\"unstyled\"\n            onClick={toggle}\n            aria-expanded={open}\n            className=\"flex items-center gap-2.5 bg-transparent p-0 text-left outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--aurora-focus-ring)] focus-visible:ring-offset-0\"\n            style={{ borderRadius: \"var(--aurora-radius-1)\", cursor: \"pointer\", color: \"inherit\" }}\n          >\n            {headerInner}\n          </Button>\n        ) : (\n          <div className=\"flex items-center gap-2.5\">{headerInner}</div>\n        )}\n        {!collapsible || open ? <div className=\"grid gap-2.5\">{children}</div> : null}\n      </div>\n    )\n  }\nSources.displayName = \"Sources\"\n\nexport { Source, Sources }\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/sources.tsx"
    }
  ],
  "meta": {
    "namespace": "@aurora",
    "style": "aurora",
    "family": "block",
    "requiresTokens": true,
    "sourcePath": "registry/aurora/blocks/ai/elements/ai-elements.tsx",
    "installTarget": "@components/aurora/ai/ai-elements.tsx",
    "taxonomy": "ai"
  },
  "docs": "Aurora AI Elements installs with its declared Aurora registry dependencies.\n\nDefault install target: `@components/aurora/ai/ai-elements.tsx`.\n\nRegistry dependencies: `aurora-tokens`, `aurora-avatar`, `aurora-badge`, `aurora-button`, `aurora-select`, `aurora-separator`, `aurora-spinner`, `aurora-textarea`, `aurora-clipboard`, `aurora-safe-url`.",
  "categories": [
    "aurora",
    "block",
    "ai"
  ],
  "type": "registry:block"
}