{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "prompt-library",
  "type": "registry:ui",
  "title": "Prompt library",
  "description": "A searchable list of saved prompts that filters by title, body and tag as you type and returns the chosen prompt through onSelect. Useful in React AI apps.",
  "dependencies": [],
  "registryDependencies": [
    "https://ui.minidev.pro/r/search-input.json",
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/prompt-library.tsx",
      "type": "registry:ui",
      "target": "components/ui/prompt-library.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { cn } from \"@/lib/utils\"\nimport { SearchInput } from \"@/components/ui/search-input\"\n\n/** PromptLibrary — a searchable list of saved prompts, each a card with a title, tag and two-line preview. */\n\ntype Prompt = { id: string; title: string; body: string; tag?: string }\n\n// Saved prompts for the Lumen finance assistant.\nconst SAMPLE_PROMPTS: Prompt[] = [\n  { id: \"overdue\", title: \"Chase overdue invoices\", body: \"List every invoice more than 14 days overdue, group by customer, and draft a polite reminder for each.\", tag: \"Collections\" },\n  { id: \"month-close\", title: \"Month-end close checklist\", body: \"Walk through unreconciled transactions, flag anything over $5,000 without a receipt, and summarize open items.\", tag: \"Close\" },\n  { id: \"cash-forecast\", title: \"13-week cash forecast\", body: \"Project cash from open invoices, recurring bills and payroll. Call out the first week balance drops below $50,000.\", tag: \"Planning\" },\n  { id: \"board-summary\", title: \"Board revenue summary\", body: \"Summarize MRR, churn and expansion for the quarter in five bullet points a board member can read in a minute.\", tag: \"Reporting\" },\n  { id: \"vendor-dupes\", title: \"Find duplicate vendor bills\", body: \"Compare bills from the last 90 days by amount, vendor and date and list likely duplicates.\", tag: \"Audit\" },\n]\n\ntype PromptLibraryProps = {\n  prompts?: Prompt[]\n  onSelect?: (p: Prompt) => void\n  className?: string\n}\n\nfunction PromptLibrary({\n  prompts = SAMPLE_PROMPTS,\n  onSelect,\n  className,\n}: PromptLibraryProps) {\n  const [q, setQ] = React.useState(\"\")\n  const filtered = prompts.filter((p) => `${p.title} ${p.body} ${p.tag ?? \"\"}`.toLowerCase().includes(q.toLowerCase()))\n  return (\n    <div data-slot=\"prompt-library\" className={cn(\"space-y-3\", className)}>\n      <SearchInput aria-label=\"Search prompts\" placeholder=\"Search prompts…\" value={q} onChange={(e) => setQ(e.target.value)} />\n      <ul className=\"space-y-2\">\n        {filtered.map((p) => (\n          <li key={p.id}>\n            <button\n              type=\"button\"\n              onClick={() => onSelect?.(p)}\n              className=\"w-full rounded-xl border border-border bg-surface px-3 py-2.5 text-left outline-none hover:border-fg-subtle focus-visible:ring-2 focus-visible:ring-accent\"\n            >\n              <div className=\"flex items-center justify-between gap-2\">\n                <span className=\"text-sm font-medium text-fg\">{p.title}</span>\n                {p.tag ? <span className=\"text-[11px] text-fg-muted\">{p.tag}</span> : null}\n              </div>\n              <p className=\"mt-1 line-clamp-2 text-xs text-fg-muted\">{p.body}</p>\n            </button>\n          </li>\n        ))}\n      </ul>\n    </div>\n  )\n}\nexport { PromptLibrary }\nexport type { PromptLibraryProps, Prompt }\n"
    }
  ]
}
