add-components-to-registry
npx machina-cli add skill andrmaz/spec-driven-architecture/add-components-to-registry --openclawAdd Components to Registry
Convert existing React components into Tambo-registered components that AI can render.
Quick Start
# Point to a component file or folder
/add-components-to-registry src/components/ProductCard.tsx
/add-components-to-registry src/components/cards/
Workflow
- Read component(s) - Analyze props, types, and purpose
- Generate Zod schema - Create propsSchema from prop types
- Write description - Help AI know when to use it
- Add to registry - Update lib/tambo.ts
Step 1: Analyze Component
Read the component file and extract:
- Component name
- Props interface/type
- What it renders (for description)
- Optional vs required props
Example Input
// 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>
);
}
Step 2: Generate Zod Schema
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"),
});
Type Mapping
| TypeScript | Zod |
|---|---|
string | z.string() |
number | z.number() |
boolean | z.boolean() |
string[] | z.array(z.string()) |
"a" | "b" | z.enum(["a", "b"]) |
optional | .optional() |
Date | z.string().describe("ISO date string") |
Record<K,V> | z.record(z.string(), z.number()) |
Step 3: Write Description
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.";
Step 4: Add to Registry
// 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
];
Batch Registration
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:
- Are barrel exports (index.ts)
- Don't export React components
- Are test files (_.test.tsx, _.spec.tsx)
- Are story files (*.stories.tsx)
Schema File Location
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
Handling Complex Props
Nested Objects
// 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"),
});
Callbacks (Skip)
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
});
Children (Skip)
Don't include children - AI renders the component, doesn't compose it:
// Skip children prop in schema
Verification
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.
Source
git clone https://github.com/andrmaz/spec-driven-architecture/blob/develop/.agents/skills/add-components-to-registry/SKILL.mdView on GitHub Overview
This skill lets you expose existing React components to Tambo by converting them into registry-ready components. It analyzes each component’s props, generates a Zod schema, and writes a usage description, then updates lib/tambo.ts so AI can render the components. It also supports batch registration from a folder for scalable projects.
How This Skill Works
The tool reads the component file to extract the name, props, and render intent; it generates a Zod schema based on prop types and optional/required flags; it writes a precise description of when to use the component and then adds an entry to the Tambo registry in lib/tambo.ts. When given a folder, it processes all .tsx files and registers each component.
When to Use It
- You want to expose an existing React component so AI can render it in conversations or demos
- You are building generative UI and need ready-to-use components accessible to AI
- You need to convert React components to Tambo components for AI compatibility
- You want to batch register a folder of components (e.g., a components/cards folder)
- You are setting up a project and need a clearer component registry via lib/tambo.ts
Quick Start
- Step 1: Point to a component file or folder (e.g., /src/components/ProductCard.tsx)
- Step 2: Run /add-components-to-registry src/components/ProductCard.tsx or the folder path
- Step 3: Verify the new entry appears in lib/tambo.ts and test rendering
Best Practices
- Thoroughly analyze props to distinguish required vs optional
- Create accurate Zod schemas with .describe() notes for each prop
- Write a specific usage description that signals when to render this component
- Keep component names and registry entries in sync across files
- Test with a folder batch to ensure all components register correctly
Example Use Cases
- ProductCard.tsx registered with a ProductCardSchema and descriptive usage text
- UserCard.tsx registered from src/components/cards using batch registration
- StatCard.tsx registered in a cards folder with optional props
- Batch-register all cards in src/components/cards
- Gallery components registered for AI rendering in a generative UI flow