{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "object-inspector",
  "type": "registry:component",
  "title": "Object Inspector",
  "description": "Right-dock detail header — kind chip, status dot, title/subtitle, with property-section slots.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/object-inspector/object-inspector.tsx",
      "content": "\"use client\";\n\nimport {\n  type ComponentPropsWithoutRef,\n  forwardRef,\n  type ReactNode,\n} from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\n\n/**\n * Object kind — drives the chip glyph + label.\n *\n * @public\n */\nexport type ObjectInspectorKind =\n  | \"agent\"\n  | \"artifact\"\n  | \"input\"\n  | \"output\"\n  | \"run\"\n  | \"task\";\n\nconst KIND_LABEL: Record<ObjectInspectorKind, string> = {\n  agent: \"Agent\",\n  artifact: \"Artifact\",\n  input: \"Input\",\n  output: \"Output\",\n  run: \"Run\",\n  task: \"Task\",\n};\n\nconst KIND_GLYPH: Record<ObjectInspectorKind, string> = {\n  agent: \"◇\",\n  artifact: \"◌\",\n  input: \"↘\",\n  output: \"↗\",\n  run: \"▶\",\n  task: \"▢\",\n};\n\n/**\n * Live status — drives the colored dot.\n *\n * @public\n */\nexport type ObjectInspectorStatus =\n  | \"complete\"\n  | \"failed\"\n  | \"idle\"\n  | \"queued\"\n  | \"running\";\n\nconst STATUS_DOT: Record<ObjectInspectorStatus, string> = {\n  complete: \"bg-emerald-500\",\n  failed: \"bg-red-500\",\n  idle: \"bg-muted-foreground\",\n  queued: \"bg-amber-500\",\n  running: \"bg-blue-500 animate-pulse\",\n};\n\nconst STATUS_LABEL: Record<ObjectInspectorStatus, string> = {\n  complete: \"Complete\",\n  failed: \"Failed\",\n  idle: \"Idle\",\n  queued: \"Queued\",\n  running: \"Running\",\n};\n\n/**\n * Localizable strings.\n *\n * @public\n */\nexport type ObjectInspectorLabels = {\n  /** Empty-state copy. Defaults to `\"No selection\"`. */\n  empty?: string;\n  /** Aria-label for the inspector. Defaults to `\"Object inspector\"`. */\n  region?: string;\n};\n\nconst DEFAULT_LABELS = {\n  empty: \"No selection\",\n  region: \"Object inspector\",\n} as const satisfies Required<ObjectInspectorLabels>;\n\n/**\n * Props for {@link ObjectInspector}.\n *\n * @public\n */\nexport type ObjectInspectorProps = {\n  /** Object kind. When omitted, the inspector renders the empty state. */\n  kind?: ObjectInspectorKind;\n  /** Localizable strings. */\n  labels?: ObjectInspectorLabels;\n  /** Object status. Defaults to `\"idle\"`. */\n  status?: ObjectInspectorStatus;\n  /** Optional subtitle (id, owner, model). */\n  subtitle?: ReactNode;\n  /** Object title. */\n  title?: ReactNode;\n} & ComponentPropsWithoutRef<\"section\">;\n\nconst KindChip = (props: { kind: ObjectInspectorKind }): React.ReactElement => (\n  <span\n    aria-label={KIND_LABEL[props.kind]}\n    className=\"inline-flex items-center gap-1 rounded-full border border-border bg-background px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n  >\n    <span aria-hidden=\"true\">{KIND_GLYPH[props.kind]}</span>\n    {KIND_LABEL[props.kind]}\n  </span>\n);\n\nconst StatusDot = (props: {\n  status: ObjectInspectorStatus;\n}): React.ReactElement => (\n  <span\n    aria-label={`Status ${STATUS_LABEL[props.status]}`}\n    className=\"inline-flex items-center gap-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground\"\n  >\n    <span\n      aria-hidden=\"true\"\n      className={cn(\"size-1.5 rounded-full\", STATUS_DOT[props.status])}\n    />\n    {STATUS_LABEL[props.status]}\n  </span>\n);\n\nconst Header = (props: {\n  kind: ObjectInspectorKind;\n  status: ObjectInspectorStatus;\n  subtitle?: ReactNode;\n  title: ReactNode;\n}): React.ReactElement => (\n  <header className=\"flex flex-col gap-2\">\n    <div className=\"flex items-center justify-between gap-2\">\n      <KindChip kind={props.kind} />\n      <StatusDot status={props.status} />\n    </div>\n    <div className=\"space-y-0.5\">\n      <h3 className=\"truncate text-sm font-semibold text-foreground\">\n        {props.title}\n      </h3>\n      {props.subtitle ? (\n        <p className=\"truncate text-xs text-muted-foreground\">\n          {props.subtitle}\n        </p>\n      ) : null}\n    </div>\n  </header>\n);\n\n/**\n * Inspector header for the right dock. Renders kind chip + status dot\n * + title + subtitle, then any children below (typically a stack of\n * {@link \"../property-section/property-section\".PropertySection} blocks). Pure presentation; the host\n * derives props from the current selection and slots the property\n * sections.\n *\n * @example\n * ```tsx\n * <ObjectInspector\n *   kind=\"run\"\n *   status=\"running\"\n *   title=\"research-2025-04-15\"\n *   subtitle=\"claude-3.7\"\n * >\n *   <PropertySection title=\"Layout\" entries={…} />\n *   <PropertySection title=\"State\" entries={…} />\n * </ObjectInspector>\n * ```\n *\n * @public\n */\nexport const ObjectInspector = forwardRef<HTMLElement, ObjectInspectorProps>(\n  (props, ref) => {\n    const {\n      children,\n      className,\n      kind,\n      labels,\n      status = \"idle\",\n      subtitle,\n      title,\n      ...rest\n    } = props;\n    const resolvedLabels = { ...DEFAULT_LABELS, ...labels };\n    if (!kind || !title) {\n      return (\n        <section\n          aria-label={resolvedLabels.region}\n          className={cn(\n            \"flex w-full flex-col items-center justify-center gap-1 rounded-2xl border bg-background p-6 text-center text-xs text-muted-foreground\",\n            className,\n          )}\n          data-object-inspector\n          data-object-state=\"empty\"\n          ref={ref}\n          {...rest}\n        >\n          <span aria-hidden=\"true\" className=\"text-lg\">\n            ◇\n          </span>\n          <span>{resolvedLabels.empty}</span>\n        </section>\n      );\n    }\n    return (\n      <section\n        aria-label={resolvedLabels.region}\n        className={cn(\n          \"flex w-full flex-col gap-3 rounded-2xl border bg-background p-3 text-foreground\",\n          className,\n        )}\n        data-object-inspector\n        data-object-kind={kind}\n        data-object-status={status}\n        ref={ref}\n        {...rest}\n      >\n        <Header kind={kind} status={status} subtitle={subtitle} title={title} />\n        {children ? <div className=\"space-y-2\">{children}</div> : null}\n      </section>\n    );\n  },\n);\nObjectInspector.displayName = \"ObjectInspector\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
