add-components-to-registry by tambo-ai/tambo
npx skills add https://github.com/tambo-ai/tambo --skill add-components-to-registry将现有的 React 组件转换为 Tambo 注册的组件,以便 AI 可以渲染。
# 指向组件文件或文件夹
/add-components-to-registry src/components/ProductCard.tsx
/add-components-to-registry src/components/cards/
读取组件文件并提取:
// src/components/ProductCard.tsx
interface ProductCardProps {
name: string;
price: number;
imageUrl?: string;
onSale?: boolean;
rating?: number;
}
export function ProductCard({
name,
price,
imageUrl,
onSale,
rating,
}: ProductCardProps) {
return (
<div className="product-card">
{imageUrl && <img src={imageUrl} alt={name} />}
<h3>{name}</h3>
<p>
${price}
{onSale && " (On Sale!)"}
</p>
{rating && <span>★ {rating}/5</span>}
</div>
);
}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
使用 .describe() 将 TypeScript 类型转换为 Zod:
import { z } from "zod";
export const ProductCardSchema = z.object({
name: z.string().describe("产品名称"),
price: z.number().describe("价格(美元)"),
imageUrl: z.string().optional().describe("产品图片 URL"),
onSale: z.boolean().optional().describe("产品是否在售"),
rating: z.number().optional().describe("评分(满分 5 分)"),
});
| TypeScript | Zod |
|---|---|
string | z.string() |
number | z.number() |
boolean | z.boolean() |
string[] | z.array(z.string()) |
| `"a" | "b"` |
optional | .optional() |
Date | z.string().describe("ISO 日期字符串") |
Record<K,V> | z.record(z.string(), z.number()) |
描述告诉 AI 何时渲染此组件。要具体:
// 差:太模糊
description: "显示一个产品";
// 好:告诉 AI 何时使用它
description: "显示一个包含名称、价格和可选图片/评分的产品。当用户要求查看产品详情、浏览商品或查看目录条目时使用。";
// lib/tambo.ts
import { TamboComponent } from "@tambo-ai/react";
import { ProductCard } from "@/components/ProductCard";
import { ProductCardSchema } from "@/components/ProductCard.schema";
export const components: TamboComponent[] = [
{
name: "ProductCard",
component: ProductCard,
description:
"显示一个包含名称、价格和可选图片/评分的产品。当用户要求查看产品详情、浏览商品或查看目录条目时使用。",
propsSchema: ProductCardSchema,
},
// ... 其他组件
];
当给定一个文件夹时,处理所有 .tsx 文件:
src/components/cards/
├── ProductCard.tsx → 注册为 "ProductCard"
├── UserCard.tsx → 注册为 "UserCard"
├── StatCard.tsx → 注册为 "StatCard"
└── index.ts → 跳过(桶文件)
跳过以下文件:
将模式文件放在组件旁边:
src/components/
├── ProductCard.tsx
├── ProductCard.schema.ts # Zod 模式
├── UserCard.tsx
└── UserCard.schema.ts
或者放在专用的模式文件夹中:
src/
├── components/
│ ├── ProductCard.tsx
│ └── UserCard.tsx
└── schemas/
├── ProductCard.schema.ts
└── UserCard.schema.ts
// TypeScript
interface Address {
street: string;
city: string;
zip: string;
}
interface Props {
address: Address;
}
// Zod
const AddressSchema = z.object({
street: z.string().describe("街道地址"),
city: z.string().describe("城市名称"),
zip: z.string().describe("邮政编码"),
});
const PropsSchema = z.object({
address: AddressSchema.describe("收货地址"),
});
不要在 propsSchema 中包含回调函数 - AI 无法提供函数:
// TypeScript
interface Props {
name: string;
onClick: () => void; // 跳过此项
}
// Zod - 仅数据属性
const PropsSchema = z.object({
name: z.string().describe("显示名称"),
// onClick 省略 - AI 提供数据,而非行为
});
不要包含子元素 - AI 渲染组件,但不组合它:
// 在模式中跳过 children 属性
注册后,在聊天中验证:
"给我看一个价格为 999 美元的笔记本电脑产品卡片"
AI 应该使用适当的属性渲染 ProductCard。
每周安装量
106
代码仓库
GitHub 星标数
11.1K
首次出现
2026 年 2 月 5 日
安全审计
安装于
gemini-cli103
opencode103
codex102
github-copilot100
amp97
kimi-cli97
Convert existing React components into Tambo-registered components that AI can render.
# Point to a component file or folder
/add-components-to-registry src/components/ProductCard.tsx
/add-components-to-registry src/components/cards/
Read the component file and extract:
// src/components/ProductCard.tsx
interface ProductCardProps {
name: string;
price: number;
imageUrl?: string;
onSale?: boolean;
rating?: number;
}
export function ProductCard({
name,
price,
imageUrl,
onSale,
rating,
}: ProductCardProps) {
return (
<div className="product-card">
{imageUrl && <img src={imageUrl} alt={name} />}
<h3>{name}</h3>
<p>
${price}
{onSale && " (On Sale!)"}
</p>
{rating && <span>★ {rating}/5</span>}
</div>
);
}
Convert TypeScript types to Zod with .describe():
import { z } from "zod";
export const ProductCardSchema = z.object({
name: z.string().describe("Product name"),
price: z.number().describe("Price in dollars"),
imageUrl: z.string().optional().describe("Product image URL"),
onSale: z.boolean().optional().describe("Whether product is on sale"),
rating: z.number().optional().describe("Rating out of 5"),
});
| TypeScript | Zod |
|---|---|
string | z.string() |
number | z.number() |
boolean | z.boolean() |
string[] | z.array(z.string()) |
The description tells AI when to render this component. Be specific:
// Bad: Too vague
description: "Shows a product";
// Good: Tells AI when to use it
description: "Displays a product with name, price, and optional image/rating. Use when user asks to see product details, browse items, or view catalog entries.";
// lib/tambo.ts
import { TamboComponent } from "@tambo-ai/react";
import { ProductCard } from "@/components/ProductCard";
import { ProductCardSchema } from "@/components/ProductCard.schema";
export const components: TamboComponent[] = [
{
name: "ProductCard",
component: ProductCard,
description:
"Displays a product with name, price, and optional image/rating. Use when user asks to see product details, browse items, or view catalog entries.",
propsSchema: ProductCardSchema,
},
// ... other components
];
When given a folder, process all .tsx files:
src/components/cards/
├── ProductCard.tsx → Register as "ProductCard"
├── UserCard.tsx → Register as "UserCard"
├── StatCard.tsx → Register as "StatCard"
└── index.ts → Skip (barrel file)
Skip files that:
Place schemas next to components:
src/components/
├── ProductCard.tsx
├── ProductCard.schema.ts # Zod schema
├── UserCard.tsx
└── UserCard.schema.ts
Or in a dedicated schemas folder:
src/
├── components/
│ ├── ProductCard.tsx
│ └── UserCard.tsx
└── schemas/
├── ProductCard.schema.ts
└── UserCard.schema.ts
// TypeScript
interface Address {
street: string;
city: string;
zip: string;
}
interface Props {
address: Address;
}
// Zod
const AddressSchema = z.object({
street: z.string().describe("Street address"),
city: z.string().describe("City name"),
zip: z.string().describe("ZIP/postal code"),
});
const PropsSchema = z.object({
address: AddressSchema.describe("Shipping address"),
});
Don't include callbacks in propsSchema - AI can't provide functions:
// TypeScript
interface Props {
name: string;
onClick: () => void; // Skip this
}
// Zod - only data props
const PropsSchema = z.object({
name: z.string().describe("Display name"),
// onClick omitted - AI provides data, not behavior
});
Don't include children - AI renders the component, doesn't compose it:
// Skip children prop in schema
After registration, verify in the chat:
"Show me a product card for a laptop priced at $999"
AI should render the ProductCard with appropriate props.
Weekly Installs
106
Repository
GitHub Stars
11.1K
First Seen
Feb 5, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli103
opencode103
codex102
github-copilot100
amp97
kimi-cli97
AI Elements:基于shadcn/ui的AI原生应用组件库,快速构建对话界面
67,500 周安装
| `"a" | "b"` |
optional | .optional() |
Date | z.string().describe("ISO date string") |
Record<K,V> | z.record(z.string(), z.number()) |