{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "context-meter",
  "title": "Context Meter",
  "description": "How full the context window is, with tokens and cost on hover.",
  "dependencies": [],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/hover-card.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/context-meter.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { HoverCard, HoverCardContent, HoverCardTrigger } from \"@/registry/cuelark/ui/hover-card\";\nimport { cn } from \"@/lib/utils\";\n\ntype ContextMeterProps = {\n  /** Tokens used so far. */\n  used: number;\n  /** The model's context window. */\n  max: number;\n  /** Optional breakdown shown on hover. */\n  breakdown?: { input?: number; output?: number; cached?: number; reasoning?: number };\n  /** Spend so far, in dollars. */\n  cost?: number;\n  className?: string;\n};\n\nconst fmt = (n: number) => (n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n));\n\n/**\n * How full the model's context window is, as a small ring that warms from ink to amber to red as it fills.\n * Hover for the token breakdown and cost, the things you check before a long conversation degrades.\n */\nfunction ContextMeter({ used, max, breakdown, cost, className }: ContextMeterProps) {\n  const pct = Math.min(1, used / max);\n  const r = 7;\n  const c = 2 * Math.PI * r;\n  const color = pct > 0.9 ? \"var(--destructive)\" : pct > 0.7 ? \"var(--warning)\" : \"var(--foreground)\";\n  return (\n    <HoverCard openDelay={150}>\n      <HoverCardTrigger asChild>\n        <button\n          type=\"button\"\n          data-slot=\"context-meter\"\n          aria-label={`Context ${Math.round(pct * 100)}% used`}\n          className={cn(\"flex h-8 items-center gap-1.5 rounded-lg px-2 font-mono text-xs text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50\", className)}\n        >\n          <svg viewBox=\"0 0 18 18\" className=\"size-4 -rotate-90\" aria-hidden=\"true\">\n            <circle cx=\"9\" cy=\"9\" r={r} fill=\"none\" stroke=\"currentColor\" strokeOpacity=\"0.2\" strokeWidth=\"2\" />\n            <circle cx=\"9\" cy=\"9\" r={r} fill=\"none\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" strokeDasharray={c} strokeDashoffset={c * (1 - pct)} className=\"transition-[stroke-dashoffset,stroke] duration-500 ease-cue\" />\n          </svg>\n          {Math.round(pct * 100)}%\n        </button>\n      </HoverCardTrigger>\n      <HoverCardContent align=\"end\" className=\"grid w-64 gap-3 p-4\">\n        <div className=\"flex items-baseline justify-between\">\n          <span className=\"cue-label\">Context window</span>\n          <span className=\"font-mono text-xs\">\n            {fmt(used)} / {fmt(max)}\n          </span>\n        </div>\n        <div className=\"h-1.5 overflow-hidden rounded-full bg-muted\">\n          <div className=\"h-full rounded-full transition-[width] duration-500 ease-cue\" style={{ width: `${pct * 100}%`, background: color }} />\n        </div>\n        {breakdown && (\n          <dl className=\"grid grid-cols-2 gap-x-4 gap-y-1.5 text-xs\">\n            {Object.entries(breakdown).map(([k, v]) =>\n              v == null ? null : (\n                <React.Fragment key={k}>\n                  <dt className=\"text-muted-foreground capitalize\">{k}</dt>\n                  <dd className=\"text-right font-mono\">{fmt(v)}</dd>\n                </React.Fragment>\n              ),\n            )}\n          </dl>\n        )}\n        {cost != null && (\n          <div className=\"flex justify-between border-t border-border pt-2 text-xs\">\n            <span className=\"text-muted-foreground\">Cost</span>\n            <span className=\"font-mono\">${cost.toFixed(cost < 0.01 ? 4 : 2)}</span>\n          </div>\n        )}\n      </HoverCardContent>\n    </HoverCard>\n  );\n}\n\nexport { ContextMeter };\nexport type { ContextMeterProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/context-meter",
  "categories": [
    "agents"
  ],
  "type": "registry:ui"
}