{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-elements",
  "type": "registry:block",
  "title": "AI Elements",
  "description": "Composable AI chat UI primitives inspired by Vercel AI Elements and shadcn/ui conventions.",
  "dependencies": [],
  "devDependencies": [],
  "registryDependencies": [
    "https://stackfoundry.dev/r/ai-sdk.json"
  ],
  "files": [
    {
      "path": "apps/web/src/components/ai-elements/conversation.tsx",
      "type": "registry:component",
      "target": "apps/web/src/components/ai-elements/conversation.tsx",
      "content": "import type { ReactNode } from \"react\";\n\nexport function AIConversation({ children }: { children: ReactNode }) {\n  return <div className=\"flex flex-col gap-3 rounded-lg border p-4\">{children}</div>;\n}\n"
    },
    {
      "path": "apps/web/src/components/ai-elements/message.tsx",
      "type": "registry:component",
      "target": "apps/web/src/components/ai-elements/message.tsx",
      "content": "import type { UIMessage } from \"ai\";\n\nexport function AIMessage({ message }: { message: UIMessage }) {\n  return (\n    <article className=\"rounded-md bg-muted p-3 text-sm\">\n      <div className=\"mb-1 font-medium capitalize\">{message.role}</div>\n      {message.parts.map((part, index) =>\n        part.type === \"text\" ? <p key={index}>{part.text}</p> : null,\n      )}\n    </article>\n  );\n}\n"
    },
    {
      "path": "apps/web/src/components/ai-elements/prompt-input.tsx",
      "type": "registry:component",
      "target": "apps/web/src/components/ai-elements/prompt-input.tsx",
      "content": "\"use client\";\n\nimport type { FormEvent } from \"react\";\n\nexport function AIPromptInput({\n  disabled,\n  onSubmit,\n  onValueChange,\n  value,\n}: {\n  disabled?: boolean;\n  onSubmit: () => void;\n  onValueChange: (value: string) => void;\n  value: string;\n}) {\n  function submit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault();\n    onSubmit();\n  }\n\n  return (\n    <form className=\"flex gap-2\" onSubmit={submit}>\n      <textarea\n        className=\"min-h-24 flex-1 rounded-md border bg-background p-3 text-sm\"\n        disabled={disabled}\n        value={value}\n        onChange={(event) => onValueChange(event.target.value)}\n        placeholder=\"Ask a question...\"\n      />\n      <button className=\"rounded-md border px-3 text-sm\" disabled={disabled} type=\"submit\">\n        Send\n      </button>\n    </form>\n  );\n}\n"
    },
    {
      "path": "apps/web/src/components/ai-elements/status.tsx",
      "type": "registry:component",
      "target": "apps/web/src/components/ai-elements/status.tsx",
      "content": "type AIChatStatus = \"submitted\" | \"streaming\" | \"ready\" | \"error\";\n\nexport function AIStatus({ status }: { status: AIChatStatus }) {\n  if (status === \"ready\") return null;\n\n  return (\n    <p className=\"text-sm text-muted-foreground\" role=\"status\">\n      {status === \"submitted\" ? \"Thinking...\" : \"Streaming response...\"}\n    </p>\n  );\n}\n"
    },
    {
      "path": "apps/web/src/components/ai-elements/index.ts",
      "type": "registry:file",
      "target": "apps/web/src/components/ai-elements/index.ts",
      "content": "export { AIConversation } from \"./conversation\";\nexport { AIMessage } from \"./message\";\nexport { AIPromptInput } from \"./prompt-input\";\nexport { AIStatus } from \"./status\";\n"
    }
  ],
  "maintenanceSkills": [
    {
      "name": "ai-elements",
      "target": ".stackfoundry/skills/ai-elements/SKILL.md",
      "content": "---\nname: ai-elements\ndescription: Maintain the AI Elements module installed by StackFoundry.\n---\n\n# AI Elements Maintenance Instructions\n\n- Keep components provider-neutral and composable.\n- Preserve AI SDK `UIMessage.parts` rendering.\n- Avoid coupling UI primitives to one model provider or gateway.\n- Keep accessibility labels and status announcements intact.\n\n## Shared Skills\n\nWhen provider, framework, or database behavior changes, load the installed shared skill before editing implementation details:\n\n- `.stackfoundry/skills/ai-sdk/SKILL.md` (source: `registry/skills/ai-sdk/SKILL.md`)\n- `.stackfoundry/skills/nextjs/SKILL.md` (source: `registry/skills/nextjs/SKILL.md`)\n\nKeep this module skill focused on ownership, installed files, env vars, deployment checks, and module-specific invariants.\n"
    },
    {
      "name": "ai-sdk",
      "target": ".stackfoundry/skills/ai-sdk/SKILL.md",
      "content": "---\nname: ai-sdk\ndescription: AI SDK guidance for installed AI modules.\n---\n\n# Ai Sdk Guidance\n\n## Installed Location\n\n- Installed target: `.stackfoundry/skills/ai-sdk/SKILL.md`\n- Registry source: `registry/skills/ai-sdk/SKILL.md`\n\nAgents maintaining an installed module should load this shared skill from the installed target when provider, framework, database, SDK, or platform behavior is involved. Keep provider-specific API details here instead of duplicating them inside module maintenance skills.\n\n- Keep provider keys server-only.\n- Stream responses deliberately and handle tool errors.\n- Validate tool inputs and outputs.\n- Document model ids, fallback behavior, and cost-sensitive paths.\n"
    },
    {
      "name": "nextjs",
      "target": ".stackfoundry/skills/nextjs/SKILL.md",
      "content": "---\nname: nextjs\ndescription: Maintain Next.js App Router code installed by StackFoundry modules.\n---\n\n# Next.js Operating Instructions\n\n## Installed Location\n\n- Installed target: `.stackfoundry/skills/nextjs/SKILL.md`\n- Registry source: `registry/skills/nextjs/SKILL.md`\n\nAgents maintaining an installed module should load this shared skill from the installed target when provider, framework, database, SDK, or platform behavior is involved. Keep provider-specific API details here instead of duplicating them inside module maintenance skills.\n\n- Keep server-only data access out of Client Components.\n- Put route handlers under `app/api` and UI routes under the relevant App Router segment.\n- Prefer Server Components for data loading and add `\"use client\"` only for interactivity.\n- Keep public environment variables prefixed with `NEXT_PUBLIC_`; keep secrets server-only.\n- Re-run typecheck and build after changing route handlers, layouts, or shared app configuration.\n"
    }
  ],
  "envVars": {},
  "docs": "# AI Elements\n\nComposable AI chat UI primitives inspired by Vercel AI Elements and shadcn/ui conventions.\n\nVercel AI Elements is a component library and registry built on shadcn/ui conventions for AI-native interfaces. This module brings a small source-owned subset into StackFoundry so teams can compose chat interfaces without taking a hard dependency on a specific provider UI.\n\n## Owns\n\n- `apps/web/src/components/ai-elements/conversation.tsx`\n- `apps/web/src/components/ai-elements/message.tsx`\n- `apps/web/src/components/ai-elements/prompt-input.tsx`\n- `apps/web/src/components/ai-elements/status.tsx`\n- `apps/web/src/components/ai-elements/index.ts`\n\n## Maintenance\n\n- Keep components provider-neutral.\n- Render AI SDK UI message `parts`, not legacy content strings.\n- Keep primitives composable so apps can replace styling or layout.\n- Credit the Vercel AI Elements / shadcn-style pattern in docs when extending this module.\n",
  "meta": {
    "category": "components",
    "env": [],
    "status": "ready",
    "maturity": "ready",
    "recommendedFor": []
  }
}
