{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "run-summary",
  "title": "Run Summary",
  "description": "A summary of completed agent work with stats, changed artifacts, warnings, and next actions.",
  "dependencies": [
    "class-variance-authority",
    "lucide-react"
  ],
  "registryDependencies": [
    "button",
    "https://uaiblocks.dev/r/uai-theme.json",
    "https://uaiblocks.dev/r/uai-utils.json"
  ],
  "files": [
    {
      "path": "src/registry/uai/components/run-summary.tsx",
      "content": "\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport {\n  ArrowRight,\n  CircleAlert,\n  CircleCheck,\n  type LucideIcon,\n  Minus,\n  PencilLine,\n  Plus,\n  TriangleAlert,\n} from \"lucide-react\";\nimport { type ComponentProps, createContext, type ReactNode, useContext, useId } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/uai-utils\";\n\nexport const RUN_SUMMARY_VARIANTS = [\"card\", \"plain\", \"compact\"] as const;\nexport const RUN_SUMMARY_OUTCOMES = [\"success\", \"partial\", \"failed\"] as const;\nexport type RunSummaryVariant = (typeof RUN_SUMMARY_VARIANTS)[number];\nexport type RunSummaryOutcome = (typeof RUN_SUMMARY_OUTCOMES)[number];\nexport type RunSummaryProps = ComponentProps<\"section\"> & {\n  variant?: RunSummaryVariant;\n  outcome?: RunSummaryOutcome;\n};\n\ntype RunSummaryContextValue = {\n  id: string;\n  variant: RunSummaryVariant;\n  outcome: RunSummaryOutcome;\n};\n\nconst RunSummaryContext = createContext<RunSummaryContextValue | null>(null);\n\nfunction useRunSummary(part: string) {\n  const context = useContext(RunSummaryContext);\n  if (!context) throw new Error(`${part} must be used within RunSummary`);\n  return context;\n}\n\nconst dangerText = \"text-destructive-ink\";\nconst outcomeDetails: Record<\n  RunSummaryOutcome,\n  { label: string; icon: LucideIcon; className: string }\n> = {\n  success: { label: \"Completed\", icon: CircleCheck, className: \"bg-success/14 text-success-ink\" },\n  partial: {\n    label: \"Completed with warnings\",\n    icon: TriangleAlert,\n    className: \"bg-warning/14 text-warning-ink\",\n  },\n  failed: { label: \"Failed\", icon: CircleAlert, className: cn(\"bg-destructive/14\", dangerText) },\n};\n\nconst runSummaryVariants = cva(\n  [\n    \"grid min-w-0 text-[13px]/[18px] text-foreground\",\n    \"*:animate-in *:fade-in-0 *:slide-in-from-bottom-1 *:duration-240 *:ease-out-quint *:fill-mode-backwards *:motion-reduce:animate-none\",\n    \"*:nth-2:[animation-delay:40ms] *:nth-3:[animation-delay:80ms] *:nth-4:[animation-delay:120ms] *:nth-5:[animation-delay:160ms] *:nth-[n+6]:[animation-delay:200ms]\",\n  ],\n  {\n    variants: {\n      variant: {\n        card: \"gap-4.5 rounded-[14px] border bg-card p-4\",\n        plain: \"gap-4.5 rounded-[14px] border-0 bg-transparent p-0\",\n        compact: \"gap-3 rounded-xl border bg-card p-3\",\n      },\n    },\n  },\n);\n\nexport function RunSummary({\n  variant = \"card\",\n  outcome = \"success\",\n  className,\n  children,\n  ...props\n}: RunSummaryProps) {\n  const id = useId();\n  return (\n    <RunSummaryContext.Provider value={{ id, variant, outcome }}>\n      <section\n        aria-labelledby={`${id}-title`}\n        data-slot=\"run-summary\"\n        data-variant={variant}\n        data-outcome={outcome}\n        className={cn(runSummaryVariants({ variant }), className)}\n        {...props}\n      >\n        {children}\n      </section>\n    </RunSummaryContext.Provider>\n  );\n}\n\nexport function RunSummaryHeader({ className, children, ...props }: ComponentProps<\"div\">) {\n  const context = useRunSummary(\"RunSummaryHeader\");\n  const { icon: Icon, className: outcomeClass, label } = outcomeDetails[context.outcome];\n  const compact = context.variant === \"compact\";\n  return (\n    <div\n      data-slot=\"run-summary-header\"\n      className={cn(\"flex min-w-0 items-start\", compact ? \"gap-2.5\" : \"gap-3\", className)}\n      {...props}\n    >\n      <span\n        className={cn(\n          \"grid flex-none place-items-center\",\n          compact ? \"size-6 rounded-lg\" : \"size-7 rounded-[10px]\",\n          outcomeClass,\n        )}\n      >\n        <Icon size={compact ? 13 : 15} strokeWidth={1.75} aria-hidden=\"true\" />\n        <span className=\"sr-only\">{label}</span>\n      </span>\n      <div className=\"grid min-w-0 flex-1 gap-0.5\">{children}</div>\n    </div>\n  );\n}\n\nexport function RunSummaryTitle({ className, ...props }: ComponentProps<\"h3\">) {\n  const context = useRunSummary(\"RunSummaryTitle\");\n  return (\n    <h3\n      data-slot=\"run-summary-title\"\n      className={cn(\n        \"m-0 font-medium tracking-[-0.005em] text-balance\",\n        context.variant === \"compact\" ? \"pt-0.5 text-[13.5px]/5\" : \"pt-1 text-[14.5px]/5\",\n        className,\n      )}\n      {...props}\n      id={`${context.id}-title`}\n    />\n  );\n}\n\nexport function RunSummaryDescription({ className, ...props }: ComponentProps<\"p\">) {\n  useRunSummary(\"RunSummaryDescription\");\n  return (\n    <p\n      data-slot=\"run-summary-description\"\n      className={cn(\"m-0 text-[12.5px]/[18px] text-muted-foreground tabular-nums\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function RunSummaryStats({ className, ...props }: ComponentProps<\"dl\">) {\n  const context = useRunSummary(\"RunSummaryStats\");\n  return (\n    <dl\n      data-slot=\"run-summary-stats\"\n      className={cn(\n        \"m-0 grid grid-cols-[repeat(auto-fit,minmax(96px,1fr))]\",\n        context.variant === \"compact\" ? \"gap-1\" : \"gap-1.5\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport type RunSummaryStatProps = ComponentProps<\"div\"> & { label: ReactNode };\n\nexport function RunSummaryStat({ label, children, className, ...props }: RunSummaryStatProps) {\n  const context = useRunSummary(\"RunSummaryStat\");\n  const compact = context.variant === \"compact\";\n  return (\n    <div\n      data-slot=\"run-summary-stat\"\n      className={cn(\n        \"flex flex-col gap-0.5\",\n        compact ? \"rounded-lg px-2.5 py-1.5\" : \"rounded-[10px] px-3 py-2.5\",\n        context.variant === \"plain\" ? \"bg-muted\" : \"bg-muted/60\",\n        className,\n      )}\n      {...props}\n    >\n      <dt className=\"text-[11.5px]/4 text-subtle-foreground\">{label}</dt>\n      <dd\n        className={cn(\n          \"m-0 font-semibold tracking-[-0.01em] tabular-nums\",\n          compact ? \"text-sm/5\" : \"text-[17px]/6\",\n        )}\n      >\n        {children}\n      </dd>\n    </div>\n  );\n}\n\nexport type RunSummaryListProps = ComponentProps<\"div\"> & {\n  /** Heading for the list. */\n  label?: ReactNode;\n};\n\nfunction SummaryList({\n  part,\n  slot,\n  defaultLabel,\n  ordered = false,\n  label,\n  className,\n  children,\n  ...props\n}: RunSummaryListProps & {\n  part: string;\n  slot: string;\n  defaultLabel: string;\n  ordered?: boolean;\n}) {\n  const context = useRunSummary(part);\n  const headingId = useId();\n  const List = ordered ? \"ol\" : \"ul\";\n  return (\n    <div data-slot={slot} className={cn(\"grid min-w-0 gap-1.5\", className)} {...props}>\n      <h4 id={headingId} className=\"m-0 text-[11.5px]/4 font-medium text-subtle-foreground\">\n        {label ?? defaultLabel}\n      </h4>\n      <List\n        aria-labelledby={headingId}\n        className={cn(\n          \"m-0 grid list-none p-0\",\n          context.variant === \"compact\" ? \"gap-0\" : \"gap-0.5\",\n        )}\n      >\n        {children}\n      </List>\n    </div>\n  );\n}\n\nexport function RunSummaryArtifacts(props: RunSummaryListProps) {\n  return (\n    <SummaryList\n      {...props}\n      part=\"RunSummaryArtifacts\"\n      slot=\"run-summary-artifacts\"\n      defaultLabel=\"Changed files\"\n    />\n  );\n}\n\nexport type RunSummaryArtifactChange = \"added\" | \"modified\" | \"deleted\";\nconst changeDetails: Record<\n  RunSummaryArtifactChange,\n  { label: string; icon: LucideIcon; className: string }\n> = {\n  added: { label: \"Added\", icon: Plus, className: \"text-success-ink\" },\n  modified: { label: \"Modified\", icon: PencilLine, className: \"text-muted-foreground\" },\n  deleted: { label: \"Deleted\", icon: Minus, className: dangerText },\n};\n\nexport type RunSummaryArtifactProps = ComponentProps<\"li\"> & {\n  change?: RunSummaryArtifactChange;\n};\n\nexport function RunSummaryArtifact({\n  change = \"modified\",\n  className,\n  children,\n  ...props\n}: RunSummaryArtifactProps) {\n  const context = useRunSummary(\"RunSummaryArtifact\");\n  const { icon: Icon, className: changeClass, label } = changeDetails[change];\n  return (\n    <li\n      data-slot=\"run-summary-artifact\"\n      className={cn(\n        \"-mx-2 flex min-w-0 items-center gap-2 rounded-lg px-2\",\n        \"transition-[background-color] duration-120 ease-[ease-out] hover:bg-accent/50 motion-reduce:transition-none\",\n        context.variant === \"compact\" ? \"min-h-6.5\" : \"min-h-7.5\",\n        className,\n      )}\n      {...props}\n      data-change={change}\n    >\n      <Icon\n        size={13}\n        strokeWidth={2}\n        aria-hidden=\"true\"\n        className={cn(\"size-[13px]\", \"flex-none\", changeClass)}\n      />\n      <span className=\"sr-only\">{label}: </span>\n      <span\n        className={cn(\n          \"flex min-w-0 flex-1 items-baseline gap-2 decoration-border-strong\",\n          change === \"deleted\" && \"line-through\",\n        )}\n      >\n        {children}\n      </span>\n    </li>\n  );\n}\n\nexport function RunSummaryArtifactName({ className, ...props }: ComponentProps<\"span\">) {\n  useRunSummary(\"RunSummaryArtifactName\");\n  return (\n    <span\n      data-slot=\"run-summary-artifact-name\"\n      className={cn(\"min-w-0 truncate font-mono text-[12px]\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function RunSummaryArtifactMeta({ className, ...props }: ComponentProps<\"span\">) {\n  useRunSummary(\"RunSummaryArtifactMeta\");\n  return (\n    <span\n      data-slot=\"run-summary-artifact-meta\"\n      className={cn(\n        \"ml-auto flex-none font-mono text-[11.5px] text-subtle-foreground tabular-nums\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function RunSummaryWarnings(props: RunSummaryListProps) {\n  return (\n    <SummaryList\n      {...props}\n      part=\"RunSummaryWarnings\"\n      slot=\"run-summary-warnings\"\n      defaultLabel=\"Warnings\"\n    />\n  );\n}\n\nexport function RunSummaryWarning({ className, children, ...props }: ComponentProps<\"li\">) {\n  useRunSummary(\"RunSummaryWarning\");\n  return (\n    <li\n      data-slot=\"run-summary-warning\"\n      className={cn(\n        \"flex items-start gap-2 rounded-[10px] bg-warning/10 px-2.5 py-2 text-[12.5px]/[18px]\",\n        className,\n      )}\n      {...props}\n    >\n      <TriangleAlert\n        size={14}\n        aria-hidden=\"true\"\n        className=\"mt-0.5 flex-none text-warning-ink size-3.5\"\n      />\n      <span className=\"min-w-0 wrap-anywhere\">{children}</span>\n    </li>\n  );\n}\n\nexport function RunSummaryNextSteps(props: RunSummaryListProps) {\n  return (\n    <SummaryList\n      {...props}\n      part=\"RunSummaryNextSteps\"\n      slot=\"run-summary-next-steps\"\n      defaultLabel=\"Next steps\"\n      ordered\n    />\n  );\n}\n\nexport function RunSummaryNextStep({ className, children, ...props }: ComponentProps<\"li\">) {\n  useRunSummary(\"RunSummaryNextStep\");\n  return (\n    <li\n      data-slot=\"run-summary-next-step\"\n      className={cn(\"flex min-w-0 items-start gap-2 py-0.75\", className)}\n      {...props}\n    >\n      <ArrowRight\n        size={13}\n        strokeWidth={1.75}\n        aria-hidden=\"true\"\n        className=\"mt-0.75 flex-none text-subtle-foreground size-[13px]\"\n      />\n      <span className=\"min-w-0\">{children}</span>\n    </li>\n  );\n}\n\nexport function RunSummaryActions({ className, ...props }: ComponentProps<\"div\">) {\n  useRunSummary(\"RunSummaryActions\");\n  return (\n    <div\n      data-slot=\"run-summary-actions\"\n      className={cn(\"flex flex-wrap justify-end gap-2 pt-0.5\", className)}\n      {...props}\n    />\n  );\n}\n\nexport type RunSummaryActionProps = ComponentProps<\"button\"> & {\n  /** Primary actions use the accent fill. */\n  primary?: boolean;\n};\n\nexport function RunSummaryAction({ primary = false, className, ...props }: RunSummaryActionProps) {\n  const context = useRunSummary(\"RunSummaryAction\");\n  const compact = context.variant === \"compact\";\n  return (\n    <Button\n      type=\"button\"\n      variant={primary ? \"default\" : \"secondary\"}\n      data-slot=\"run-summary-action\"\n      data-emphasis={primary ? \"primary\" : \"secondary\"}\n      className={cn(\n        \"cursor-pointer rounded-full py-0\",\n        \"[transition:background-color_120ms_ease-out,filter_120ms_ease-out,scale_140ms_cubic-bezier(0.23,1,0.32,1)] active:scale-[0.97] motion-reduce:transition-none motion-reduce:active:scale-100\",\n        \"focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-ring\",\n        compact\n          ? \"h-7 px-3 text-[12.5px] has-[>svg]:px-3\"\n          : \"h-8 px-3.5 text-[13px] has-[>svg]:px-3.5\",\n        primary\n          ? \"bg-primary text-primary-foreground hover:bg-primary hover:brightness-[1.08]\"\n          : \"bg-secondary text-foreground hover:bg-[color-mix(in_oklab,var(--secondary)_85%,var(--foreground))]\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/uai/run-summary.tsx"
    }
  ],
  "categories": [
    "ai",
    "agents"
  ],
  "type": "registry:ui"
}