Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions app/components/[category]/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import {
registry,
type ComponentExample,
} from "@/lib/registry";
import { CodeBlock } from "@/components/app/code-block";
import { InstallBlock } from "@/components/app/install-block";
import { CodeBlock } from "@/components/app/docs/code-block";
import { InstallBlock } from "@/components/app/docs/install-block";
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/components/motion/tabs";
import { NewBadge } from "@/components/app/new-badge";
import { ComponentCard } from "@/components/app/component-card";
import { JsonLd } from "@/components/app/json-ld";
import { NewBadge } from "@/components/app/docs/new-badge";
import { ComponentCard } from "@/components/app/docs/component-card";
import { JsonLd } from "@/components/app/analytics/json-ld";
import { getPreview, previews } from "@/components/previews";
import { pageUrlFor, withSignature } from "@/lib/signature";
import { readSourceFile } from "@/lib/source-files";
Expand Down
4 changes: 2 additions & 2 deletions app/components/[category]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { findCategory, registry } from "@/lib/registry";
import { ComponentCard } from "@/components/app/component-card";
import { JsonLd } from "@/components/app/json-ld";
import { ComponentCard } from "@/components/app/docs/component-card";
import { JsonLd } from "@/components/app/analytics/json-ld";
import { breadcrumbJsonLd, categoryJsonLd } from "@/lib/seo";

export function generateStaticParams() {
Expand Down
134 changes: 107 additions & 27 deletions app/docs/ai-agents/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Metadata } from "next";
import Link from "next/link";
import { ArrowUpRight } from "lucide-react";
import { CodeBlock } from "@/components/app/code-block";
import { CodeBlock } from "@/components/app/docs/code-block";

export const metadata: Metadata = {
title: "AI Agents",
Expand All @@ -25,12 +25,36 @@ export const metadata: Metadata = {
};

const ENDPOINTS: { label: string; url: string; desc: string }[] = [
{ label: "llms.txt", url: "/llms.txt", desc: "Markdown index in llmstxt.org format." },
{ label: "Registry index", url: "/r", desc: "JSON catalogue of every component." },
{ label: "Component detail", url: "/r/{slug}", desc: "JSON with files, deps, source." },
{ label: "shadcn catalog", url: "/registry.json", desc: "Directory-compatible registry catalog." },
{ label: "shadcn item", url: "/r/{slug}.json", desc: "Install item with inline file content and shadcn semantic color classes." },
{ label: "Raw source", url: "/r/{slug}/raw", desc: "Plain text .tsx ready to drop in." },
{
label: "llms.txt",
url: "/llms.txt",
desc: "Markdown index in llmstxt.org format.",
},
{
label: "Registry index",
url: "/r",
desc: "JSON catalogue of every component.",
},
{
label: "Component detail",
url: "/r/{slug}",
desc: "JSON with files, deps, source.",
},
{
label: "shadcn catalog",
url: "/registry.json",
desc: "Directory-compatible registry catalog.",
},
{
label: "shadcn item",
url: "/r/{slug}.json",
desc: "Install item with inline file content and shadcn semantic color classes.",
},
{
label: "Raw source",
url: "/r/{slug}/raw",
desc: "Plain text .tsx ready to drop in.",
},
];

const MCP_URL = "https://mcp.beui.dev/mcp";
Expand Down Expand Up @@ -92,17 +116,30 @@ const ENTRY_SHAPE = `{

export default function AIAgentsPage() {
return (
<div className="max-w-3xl">
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Intro</p>
<h1 className="mt-2 text-3xl font-semibold tracking-tight text-foreground">For AI agents</h1>
<>
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
Intro
</p>
<h1 className="mt-2 text-3xl font-semibold tracking-tight text-foreground">
For AI agents
</h1>
<p className="mt-3 text-muted-foreground">
beUI exposes a static, agent-friendly surface. Connect the MCP server below, or hit the raw endpoints directly. Coding agents (Claude, Codex, Cursor, Amp) can list components, fetch source with all deps, and drop files into the user&apos;s project.
beUI exposes a static, agent-friendly surface. Connect the MCP server
below, or hit the raw endpoints directly. Coding agents (Claude, Codex,
Cursor, Amp) can list components, fetch source with all deps, and drop
files into the user&apos;s project.
</p>

<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">MCP server</h2>
<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">
MCP server
</h2>
<p className="mt-2 text-muted-foreground">
The fastest path: connect the beUI MCP server and your agent can list, search and install components directly. Hosted at{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs text-foreground">{MCP_URL}</code>.
The fastest path: connect the beUI MCP server and your agent can list,
search and install components directly. Hosted at{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs text-foreground">
{MCP_URL}
</code>
.
</p>
<div className="mt-4">
<CodeBlock code={MCP_CLI_SNIPPET} lang="bash" filename="terminal" />
Expand All @@ -114,17 +151,42 @@ export default function AIAgentsPage() {
<CodeBlock code={MCP_MANUAL_SNIPPET} lang="json" filename="mcp.json" />
</div>
<p className="mt-4 text-sm text-muted-foreground">
Tools: <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">list_components</code>, <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">search_components</code>, <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">get_component</code>, <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">get_install_command</code>.
Tools:{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
list_components
</code>
,{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
search_components
</code>
,{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
get_component
</code>
,{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
get_install_command
</code>
.
</p>

<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">Endpoints</h2>
<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">
Endpoints
</h2>
<ul className="mt-4 divide-y divide-border rounded-2xl border border-border bg-card">
{ENDPOINTS.map((e) => (
<li key={e.url} className="flex items-start justify-between gap-4 p-4">
<li
key={e.url}
className="flex items-start justify-between gap-4 p-4"
>
<div className="min-w-0">
<div className="flex items-center gap-2">
<code className="rounded-md bg-foreground/5 px-2 py-0.5 font-mono text-xs text-foreground">{e.url}</code>
<span className="text-sm font-medium text-foreground">{e.label}</span>
<code className="rounded-md bg-foreground/5 px-2 py-0.5 font-mono text-xs text-foreground">
{e.url}
</code>
<span className="text-sm font-medium text-foreground">
{e.label}
</span>
</div>
<p className="mt-1 text-sm text-muted-foreground">{e.desc}</p>
</div>
Expand All @@ -143,28 +205,46 @@ export default function AIAgentsPage() {
))}
</ul>

<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">Agent flow</h2>
<p className="mt-2 text-muted-foreground">Four calls, then install. Components are self-contained and own their files.</p>
<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">
Agent flow
</h2>
<p className="mt-2 text-muted-foreground">
Four calls, then install. Components are self-contained and own their
files.
</p>
<div className="mt-4">
<CodeBlock code={FETCH_SNIPPET} lang="ts" filename="agent.ts" />
</div>

<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">shadcn flow</h2>
<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">
shadcn flow
</h2>
<p className="mt-2 text-muted-foreground">
The shadcn item installs source files and package dependencies. Components use shadcn semantic color utilities directly, so they inherit the target app&apos;s theme without beUI-specific color variables.
The shadcn item installs source files and package dependencies.
Components use shadcn semantic color utilities directly, so they inherit
the target app&apos;s theme without beUI-specific color variables.
</p>
<div className="mt-4">
<CodeBlock code={SHADCN_SNIPPET} lang="bash" filename="terminal" />
</div>

<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">Entry shape</h2>
<h2 className="mt-10 text-xl font-semibold tracking-tight text-foreground">
Entry shape
</h2>
<p className="mt-2 text-muted-foreground">
Internal helpers (e.g. <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">@/lib/utils</code>) ship inline as <code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">type: util</code> so the agent does not have to chase imports.
Internal helpers (e.g.{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
@/lib/utils
</code>
) ship inline as{" "}
<code className="rounded bg-foreground/5 px-1.5 py-0.5 font-mono text-xs">
type: util
</code>{" "}
so the agent does not have to chase imports.
</p>
<div className="mt-4">
<CodeBlock code={ENTRY_SHAPE} lang="json" filename="r/swap.json" />
</div>

</div>
</>
);
}
2 changes: 1 addition & 1 deletion app/docs/theme/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Metadata } from "next";
import Link from "next/link";
import { ArrowUpRight } from "lucide-react";
import { CodeBlock } from "@/components/app/code-block";
import { CodeBlock } from "@/components/app/docs/code-block";
import { THEME_CSS } from "@/lib/theme-css";

export const metadata: Metadata = {
Expand Down
18 changes: 9 additions & 9 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import { SpeedInsights } from "@vercel/speed-insights/next";
import { Inter, JetBrains_Mono } from "next/font/google";
import { GeistPixelSquare } from "geist/font/pixel";
import "./globals.css";
import { GoogleAnalytics } from "@/components/app/google-analytics";
import { ThemeProvider } from "@/components/app/theme-provider";
import { PreferencesProvider } from "@/components/app/preferences-provider";
import { PreferencesPanel } from "@/components/app/preferences-panel";
import { SiteHeader } from "@/components/app/site-header";
import { SiteDock } from "@/components/app/site-dock";
import { SiteFrame } from "@/components/app/site-frame";
import { KeyboardShortcuts } from "@/components/app/keyboard-shortcuts";
import { JsonLd } from "@/components/app/json-ld";
import { GoogleAnalytics } from "@/components/app/analytics/google-analytics";
import { ThemeProvider } from "@/components/app/chrome/theme-provider";
import { PreferencesProvider } from "@/components/app/preferences/preferences-provider";
import { PreferencesPanel } from "@/components/app/preferences/preferences-panel";
import { SiteHeader } from "@/components/app/chrome/site-header";
import { SiteDock } from "@/components/app/chrome/site-dock";
import { SiteFrame } from "@/components/app/chrome/site-frame";
import { KeyboardShortcuts } from "@/components/app/chrome/keyboard-shortcuts";
import { JsonLd } from "@/components/app/analytics/json-ld";
import { getGithubStarCount } from "@/lib/github";
import { AUTHOR, SITE_DESCRIPTION, SITE_NAME, siteJsonLd } from "@/lib/seo";
import { SITE_URL } from "@/lib/site";
Expand Down
10 changes: 5 additions & 5 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Link from "next/link";
import { ArrowRight } from "lucide-react";
import { registry } from "@/lib/registry";
import { Hero } from "@/components/app/hero";
import { InstallCommand } from "@/components/app/install-command";
import { LandingComponentCard } from "@/components/app/landing-component-card";
import { SiteFooter } from "@/components/app/site-footer";
import { WorkCta } from "@/components/app/work-cta";
import { Hero } from "@/components/app/landing/hero";
import { InstallCommand } from "@/components/app/docs/install-command";
import { LandingComponentCard } from "@/components/app/landing/landing-component-card";
import { SiteFooter } from "@/components/app/chrome/site-footer";
import { WorkCta } from "@/components/app/landing/work-cta";

const CURATED: { category: string; slug: string }[] = [
{ category: "motion", slug: "button" },
Expand Down
2 changes: 1 addition & 1 deletion app/sponsors/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Metadata } from "next";
import { ArrowUpRight } from "lucide-react";
import { CopyButton } from "@/components/app/copy-button";
import { CopyButton } from "@/components/app/docs/copy-button";
import { PressLink } from "@/components/app/press-link";

export const metadata: Metadata = {
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Menu } from "lucide-react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useEffect, useState } from "react";
import { SidebarNav } from "@/components/app/site-sidebar";
import { SidebarNav } from "@/components/app/chrome/site-sidebar";
import { BottomSheet } from "@/components/motion/bottom-sheet";
import { Button } from "@/components/motion/button";
import { cn } from "@/lib/utils";
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import Link from "next/link";
import { GithubIcon } from "@/components/app/icons";
import { registry } from "@/lib/registry";

const motionComponents = registry.find((c) => c.slug === "motion")?.components ?? [];
const blockComponents = registry.find((c) => c.slug === "blocks")?.components ?? [];
// The catalog keeps growing — the footer shows only the newest few per column.
const FOOTER_LIMIT = 8;

const allMotion = registry.find((c) => c.slug === "motion")?.components ?? [];
const allBlocks = registry.find((c) => c.slug === "blocks")?.components ?? [];
const motionComponents = allMotion.slice(-FOOTER_LIMIT).reverse();
const blockComponents = allBlocks.slice(-FOOTER_LIMIT).reverse();

export function SiteFooter() {
return (
Expand Down Expand Up @@ -68,6 +73,14 @@ export function SiteFooter() {
</Link>
</li>
))}
<li>
<Link
href="/components/motion"
className="text-sm font-medium text-foreground transition-colors hover:text-muted-foreground"
>
View all ({allMotion.length})
</Link>
</li>
</ul>
</div>

Expand All @@ -87,6 +100,14 @@ export function SiteFooter() {
</Link>
</li>
))}
<li>
<Link
href="/components/blocks"
className="text-sm font-medium text-foreground transition-colors hover:text-muted-foreground"
>
View all ({allBlocks.length})
</Link>
</li>
</ul>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import { usePathname } from "next/navigation";
import type { ReactNode } from "react";
import { SiteSidebar } from "@/components/app/site-sidebar";
import { PageTransition } from "@/components/app/page-transition";
import { SiteSidebar } from "@/components/app/chrome/site-sidebar";
import { PageTransition } from "@/components/app/chrome/page-transition";

const SIDEBAR_PATHS = ["/components", "/docs"];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { GithubIcon } from "@/components/app/icons";
import { MobileNav } from "@/components/app/mobile-nav";
import { usePreferences } from "@/components/app/preferences-provider";
import { MobileNav } from "@/components/app/chrome/mobile-nav";
import { usePreferences } from "@/components/app/preferences/preferences-provider";
import { PressLink } from "@/components/app/press-link";
import { SiteSearch } from "@/components/app/site-search";
import { SiteSearch } from "@/components/app/chrome/site-search";
import { Tooltip } from "@/components/motion/tooltip";
import { cn } from "@/lib/utils";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
CommandPalette,
type CommandItem,
} from "@/components/motion/command-palette";
import { NewBadge } from "@/components/app/new-badge";
import { NewBadge } from "@/components/app/docs/new-badge";
import { registry } from "@/lib/registry";

const PAGES = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Link from "next/link";
import { usePathname } from "next/navigation";
import { registry } from "@/lib/registry";
import { NewBadge } from "@/components/app/new-badge";
import { NewBadge } from "@/components/app/docs/new-badge";
import { SharedLayoutBg } from "@/components/motion/shared-layout-bg";
import { cn } from "@/lib/utils";

Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Link from "next/link";
import { NewBadge } from "@/components/app/new-badge";
import { NewBadge } from "@/components/app/docs/new-badge";

export function ComponentCard({
categorySlug,
Expand Down
File renamed without changes.
Loading
Loading