{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "activity-log",
  "title": "Activity log",
  "description": "A docket of what an agent did: thoughts, actions, questions, responses and errors, each timed. Questions waiting on you are highlighted.",
  "dependencies": [
    "cn"
  ],
  "registryDependencies": [
    "https://bevel-ui.vercel.app/r/bevel.json"
  ],
  "files": [
    {
      "path": "registry/bevel/ui/activity-log.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"cn\"\n\n/** A docket of what an agent did. Give it an aria-label. */\nfunction ActivityLog({ className, ...props }: React.ComponentProps<\"section\">) {\n  return (\n    <section\n      data-slot=\"activity-log\"\n      className={cn(\"bevel-paper flex w-full flex-col rounded-(--bevel-radius-xs) text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ActivityLogTitle({ className, ...props }: React.ComponentProps<\"h3\">) {\n  return (\n    <h3\n      data-slot=\"activity-log-title\"\n      className={cn(\n        \"border-b border-(--bevel-paper-rule) px-4 py-3 text-(length:--bevel-label) font-semibold tracking-(--bevel-tracking-label) uppercase\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst LogContext = React.createContext<{ mountedRef: React.RefObject<boolean> }>({\n  mountedRef: { current: false },\n})\n\ntype ActivityLogEntriesProps = React.ComponentProps<\"div\"> & {\n  /** Keep the newest entry in view, but only if the reader was already at the bottom. */\n  stickToBottom?: boolean\n}\n\n/**\n * The entries, oldest first. A live log: screen readers hear new entries\n * politely. Scrolls once it's taller than --activity-log-height.\n */\nfunction ActivityLogEntries({ className, stickToBottom = true, children, ...props }: ActivityLogEntriesProps) {\n  const ref = React.useRef<HTMLDivElement>(null)\n  const atBottom = React.useRef(true)\n  const mountedRef = React.useRef(false)\n  const count = React.Children.count(children)\n\n  React.useEffect(() => {\n    mountedRef.current = true\n  }, [])\n\n  React.useLayoutEffect(() => {\n    const el = ref.current\n    if (el && stickToBottom && atBottom.current) el.scrollTop = el.scrollHeight\n  }, [count, stickToBottom])\n\n  const context = React.useMemo(() => ({ mountedRef }), [])\n\n  return (\n    <LogContext value={context}>\n      <div\n        ref={ref}\n        role=\"log\"\n        tabIndex={0}\n        data-slot=\"activity-log-entries\"\n        onScroll={(event) => {\n          const el = event.currentTarget\n          atBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < 8\n        }}\n        className={cn(\n          \"max-h-(--activity-log-height) overflow-y-auto overscroll-contain rounded-b-(--bevel-radius-xs) outline-none focus-visible:ring-2 focus-visible:ring-(--bevel-pen-blue)/40\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </div>\n    </LogContext>\n  )\n}\n\ntype ActivityLogKind = \"thought\" | \"action\" | \"question\" | \"response\" | \"error\"\n\nconst kindText: Record<ActivityLogKind, string> = {\n  thought: \"Thought\",\n  action: \"Action\",\n  question: \"Question\",\n  response: \"Response\",\n  error: \"Error\",\n}\n\ntype ActivityLogEntryProps = React.ComponentProps<\"div\"> & {\n  kind?: ActivityLogKind\n  /** When it happened, as shown. Pass a dateTime for machines. */\n  time?: React.ReactNode\n  dateTime?: string\n}\n\n/**\n * One entry: when, what kind, and what. Questions waiting on a person are\n * highlighted. Entries added after the log renders print in.\n */\nfunction ActivityLogEntry({\n  className,\n  kind = \"action\",\n  time,\n  dateTime,\n  children,\n  ...props\n}: ActivityLogEntryProps) {\n  const { mountedRef } = React.useContext(LogContext)\n  const [prints] = React.useState(() => mountedRef.current)\n  return (\n    <div\n      data-slot=\"activity-log-entry\"\n      data-kind={kind}\n      data-enter={prints ? \"\" : undefined}\n      className={cn(\n        \"grid grid-cols-[var(--activity-log-time)_var(--activity-log-kind)_minmax(0,1fr)] items-baseline gap-x-2 border-b border-(--bevel-paper-rule) px-4 py-2.5 last:border-b-0\",\n        \"data-[kind=question]:bg-(--activity-log-question)\",\n        \"transition-[translate,opacity] duration-(--bevel-duration-move) ease-(--bevel-ease-out) motion-reduce:transition-none\",\n        \"data-enter:starting:-translate-y-(--activity-log-print-in) data-enter:starting:opacity-0\",\n        className\n      )}\n      {...props}\n    >\n      <time\n        dateTime={dateTime}\n        className=\"font-mono text-(length:--bevel-fine) text-(--bevel-paper-muted) tabular-nums\"\n      >\n        {time}\n      </time>\n      <span className=\"text-(length:--bevel-fine) font-bold tracking-(--bevel-tracking-print) text-(--activity-log-ink) uppercase\">\n        {kindText[kind]}\n      </span>\n      <div\n        className={cn(\n          \"flex min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1 text-(--bevel-paper-foreground)\",\n          kind === \"thought\" && \"text-(--bevel-pencil) italic\"\n        )}\n      >\n        {children}\n      </div>\n    </div>\n  )\n}\n\nexport { ActivityLog, ActivityLogTitle, ActivityLogEntries, ActivityLogEntry }\nexport type { ActivityLogKind, ActivityLogEntryProps }\n",
      "type": "registry:ui"
    }
  ],
  "css": {
    ":root": {
      "--activity-log-height": "22rem",
      "--activity-log-time": "3.25rem",
      "--activity-log-kind": "5.5rem",
      "--activity-log-print-in": "0.5em",
      "--activity-log-question": "oklch(0.93 0.1 95 / 0.55)"
    },
    "[data-slot=\"activity-log-entry\"]": {
      "--activity-log-ink": "var(--bevel-paper-foreground)"
    },
    "[data-slot=\"activity-log-entry\"][data-kind=\"thought\"]": {
      "--activity-log-ink": "var(--bevel-pencil)"
    },
    "[data-slot=\"activity-log-entry\"][data-kind=\"action\"]": {
      "--activity-log-ink": "var(--bevel-pen-blue)"
    },
    "[data-slot=\"activity-log-entry\"][data-kind=\"question\"]": {
      "--activity-log-ink": "var(--bevel-ink-amber)"
    },
    "[data-slot=\"activity-log-entry\"][data-kind=\"error\"]": {
      "--activity-log-ink": "var(--bevel-pen-red)"
    }
  },
  "categories": [
    "agents"
  ],
  "type": "registry:ui"
}