{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "grok-plan",
  "title": "Grok Plan",
  "description": "Grok's plan.md approval card — framed viewer, a/s/c/q actions, Waiting on plan approval, and plan-approval composer.",
  "registryDependencies": [
    "https://brainless.swerdlow.dev/r/grok-prompt.json"
  ],
  "files": [
    {
      "path": "registry/brainless/grok/grok-plan.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { GrokPrompt } from \"@/registry/brainless/grok/grok-prompt\";\nimport { cn } from \"@/lib/utils\";\n\n/**\n * GrokPlan — Grok CLI's plan.md approval card.\n *\n * Captured grammar (v0.2.93): a framed `plan.md` viewer with line numbers,\n * an action row (`a approve | s request changes | c comment | q quit plan`),\n * a yellow `◆ Waiting on plan approval` status (38;5;11 — plan accent only),\n * and the composer in `· plan approval` mode.\n */\nconst BORDER = \"#808080\";\nconst FG = \"#e1e1e1\";\nconst MUTED = \"#8b8b90\";\nconst DIM = \"#6c6c6c\";\nconst PLAN = \"#ffff00\"; // 38;5;11 — plan-mode accent only\n\nconst DEFAULT_LINES = [\n  \"Plan: Touch planned.txt\",\n  \"\",\n  \"Context\",\n  \"\",\n  \"Create an empty marker file planned.txt in the workspace root so a planned touch can be verified. No other files or changes.\",\n  \"\",\n  \"Steps\",\n  \"\",\n  \"1. Create planned.txt — Write (or touch) an empty file at the workspace root.\",\n  \"2. Verify — Confirm the file exists (e.g. read or ls) and stop.\",\n  \"\",\n  \"Critical files\",\n  \"\",\n  \"• planned.txt (new) — workspace root\",\n];\n\nconst ACTIONS = [\n  { key: \"a\", label: \"approve\" },\n  { key: \"s\", label: \"request changes\" },\n  { key: \"c\", label: \"comment\" },\n  { key: \"q\", label: \"quit plan\" },\n] as const;\n\nexport function GrokPlan({\n  filename = \"plan.md\",\n  lines = DEFAULT_LINES,\n  status = \"Waiting on plan approval\",\n  onAction,\n  className,\n}: {\n  filename?: string;\n  lines?: string[];\n  status?: string;\n  onAction?: (key: (typeof ACTIONS)[number][\"key\"]) => void;\n  className?: string;\n}) {\n  return (\n    <div className={cn(\"space-y-3 font-mono text-[13px] leading-[1.5]\", className)}>\n      <div\n        className=\"overflow-hidden rounded-sm border\"\n        style={{ borderColor: BORDER }}\n        role=\"region\"\n        aria-label={`${filename} plan`}\n      >\n        <div\n          className=\"flex items-center justify-between border-b px-2 py-1 text-[12px]\"\n          style={{ borderColor: BORDER, color: MUTED }}\n        >\n          <span>\n            <span aria-hidden>─ </span>\n            {filename}\n          </span>\n          <span aria-hidden title=\"Open\">\n            [↗]\n          </span>\n        </div>\n\n        <ol className=\"max-h-[16rem] overflow-auto px-2 py-1.5\" style={{ color: FG }}>\n          {lines.map((line, i) => (\n            <li key={i} className=\"flex gap-2\">\n              <span\n                aria-hidden\n                className=\"w-5 shrink-0 select-none text-right tabular-nums\"\n                style={{ color: DIM }}\n              >\n                {i + 1}\n              </span>\n              <span className=\"min-w-0 whitespace-pre-wrap\">{line || \"\\u00a0\"}</span>\n            </li>\n          ))}\n        </ol>\n\n        <div\n          className=\"flex flex-wrap items-center justify-center gap-x-2 border-t px-2 py-1.5 text-[12px]\"\n          style={{ borderColor: BORDER, color: MUTED }}\n        >\n          {ACTIONS.map((a, i) => (\n            <React.Fragment key={a.key}>\n              {i > 0 ? <span aria-hidden>|</span> : null}\n              <button\n                type=\"button\"\n                onClick={() => onAction?.(a.key)}\n                className=\"rounded-none px-0.5 outline-none hover:text-white focus-visible:ring-1 focus-visible:ring-white/40\"\n              >\n                <span className=\"font-semibold\" style={{ color: FG }}>\n                  {a.key}\n                </span>{\" \"}\n                {a.label}\n              </button>\n            </React.Fragment>\n          ))}\n        </div>\n      </div>\n\n      <div\n        className=\"flex items-baseline gap-2\"\n        role=\"status\"\n        aria-live=\"polite\"\n        style={{ color: PLAN }}\n      >\n        <span aria-hidden>◆</span>\n        <span>{status}</span>\n      </div>\n\n      <GrokPrompt mode=\"plan-approval\" showShortcuts={false} />\n\n      <div\n        className=\"flex flex-wrap items-center gap-x-2 text-[12px]\"\n        style={{ color: DIM }}\n      >\n        <span>\n          <span className=\"font-semibold\" style={{ color: FG }}>\n            c\n          </span>\n          :comment\n        </span>\n        <span aria-hidden>│</span>\n        <span>\n          <span className=\"font-semibold\" style={{ color: FG }}>\n            a\n          </span>\n          :approve\n        </span>\n        <span aria-hidden>│</span>\n        <span>\n          <span className=\"font-semibold\" style={{ color: FG }}>\n            q\n          </span>\n          :quit plan\n        </span>\n        <span aria-hidden>│</span>\n        <span>\n          <span className=\"font-semibold\" style={{ color: FG }}>\n            Tab\n          </span>\n          :prompt\n        </span>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/brainless/grok/grok-plan.tsx"
    }
  ],
  "type": "registry:ui"
}