{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "claude-code-terminal",
  "title": "Claude Code Terminal",
  "description": "The terminal window with traffic lights and a title bar for Claude Code sessions.",
  "dependencies": [
    "cn"
  ],
  "registryDependencies": [
    "card",
    "collapsible",
    "scroll-area"
  ],
  "files": [
    {
      "path": "registry/notra/claude-code/components/claude-code-terminal.tsx",
      "content": "import { cn } from \"cn\";\n\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\nimport type { ClaudeCodeTerminalProps } from \"../types/claude-code\";\n\nexport const ClaudeCodeTerminal = ({\n  children,\n  className,\n  contentClassName,\n  footer,\n  title,\n  ...props\n}: ClaudeCodeTerminalProps) => (\n  <Card\n    className={cn(\n      \"bg-claude-code-bg font-claude-code text-claude-code-fg ring-claude-code-ring w-full min-w-0 gap-0 overflow-clip rounded-xl py-0 shadow-[0_1.5rem_3.5rem_-1rem_var(--claude-code-shadow)] ring-1\",\n      className\n    )}\n    data-slot=\"claude-code-terminal\"\n    {...props}\n  >\n    <CardHeader className=\"bg-claude-code-chrome relative flex h-8 shrink-0 items-center justify-center rounded-none px-3 py-0\">\n      <div\n        aria-hidden=\"true\"\n        className=\"absolute inset-y-0 left-3 flex items-center gap-2\"\n      >\n        <span className=\"bg-claude-code-traffic size-3 shrink-0 rounded-full\" />\n        <span className=\"bg-claude-code-traffic size-3 shrink-0 rounded-full\" />\n        <span className=\"bg-claude-code-traffic size-3 shrink-0 rounded-full\" />\n      </div>\n      {title && (\n        <CardTitle className=\"font-claude-code text-claude-code-title max-w-[60%] min-w-0 truncate text-xs leading-4 font-normal\">\n          {title}\n        </CardTitle>\n      )}\n    </CardHeader>\n    <ScrollArea className=\"min-h-0 flex-1\">\n      <CardContent\n        className={cn(\n          \"flex flex-col gap-5 px-3 py-4 text-[0.8125rem] leading-5 sm:px-4\",\n          contentClassName\n        )}\n        data-slot=\"claude-code-terminal-content\"\n      >\n        {children}\n      </CardContent>\n    </ScrollArea>\n    {footer && (\n      <div className=\"shrink-0 px-3 pb-3 text-[0.8125rem] leading-5 sm:px-4\">\n        {footer}\n      </div>\n    )}\n  </Card>\n);\n",
      "type": "registry:component",
      "target": "components/claude-code/components/claude-code-terminal.tsx"
    },
    {
      "path": "registry/notra/claude-code/types/claude-code.ts",
      "content": "import type {\n  ChangeEventHandler,\n  ComponentProps,\n  KeyboardEventHandler,\n  ReactNode,\n  Ref,\n} from \"react\";\n\nimport type { Card } from \"@/components/ui/card\";\nimport type { Collapsible } from \"@/components/ui/collapsible\";\n\nexport type ClaudeCodeMode =\n  | \"auto\"\n  | \"manual\"\n  | \"accept-edits\"\n  | \"plan\"\n  | \"bypass\";\n\nexport type ClaudeCodeEffort =\n  | \"low\"\n  | \"medium\"\n  | \"high\"\n  | \"xhigh\"\n  | \"max\"\n  | \"ultracode\";\n\nexport type ClaudeCodeTodoStatus = \"done\" | \"active\" | \"todo\";\n\nexport type ClaudeCodeToolCallStatus = \"success\" | \"error\" | \"pending\";\n\nexport interface ClaudeCodeModeConfig {\n  className: string;\n  /** Whether the status line shows the shift+tab hint. */\n  cycles: boolean;\n  label: string;\n}\n\nexport interface ClaudeCodeEffortConfig {\n  className: string;\n  glyph: string;\n}\n\nexport interface ClaudeCodeTodoConfig {\n  glyph: string;\n  labelClassName: string;\n  srLabel: string;\n}\n\nexport interface ClaudeCodeToolCallConfig {\n  className: string;\n  srLabel: string;\n}\n\nexport interface ClaudeCodeTodo {\n  label: string;\n  status: ClaudeCodeTodoStatus;\n}\n\nexport interface ClaudeCodePullRequest {\n  href?: string;\n  number: number;\n}\n\nexport interface ClaudeCodeTerminalProps extends Omit<\n  ComponentProps<typeof Card>,\n  \"title\"\n> {\n  contentClassName?: string;\n  /** Pinned under the scrolling transcript, like Claude Code's prompt. */\n  footer?: ReactNode;\n  title?: ReactNode;\n}\n\nexport interface ClaudeCodeLogoProps extends ComponentProps<\"svg\"> {\n  size?: number;\n}\n\nexport interface ClaudeCodeHeaderProps extends ComponentProps<\"div\"> {\n  cwd?: string;\n  model?: string;\n  org?: string;\n  /** Dim `⎿` lines under the notices, like hook output or tips. */\n  tips?: string[];\n  version?: string;\n  /** Notice lines printed under the header. Supports `code` and **bold**. */\n  whatsNew?: string[];\n}\n\nexport interface ClaudeCodeMessageProps extends ComponentProps<\"div\"> {\n  from?: \"user\" | \"assistant\";\n}\n\nexport interface ClaudeCodeThinkingProps extends Omit<\n  ComponentProps<typeof Collapsible>,\n  \"children\"\n> {\n  children?: ReactNode;\n  label?: ReactNode;\n}\n\nexport interface ClaudeCodeSpinnerProps extends ComponentProps<\"div\"> {\n  /** Extra fields in the parentheses, like `thinking`. */\n  details?: string[];\n  elapsed?: string;\n  /** Freeze the glyph, for screenshots and reduced motion. */\n  paused?: boolean;\n  tip?: string;\n  tokens?: number;\n  verb?: string;\n}\n\nexport interface ClaudeCodeTurnSummaryProps extends ComponentProps<\"div\"> {\n  doneAt?: string;\n  duration: string;\n  verb?: string;\n}\n\nexport interface ClaudeCodeInterruptedProps extends ComponentProps<\"p\"> {\n  /** Shown after `Interrupted ·`. */\n  hint?: ReactNode;\n}\n\nexport interface ClaudeCodeTodoListProps extends ComponentProps<\"div\"> {\n  /** The tool line above the list. Pass `null` to leave it out. */\n  heading?: string | null;\n  todos: ClaudeCodeTodo[];\n}\n\nexport interface ClaudeCodeToolCallProps extends Omit<\n  ComponentProps<typeof Collapsible>,\n  \"children\"\n> {\n  arg?: string;\n  children?: ReactNode;\n  result: ReactNode;\n  status?: ClaudeCodeToolCallStatus;\n  tool: string;\n}\n\nexport interface ClaudeCodeToolSummaryProps extends Omit<\n  ComponentProps<typeof Collapsible>,\n  \"children\"\n> {\n  children?: ReactNode;\n  count: number;\n  noun?: string;\n  verb?: string;\n}\n\nexport interface ClaudeCodePromptProps extends Omit<\n  ComponentProps<\"form\">,\n  \"defaultValue\" | \"onChange\" | \"onKeyDown\" | \"onSubmit\"\n> {\n  /** A turn is running: Enter does not send and Escape calls `onStop`. */\n  busy?: boolean;\n  defaultValue?: string;\n  effort?: ClaudeCodeEffort | false;\n  inputClassName?: string;\n  inputRef?: Ref<HTMLInputElement>;\n  mode?: ClaudeCodeMode;\n  onChange?: ChangeEventHandler<HTMLInputElement>;\n  onKeyDown?: KeyboardEventHandler<HTMLInputElement>;\n  /**\n   * Called with the trimmed text on Enter. An uncontrolled prompt clears\n   * afterwards; with `value`, clear it yourself here.\n   */\n  onSend?: (text: string) => void;\n  /** Called on Escape while `busy`, to interrupt the running turn. */\n  onStop?: () => void;\n  placeholder?: string;\n  pullRequest?: ClaudeCodePullRequest;\n  value?: string;\n}\n\nexport interface ClaudeCodeSessionHeader {\n  cwd: string;\n  model: string;\n  org: string;\n  tips: string[];\n  version: string;\n  whatsNew: string[];\n}\n\nexport interface ClaudeCodeSessionToolCall {\n  arg?: string;\n  detail?: string;\n  id: string;\n  result: string;\n  status?: ClaudeCodeToolCallStatus;\n  tool: string;\n}\n\nexport interface ClaudeCodeSessionSpinner {\n  details: string[];\n  elapsed: string;\n  tip: string;\n  tokens: number;\n  verb: string;\n}\n\nexport interface ClaudeCodeSessionTurn {\n  answer: string;\n  commands: ClaudeCodeSessionToolCall[];\n  id: string;\n  prompt: string;\n  summary: ClaudeCodeSessionSummary;\n  thinking?: string;\n  todos?: ClaudeCodeTodo[];\n}\n\nexport interface ClaudeCodeSessionSummary {\n  doneAt: string;\n  duration: string;\n  verb: string;\n}\n\nexport type ClaudeCodeTurnStatus =\n  | \"working\"\n  | \"streaming\"\n  | \"done\"\n  | \"interrupted\";\n\n/** A scripted answer the demo plays back when you send a prompt. */\nexport interface ClaudeCodeReply {\n  answer: string;\n  commands: ClaudeCodeSessionToolCall[];\n  /** The spinner verb while the turn runs, like `Sketching`. */\n  spinnerVerb: string;\n  /** The verb on the summary line once the turn is done, like `Cooked`. */\n  summaryVerb: string;\n}\n\nexport interface ClaudeCodeChatTurn extends Omit<\n  ClaudeCodeSessionTurn,\n  \"summary\"\n> {\n  status: ClaudeCodeTurnStatus;\n  summary?: ClaudeCodeSessionSummary;\n}\n\nexport interface ClaudeCodeChat {\n  busy: boolean;\n  /** Whole seconds since the running turn started. */\n  elapsed: number;\n  send: (text: string) => Promise<void>;\n  spinnerVerb: string;\n  stop: () => void;\n  /** Tokens streamed in the running turn so far. */\n  tokens: number;\n  turns: ClaudeCodeChatTurn[];\n}\n\nexport interface ClaudeCodeSessionPendingTurn {\n  prompt: string;\n  spinner: ClaudeCodeSessionSpinner;\n  todos: ClaudeCodeTodo[];\n  toolCall: ClaudeCodeSessionToolCall;\n}\n\nexport interface ClaudeCodeSession {\n  header: ClaudeCodeSessionHeader;\n  pending: ClaudeCodeSessionPendingTurn;\n  promptPlaceholder: string;\n  pullRequest: ClaudeCodePullRequest;\n  title: string;\n  turns: ClaudeCodeSessionTurn[];\n}\n",
      "type": "registry:lib",
      "target": "components/claude-code/types/claude-code.ts"
    }
  ],
  "cssVars": {
    "theme": {
      "color-claude-code-bg": "var(--claude-code-bg)",
      "color-claude-code-chrome": "var(--claude-code-chrome)",
      "color-claude-code-traffic": "var(--claude-code-traffic)",
      "color-claude-code-title": "var(--claude-code-title)",
      "color-claude-code-shadow": "var(--claude-code-shadow)",
      "color-claude-code-ring": "var(--claude-code-ring)",
      "color-claude-code-fg": "var(--claude-code-fg)",
      "color-claude-code-strong": "var(--claude-code-strong)",
      "color-claude-code-accent": "var(--claude-code-accent)",
      "color-claude-code-muted": "var(--claude-code-muted)",
      "color-claude-code-rule": "var(--claude-code-rule)",
      "color-claude-code-link": "var(--claude-code-link)",
      "color-claude-code-pr": "var(--claude-code-pr)",
      "color-claude-code-user-bg": "var(--claude-code-user-bg)",
      "color-claude-code-user-prompt": "var(--claude-code-user-prompt)",
      "color-claude-code-success": "var(--claude-code-success)",
      "color-claude-code-error": "var(--claude-code-error)",
      "color-claude-code-mode-auto": "var(--claude-code-mode-auto)",
      "color-claude-code-mode-accept-edits": "var(--claude-code-mode-accept-edits)",
      "color-claude-code-mode-plan": "var(--claude-code-mode-plan)",
      "color-claude-code-mode-bypass": "var(--claude-code-mode-bypass)",
      "font-claude-code": "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace"
    },
    "light": {
      "claude-code-bg": "#ffffff",
      "claude-code-chrome": "#ececec",
      "claude-code-traffic": "#d4d4d4",
      "claude-code-title": "#00000073",
      "claude-code-shadow": "#00000026",
      "claude-code-ring": "#0000001a",
      "claude-code-fg": "#1f1f1f",
      "claude-code-strong": "#000000",
      "claude-code-accent": "#d77757",
      "claude-code-muted": "#666666",
      "claude-code-rule": "#999999",
      "claude-code-link": "#5769f7",
      "claude-code-pr": "#966c1e",
      "claude-code-user-bg": "#f0f0f0",
      "claude-code-user-prompt": "#999999",
      "claude-code-success": "#2c7a39",
      "claude-code-error": "#ab2b3f",
      "claude-code-mode-auto": "#966c1e",
      "claude-code-mode-accept-edits": "#8700ff",
      "claude-code-mode-plan": "#006666",
      "claude-code-mode-bypass": "#d1245a"
    },
    "dark": {
      "claude-code-bg": "#0f0f0f",
      "claude-code-chrome": "#1c1c1c",
      "claude-code-traffic": "#3a3a3a",
      "claude-code-title": "#ffffff66",
      "claude-code-shadow": "#0000004d",
      "claude-code-ring": "#ffffff1a",
      "claude-code-fg": "#f7f7f7",
      "claude-code-strong": "#ffffff",
      "claude-code-accent": "#e06443",
      "claude-code-muted": "#8c8c8c",
      "claude-code-rule": "#7b7b7b",
      "claude-code-link": "#a4b0fc",
      "claude-code-pr": "#d9b559",
      "claude-code-user-bg": "#2e2e2e",
      "claude-code-user-prompt": "#5c5c5c",
      "claude-code-success": "#4eba65",
      "claude-code-error": "#ff6b80",
      "claude-code-mode-auto": "#e5c07b",
      "claude-code-mode-accept-edits": "#af87ff",
      "claude-code-mode-plan": "#48968c",
      "claude-code-mode-bypass": "#fd526f"
    }
  },
  "type": "registry:component"
}