{
  "$schema": "https://www.cooki-ui.design/schema/registry-item.json",
  "name": "ai-streaming-bubble",
  "type": "registry:ui",
  "title": "AI Streaming Message Bubble",
  "description": "Simulated live streaming assistant bubble with glowing typing cursor, latency metrics, code snippet highlighter, and copy action.",
  "category": "ai",
  "dependencies": [
    "framer-motion",
    "@phosphor-icons/react"
  ],
  "files": [
    {
      "path": "registry/ai/ai-streaming-bubble/ai-streaming-bubble.tsx",
      "type": "registry:ui",
      "target": "components/ui/ai-streaming-bubble.tsx",
      "content": "import React, { useState, useEffect } from 'react';\nimport { motion } from 'framer-motion';\nimport { Copy, Check, ArrowClockwise, Cpu } from '@phosphor-icons/react';\n\nconst FULL_TEXT = `import { MagneticDock } from '@/components/ui'\n\n// Instantiating zero-backend component\nexport default function Preview() {\n  return <MagneticDock maxScale={1.4} />\n}`;\n\nexport const AiStreamingBubble: React.FC = () => {\n  const [displayedText, setDisplayedText] = useState('');\n  const [isDone, setIsDone] = useState(false);\n  const [copied, setCopied] = useState(false);\n\n  const startStream = () => {\n    setDisplayedText('');\n    setIsDone(false);\n    let index = 0;\n    const interval = setInterval(() => {\n      index++;\n      setDisplayedText(FULL_TEXT.slice(0, index));\n      if (index >= FULL_TEXT.length) {\n        clearInterval(interval);\n        setIsDone(true);\n      }\n    }, 28);\n  };\n\n  useEffect(() => {\n    startStream();\n  }, []);\n\n  const handleCopy = () => {\n    navigator.clipboard.writeText(FULL_TEXT);\n    setCopied(true);\n    setTimeout(() => setCopied(false), 2000);\n  };\n\n  return (\n    <div className=\"w-full max-w-md mx-auto rounded-2xl border border-zinc-200 dark:border-white/10 bg-white/90 dark:bg-zinc-900/90 p-4 shadow-lg backdrop-blur-md\">\n      <div className=\"flex items-center justify-between pb-3 border-b border-zinc-100 dark:border-white/5\">\n        <div className=\"flex items-center gap-2\">\n          <div className=\"h-6 w-6 rounded-lg bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400\">\n            <Cpu size={13} weight=\"bold\" />\n          </div>\n          <span className=\"text-xs font-mono font-semibold text-zinc-900 dark:text-zinc-100\">\n            Assistant Stream\n          </span>\n          <span className=\"text-[10px] font-mono px-1.5 py-0.2 rounded bg-emerald-500/10 text-emerald-500 border border-emerald-500/20\">\n            128 t/s\n          </span>\n        </div>\n\n        <div className=\"flex items-center gap-1\">\n          <button\n            onClick={startStream}\n            className=\"p-1 rounded text-zinc-400 hover:text-zinc-900 dark:hover:text-white\"\n            title=\"Replay stream\"\n          >\n            <ArrowClockwise size={13} />\n          </button>\n          <button\n            onClick={handleCopy}\n            className=\"p-1 rounded text-zinc-400 hover:text-zinc-900 dark:hover:text-white\"\n            title=\"Copy response\"\n          >\n            {copied ? <Check size={13} className=\"text-emerald-500\" /> : <Copy size={13} />}\n          </button>\n        </div>\n      </div>\n\n      <div className=\"mt-3 font-mono text-xs text-zinc-800 dark:text-zinc-200 whitespace-pre leading-relaxed bg-zinc-50 dark:bg-zinc-950/80 p-3 rounded-xl border border-zinc-200/50 dark:border-white/5\">\n        {displayedText}\n        {!isDone && (\n          <motion.span\n            animate={{ opacity: [1, 0, 1] }}\n            transition={{ repeat: Infinity, duration: 0.6 }}\n            className=\"inline-block w-2 h-4 bg-indigo-500 ml-0.5 align-middle\"\n          />\n        )}\n      </div>\n    </div>\n  );\n};\n"
    }
  ]
}