Get the FREE Ultimate OpenClaw Setup Guide →

add-components-to-registry

npx machina-cli add skill andrmaz/spec-driven-architecture/add-components-to-registry --openclaw
Files (1)
SKILL.md
5.6 KB

Add 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

  1. Read component(s) - Analyze props, types, and purpose
  2. Generate Zod schema - Create propsSchema from prop types
  3. Write description - Help AI know when to use it
  4. 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

TypeScriptZod
stringz.string()
numberz.number()
booleanz.boolean()
string[]z.array(z.string())
"a" | "b"z.enum(["a", "b"])
optional.optional()
Datez.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

  1. Step 1: Point to a component file or folder (e.g., /src/components/ProductCard.tsx)
  2. Step 2: Run /add-components-to-registry src/components/ProductCard.tsx or the folder path
  3. 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

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers