{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "object-inspector",
  "title": "Object Inspector",
  "description": "Right-dock detail header — kind chip, status dot, title/subtitle, with property-section slots.",
  "dependencies": [
    "@vllnt/ui@^0.3.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/object-inspector/object-inspector.tsx",
      "content": "\"use client\";\n\nimport type { ComponentPropsWithoutRef, ReactNode } 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 = ({\n  ref,\n  ...props\n}: ObjectInspectorProps & { ref?: React.Ref<HTMLElement> }) => {\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};\nObjectInspector.displayName = \"ObjectInspector\";\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component",
  "version": "0.3.0",
  "stability": "stable"
}
