{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "flame-profile",
  "type": "registry:component",
  "title": "Flame Profile",
  "description": "An agent run as a flame graph, one stacked frame per call and as wide as it took; switch the lens to tokens or cost and the frames spring to their new sizes, click any frame to zoom in, and the slowest one is flagged for you.",
  "categories": [
    "component",
    "Mission Control"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "utils",
    "https://coss.com/ui/r/segmented-control.json"
  ],
  "files": [
    {
      "path": "registry/devl/flame-profile.tsx",
      "type": "registry:component",
      "content": "\"use client\";\n\nimport { ChevronRightIcon, FlameIcon } from \"lucide-react\";\nimport { AnimatePresence, motion, useReducedMotion } from \"motion/react\";\nimport { type KeyboardEvent, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { SegmentedControl, SegmentedControlItem } from \"@/components/ui/segmented-control\";\nimport { cn } from \"@/lib/utils\";\n\nexport type FrameKind = \"agent\" | \"llm\" | \"tool\";\nexport type FlameLens = \"time\" | \"tokens\" | \"cost\";\n\nexport interface FlameFrame {\n  id: string;\n  name: string;\n  kind: FrameKind;\n  ms: number;\n  tokens?: number;\n  cost?: number;\n  detail?: string;\n  children?: FlameFrame[];\n}\n\nexport interface FlameProfileProps {\n  root: FlameFrame;\n  title?: string;\n  defaultLens?: FlameLens;\n  currency?: string;\n  className?: string;\n}\n\ninterface Placed {\n  frame: FlameFrame;\n  depth: number;\n  x0: number;\n  x1: number;\n  path: FlameFrame[];\n}\n\nconst ROW = 28;\nconst GAP = 2;\nconst spring = { type: \"spring\", stiffness: 300, damping: 34, mass: 0.9 } as const;\n\nconst kinds: Record<FrameKind, { label: string; frame: string; dot: string }> = {\n  agent: {\n    label: \"Agent\",\n    frame: \"bg-emerald-500/14 text-emerald-900 hover:bg-emerald-500/24 dark:bg-emerald-400/14 dark:text-emerald-100 dark:hover:bg-emerald-400/24\",\n    dot: \"bg-emerald-500 dark:bg-emerald-400\",\n  },\n  llm: {\n    label: \"Model call\",\n    frame: \"bg-violet-500/16 text-violet-900 hover:bg-violet-500/26 dark:bg-violet-400/18 dark:text-violet-100 dark:hover:bg-violet-400/28\",\n    dot: \"bg-violet-500 dark:bg-violet-400\",\n  },\n  tool: {\n    label: \"Tool\",\n    frame: \"bg-sky-500/14 text-sky-900 hover:bg-sky-500/24 dark:bg-sky-400/14 dark:text-sky-100 dark:hover:bg-sky-400/24\",\n    dot: \"bg-sky-500 dark:bg-sky-400\",\n  },\n};\n\nconst lenses: { id: FlameLens; label: string }[] = [\n  { id: \"time\", label: \"Time\" },\n  { id: \"tokens\", label: \"Tokens\" },\n  { id: \"cost\", label: \"Cost\" },\n];\n\nfunction totals(f: FlameFrame, memo: Map<string, { tokens: number; cost: number }>) {\n  let tokens = f.tokens ?? 0;\n  let cost = f.cost ?? 0;\n  for (const c of f.children ?? []) {\n    const t = totals(c, memo);\n    tokens += t.tokens;\n    cost += t.cost;\n  }\n  const out = { tokens, cost };\n  memo.set(f.id, out);\n  return out;\n}\n\nconst fmtMs = (ms: number) => (ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(ms < 10_000 ? 2 : 1)}s`);\nconst fmtTokens = (n: number) => (n >= 1000 ? `${(n / 1000).toFixed(n >= 10_000 ? 0 : 1)}k` : `${Math.round(n)}`);\nconst fmtCost = (n: number, cur: string) => `${cur}${n < 0.1 ? n.toFixed(3) : n.toFixed(2)}`;\n\nexport function FlameProfile({ root, title = \"Agent run\", defaultLens = \"time\", currency = \"$\", className }: FlameProfileProps) {\n  const reduce = useReducedMotion();\n  const [lens, setLens] = useState<FlameLens>(defaultLens);\n  const [zoomId, setZoomId] = useState(root.id);\n  const [hover, setHover] = useState<string | null>(null);\n  const [tipOn, setTipOn] = useState(false);\n  const [width, setWidth] = useState(520);\n  const box = useRef<HTMLDivElement>(null);\n  const tipTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n  const warm = useRef(0);\n\n  useLayoutEffect(() => {\n    const el = box.current;\n    if (!el) return;\n    const ro = new ResizeObserver(() => setWidth(el.clientWidth));\n    ro.observe(el);\n    setWidth(el.clientWidth);\n    return () => ro.disconnect();\n  }, []);\n  useEffect(() => () => clearTimeout(tipTimer.current), []);\n\n  const sums = useMemo(() => {\n    const memo = new Map<string, { tokens: number; cost: number }>();\n    totals(root, memo);\n    return memo;\n  }, [root]);\n\n  const metric = (f: FlameFrame, l: FlameLens = lens) =>\n    l === \"time\" ? f.ms : l === \"tokens\" ? (sums.get(f.id)?.tokens ?? 0) : (sums.get(f.id)?.cost ?? 0);\n\n  const placed = useMemo(() => {\n    const out: Placed[] = [];\n    const place = (f: FlameFrame, depth: number, x0: number, x1: number, path: FlameFrame[]) => {\n      out.push({ frame: f, depth, x0, x1, path });\n      const kids = f.children ?? [];\n      const sum = kids.reduce((s, c) => s + metric(c), 0);\n      const scale = Math.max(metric(f), sum) || 1;\n      let x = x0;\n      for (const c of kids) {\n        const w = ((x1 - x0) * metric(c)) / scale;\n        place(c, depth + 1, x, x + w, [...path, f]);\n        x += w;\n      }\n    };\n    place(root, 0, 0, 1, []);\n    return out;\n  }, [root, lens, sums]);\n\n  const zoom = placed.find((p) => p.frame.id === zoomId) ?? placed[0];\n  const span = zoom.x1 - zoom.x0 || 1;\n  const view = (p: Placed) => {\n    const a = Math.min(Math.max((p.x0 - zoom.x0) / span, 0), 1);\n    const b = Math.min(Math.max((p.x1 - zoom.x0) / span, 0), 1);\n    const inside = p.depth >= zoom.depth && (p.frame.id === zoom.frame.id || p.path.some((f) => f.id === zoom.frame.id));\n    return { a, b, d: p.depth - zoom.depth, visible: inside && b - a > 0.0005 };\n  };\n  const rows = Math.max(...placed.filter((p) => view(p).visible).map((p) => p.depth - zoom.depth)) + 1;\n  const maxRows = Math.max(...placed.map((p) => p.depth)) + 1;\n\n  const leaves = placed.filter((p) => !p.frame.children?.length && view(p).visible);\n  const hottest = leaves.reduce<Placed | null>((best, p) => (!best || metric(p.frame) > metric(best.frame) ? p : best), null);\n  const hotShare = hottest ? metric(hottest.frame) / (metric(zoom.frame) || 1) : 0;\n\n  const fmt = (n: number, l: FlameLens = lens) => (l === \"time\" ? fmtMs(n) : l === \"tokens\" ? fmtTokens(n) : fmtCost(n, currency));\n  const zoomTotal = metric(zoom.frame);\n  const ticks = [0, 0.25, 0.5, 0.75, 1];\n\n  const showTip = (id: string) => {\n    clearTimeout(tipTimer.current);\n    setHover(id);\n    if (tipOn || performance.now() - warm.current < 500) setTipOn(true);\n    else tipTimer.current = setTimeout(() => setTipOn(true), 260);\n  };\n  const hideTip = () => {\n    clearTimeout(tipTimer.current);\n    if (tipOn) warm.current = performance.now();\n    setTipOn(false);\n    setHover(null);\n  };\n\n  const zoomTo = (id: string) => {\n    setZoomId(id);\n    hideTip();\n  };\n  const onKeyDown = (e: KeyboardEvent) => {\n    if (e.key === \"Escape\" && zoom.path.length) {\n      e.preventDefault();\n      zoomTo(zoom.path[zoom.path.length - 1].id);\n    }\n  };\n\n  const hovered = hover ? placed.find((p) => p.frame.id === hover) : undefined;\n  const hv = hovered ? view(hovered) : null;\n  const tipX = hv ? Math.min(Math.max(((hv.a + hv.b) / 2) * width, 112), width - 112) : 0;\n\n  return (\n    <div\n      className={cn(\"flex w-[560px] max-w-full flex-col gap-4 rounded-2xl border bg-card p-4 text-card-foreground shadow-xs/5\", className)}\n      onKeyDown={onKeyDown}\n    >\n      <div className=\"flex flex-wrap items-start justify-between gap-3\">\n        <div className=\"flex min-w-0 flex-col gap-0.5\">\n          <span className=\"truncate font-medium text-sm\">{title}</span>\n          <span className=\"text-muted-foreground text-xs tabular-nums\">\n            {fmtMs(root.ms)} · {fmtTokens(sums.get(root.id)?.tokens ?? 0)} tokens · {fmtCost(sums.get(root.id)?.cost ?? 0, currency)}\n          </span>\n        </div>\n        <SegmentedControl aria-label=\"Size frames by\" size=\"sm\">\n          {lenses.map((l) => (\n            <SegmentedControlItem\n              aria-pressed={lens === l.id}\n              className=\"text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n              data-pressed={lens === l.id ? \"\" : undefined}\n              key={l.id}\n              onClick={() => setLens(l.id)}\n            >\n              {l.label}\n            </SegmentedControlItem>\n          ))}\n        </SegmentedControl>\n      </div>\n\n      <nav aria-label=\"Zoomed frame\" className=\"-my-1 flex h-7 min-w-0 items-center gap-0.5 text-xs\">\n        {[...zoom.path, zoom.frame].map((f, i, all) => {\n          const last = i === all.length - 1;\n          return (\n            <span className={cn(\"flex items-center gap-0.5\", last ? \"min-w-0\" : \"shrink-0\")} key={f.id}>\n              {i > 0 && <ChevronRightIcon aria-hidden className=\"size-3 shrink-0 text-muted-foreground/60\" />}\n              {last ? (\n                <span aria-current=\"location\" className=\"truncate px-1.5 font-medium\">\n                  {f.name}\n                </span>\n              ) : (\n                <button\n                  className=\"max-w-28 truncate rounded-md px-1.5 py-1 text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring\"\n                  onClick={() => zoomTo(f.id)}\n                  type=\"button\"\n                >\n                  {f.name}\n                </button>\n              )}\n            </span>\n          );\n        })}\n        <span className=\"ml-auto shrink-0 pl-2 text-muted-foreground tabular-nums\">\n          {zoom.path.length ? \"Esc to zoom out\" : \"Click a frame to zoom\"}\n        </span>\n      </nav>\n\n      <div className=\"relative\" onPointerLeave={hideTip} ref={box}>\n        <motion.div\n          animate={{ height: rows * (ROW + GAP) - GAP }}\n          className=\"relative overflow-hidden\"\n          initial={false}\n          style={{ minHeight: ROW }}\n          transition={reduce ? { duration: 0 } : spring}\n        >\n          {placed.map((p) => {\n            const v = view(p);\n            const px = (v.b - v.a) * width;\n            const hot = hottest?.frame.id === p.frame.id;\n            const isZoom = p.frame.id === zoom.frame.id && zoom.path.length > 0;\n            return (\n              <motion.button\n                animate={{\n                  left: `${v.a * 100}%`,\n                  width: `${(v.b - v.a) * 100}%`,\n                  y: Math.max(v.d, 0) * (ROW + GAP),\n                  opacity: v.visible ? 1 : 0,\n                }}\n                aria-label={`${p.frame.name}, ${fmtMs(p.frame.ms)}, ${fmtTokens(metric(p.frame, \"tokens\"))} tokens, ${fmtCost(metric(p.frame, \"cost\"), currency)}`}\n                className=\"group absolute top-0 left-0 px-px outline-none\"\n                initial={false}\n                key={p.frame.id}\n                onBlur={hideTip}\n                onClick={() => zoomTo(isZoom ? (zoom.path[zoom.path.length - 1]?.id ?? root.id) : p.frame.id)}\n                onFocus={() => showTip(p.frame.id)}\n                onPointerEnter={() => showTip(p.frame.id)}\n                style={{ height: ROW, pointerEvents: v.visible ? \"auto\" : \"none\" }}\n                tabIndex={v.visible ? 0 : -1}\n                transition={reduce ? { duration: 0 } : spring}\n                type=\"button\"\n              >\n                <span\n                  className={cn(\n                    \"flex h-full items-center gap-1 overflow-hidden rounded-md px-2 text-left font-medium text-xs transition-[background-color,box-shadow] duration-150 group-focus-visible:ring-2 group-focus-visible:ring-ring group-focus-visible:ring-inset\",\n                    kinds[p.frame.kind].frame,\n                    hot && \"ring-1 ring-orange-500/70 ring-inset dark:ring-orange-400/70\",\n                    hover && hover !== p.frame.id && \"opacity-80\",\n                  )}\n                >\n                  {hot && px > 28 && <FlameIcon aria-hidden className=\"size-3 shrink-0 text-orange-600 dark:text-orange-400\" />}\n                  {px > 52 && <span className=\"truncate\">{p.frame.name}</span>}\n                  {px > 150 && (\n                    <span className=\"ml-auto shrink-0 pl-2 font-normal tabular-nums opacity-80\">{fmt(metric(p.frame))}</span>\n                  )}\n                </span>\n              </motion.button>\n            );\n          })}\n        </motion.div>\n\n        <div aria-hidden className=\"relative mt-2 h-4 border-t text-[11px] text-muted-foreground tabular-nums\">\n          {ticks.map((t) => (\n            <span\n              className={cn(\n                \"absolute top-1\",\n                t === 0 ? \"left-0\" : t === 1 ? \"right-0\" : \"-translate-x-1/2\",\n                \"before:absolute before:-top-1 before:h-1 before:w-px before:bg-border\",\n                t === 0 ? \"before:left-0\" : t === 1 ? \"before:right-0\" : \"before:left-1/2\",\n              )}\n              key={t}\n              style={t > 0 && t < 1 ? { left: `${t * 100}%` } : undefined}\n            >\n              {fmt(zoomTotal * t)}\n            </span>\n          ))}\n        </div>\n\n        <AnimatePresence>\n          {tipOn && hovered && hv?.visible && (\n            <motion.div\n              animate={{ opacity: 1 }}\n              className=\"pointer-events-none absolute z-10 w-56 -translate-x-1/2 -translate-y-full rounded-xl border bg-popover p-3 text-popover-foreground shadow-lg/5\"\n              exit={{ opacity: 0, transition: { duration: 0.1 } }}\n              initial={{ opacity: 0 }}\n              role=\"tooltip\"\n              style={{ left: tipX, top: hv.d * (ROW + GAP) - 6 }}\n              transition={{ duration: 0.12, ease: \"easeOut\" }}\n            >\n              <div className=\"flex items-center gap-1.5\">\n                <span className={cn(\"size-2 shrink-0 rounded-full\", kinds[hovered.frame.kind].dot)} />\n                <span className=\"truncate font-medium text-sm\">{hovered.frame.name}</span>\n              </div>\n              <div className=\"mt-0.5 truncate text-muted-foreground text-xs\">\n                {kinds[hovered.frame.kind].label}\n                {hovered.frame.detail ? ` · ${hovered.frame.detail}` : \"\"}\n              </div>\n              <dl className=\"mt-2.5 grid grid-cols-3 gap-2 border-t pt-2.5 text-xs\">\n                {lenses.map((l) => (\n                  <div className=\"flex flex-col gap-0.5\" key={l.id}>\n                    <dt className={cn(\"text-muted-foreground\", l.id === lens && \"text-foreground\")}>{l.label}</dt>\n                    <dd className=\"font-medium tabular-nums\">{fmt(metric(hovered.frame, l.id), l.id)}</dd>\n                  </div>\n                ))}\n              </dl>\n              <div className=\"mt-2 text-muted-foreground text-xs tabular-nums\">\n                {Math.round((metric(hovered.frame) / (metric(root) || 1)) * 100)}% of the run’s {lens === \"time\" ? \"time\" : lens}\n              </div>\n            </motion.div>\n          )}\n        </AnimatePresence>\n      </div>\n\n      <div className=\"flex flex-wrap items-center justify-between gap-x-4 gap-y-2 border-t pt-3 text-xs\">\n        <ul className=\"flex items-center gap-3 text-muted-foreground\">\n          {(Object.keys(kinds) as FrameKind[]).map((k) => (\n            <li className=\"flex items-center gap-1.5\" key={k}>\n              <span className={cn(\"size-2 rounded-[calc(var(--radius)*0.3)]\", kinds[k].dot)} />\n              {kinds[k].label}\n            </li>\n          ))}\n        </ul>\n        {hottest && (\n          <button\n            className=\"-mx-1.5 flex min-w-0 items-center gap-1.5 rounded-md px-1.5 py-1 outline-none transition-colors hover:bg-accent focus-visible:ring-2 focus-visible:ring-ring\"\n            onClick={() => zoomTo(hottest.path[hottest.path.length - 1]?.id ?? hottest.frame.id)}\n            type=\"button\"\n          >\n            <FlameIcon aria-hidden className=\"size-3.5 shrink-0 text-orange-600 dark:text-orange-400\" />\n            <span className=\"text-muted-foreground\">{lens === \"time\" ? \"Slowest\" : lens === \"tokens\" ? \"Hungriest\" : \"Priciest\"}</span>\n            <span className=\"truncate font-medium\">{hottest.frame.name}</span>\n            <span className=\"shrink-0 text-muted-foreground tabular-nums\">\n              {fmt(metric(hottest.frame))} · {Math.round(hotShare * 100)}%\n            </span>\n          </button>\n        )}\n      </div>\n      <span className=\"sr-only\" aria-live=\"polite\">\n        {`Sized by ${lens}. Showing ${zoom.frame.name}, ${fmt(zoomTotal)}. ${maxRows} levels deep.`}\n      </span>\n    </div>\n  );\n}\n"
    }
  ]
}