Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

222 lines
6.0 KiB
TypeScript

import { INTERNAL_EXAMPLES, type ExampleItem } from "@/lib/examples";
import { examples } from "@/lib/source";
import type {
XuluxTemplate,
XuluxTemplateCatalog,
XuluxTemplateCategory,
} from "@/components/xulux/templates/types";
const CATEGORIES: XuluxTemplateCategory[] = [
{
id: "chat",
name: "Chat",
description: "Conversational AI interfaces and chat surface patterns.",
},
{
id: "agents",
name: "Agents",
description: "Tool-using and workflow-oriented assistant experiences.",
},
{
id: "ui-patterns",
name: "UI Patterns",
description: "Artifacts, generative UI, forms, and embedded surfaces.",
},
{
id: "mobile",
name: "Mobile",
description: "React Native and mobile-first assistant-ui examples.",
},
];
// Fumadocs owns the example page content. This file only adds curated UI metadata
// that the docs source does not currently expose, such as category, preview type,
// and template-friendly tech labels.
const PREVIEW_COMPONENT_SLUGS = new Set([
"ai-sdk",
"artifacts",
"chatgpt",
"claude",
"gemini",
"generative-ui",
"grok",
"modal",
"perplexity",
]);
const TECH_BY_SLUG: Record<string, XuluxTemplate["tech"]> = {
"ai-sdk": {
framework: "Next.js",
runtime: "AI SDK",
frontendPattern: "Thread + Composer",
},
artifacts: {
framework: "Next.js",
runtime: "AI SDK",
frontendPattern: "Artifacts",
},
chatgpt: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Chat clone",
},
claude: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Chat clone",
},
expo: {
framework: "Expo",
runtime: "React Native",
frontendPattern: "Mobile chat",
},
"form-demo": {
framework: "Next.js",
runtime: "AI SDK",
frontendPattern: "Frontend tools",
},
gemini: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Chat clone",
},
"generative-ui": {
framework: "Next.js",
runtime: "AI SDK",
frontendPattern: "Generative UI",
},
grok: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Chat clone",
},
mem0: {
framework: "React",
runtime: "Mem0",
frontendPattern: "Memory chat",
},
modal: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Assistant modal",
},
perplexity: {
framework: "React",
runtime: "Local runtime",
frontendPattern: "Search chat",
},
stockbroker: {
framework: "React",
runtime: "LangGraph",
frontendPattern: "Human-in-the-loop",
},
};
const GRADIENTS = [
"from-cyan-500/40 via-sky-500/30 to-blue-400/20",
"from-emerald-500/40 via-teal-500/30 to-cyan-400/20",
"from-violet-500/40 via-purple-500/30 to-fuchsia-400/20",
"from-rose-500/40 via-orange-500/30 to-amber-400/20",
"from-slate-500/40 via-zinc-500/30 to-neutral-400/20",
];
function slugFromUrl(url: string): string | null {
const match = /^\/examples\/([^/?#]+)/.exec(url);
return match?.[1] ?? null;
}
function categoryForSlug(slug: string): XuluxTemplateCategory {
if (slug === "expo") return CATEGORIES[3]!;
if (["artifacts", "form-demo", "generative-ui", "modal"].includes(slug)) {
return CATEGORIES[2]!;
}
if (["stockbroker"].includes(slug)) return CATEGORIES[1]!;
return CATEGORIES[0]!;
}
function tagsForSlug(slug: string, item: ExampleItem): string[] {
const tags = new Set<string>();
if (slug.includes("ai-sdk")) tags.add("AI SDK");
if (slug.includes("langgraph") || slug === "stockbroker")
tags.add("LangGraph");
if (slug === "expo") tags.add("React Native");
if (slug === "artifacts") tags.add("Artifacts");
if (slug === "form-demo") tags.add("Forms");
if (slug === "generative-ui") tags.add("Generative UI");
if (slug === "modal") tags.add("Modal");
if (item.title.toLowerCase().includes("clone")) tags.add("Clone");
tags.add("Example");
return [...tags];
}
function sourcePathFromGithubLink(
githubLink: string | undefined,
): string | undefined {
if (!githubLink) return undefined;
const marker = "/assistant-ui/assistant-ui/";
const index = githubLink.indexOf(marker);
if (index === -1) return githubLink;
const repoPath = githubLink.slice(index + marker.length);
return repoPath.replace(/^blob\/main\//, "").replace(/^tree\/main\//, "");
}
function getExamplePageData(slug: string) {
return examples.getPage([slug]);
}
export function getXuluxExamplePreview(slug: string) {
const item = INTERNAL_EXAMPLES.find(
(example) => slugFromUrl(example.link) === slug,
);
if (!item) return null;
return {
slug,
title: item.title,
description: item.description,
screenshotUrl: item.image,
hasComponentPreview: PREVIEW_COMPONENT_SLUGS.has(slug),
};
}
export function getXuluxExamplesCatalog(): XuluxTemplateCatalog {
const templates = INTERNAL_EXAMPLES.flatMap<XuluxTemplate>((item, index) => {
if (item.external) return [];
const slug = slugFromUrl(item.link);
if (!slug) return [];
const page = getExamplePageData(slug);
if (!page) return [];
const category = categoryForSlug(slug);
const hasComponentPreview = PREVIEW_COMPONENT_SLUGS.has(slug);
return {
id: slug,
title: page.data.title ?? item.title,
description: page.data.description ?? item.description ?? item.title,
categoryId: category.id,
categoryName: category.name,
tags: tagsForSlug(slug, item),
prompt: `Use the ${page.data.title ?? item.title} example as the starting point and help me adapt it.`,
gradient: GRADIENTS[index % GRADIENTS.length]!,
kind: "example",
previewStatus: hasComponentPreview ? "live" : "stale",
previewUrl: `/xulux-preview/${slug}`,
screenshotUrl: item.image,
sourcePath: sourcePathFromGithubLink(item.githubLink),
docsUrl: page.url,
featured: index < 6,
tech: TECH_BY_SLUG[slug] ?? {
framework: "React",
runtime: "assistant-ui",
frontendPattern: "Example",
},
env: [],
canStart: true,
};
});
return {
categories: CATEGORIES,
templates,
};
}