YYayaw

Component Catalog

Internal UI component inventory, preview rules, and V2 registry contract.

Overview

Yayaw includes an internal component catalog at:

  • /dashboard/content/components

The catalog supports a mixed inventory:

  • local components from src/components/ui/*
  • imported components stored in DB snapshots (non-executable)

Related docs:

CMS Role

The component catalog is the CMS rendering inventory. It documents and previews the low-level UI pieces that sections can use, including local components and imported source snapshots. Components are not authored content by themselves; they are the safe rendering primitives used by reusable sections and direct page references.

Keep component imports non-executable, compile them into validated recipes, and publish only entries that pass compile and smoke-render checks.

Goals:

  • list UI components from src/components/ui
  • list imported UI components from DB revisions
  • preview compatible components with live props controls
  • show source files used by each entry
  • validate token-aware rendering with the current runtime design tokens

Scope and Conventions

Local source of truth remains explicit: src/components/ui/catalog/registry.ts.

Current scope:

  • top-level files in src/components/ui/*.tsx
  • key entries for src/components/ui/kibo-ui/*/index.tsx
  • key entry for src/components/ui/yayaw-table/index.ts
  • imported entries from DB (ui_component_registry_items) merged into the same inventory

Conventions:

  • one catalog entry per key component
  • one key component per folder for nested component directories
  • target entrypoint is index.tsx for nested folders (legacy exceptions are explicit in the registry)
  • imported entries are global-scope registry items with source snapshots only
  • collision rule is deterministic: imported > local for the same slug/id

Preview Model

Preview behavior is recipe-driven and shared with runtime rendering:

  • src/lib/server/services/components/ui-component-recipe-compiler.ts
  • src/components/ui/catalog/ui-recipe-renderer-server.tsx
  • src/components/ui/catalog/ui-recipe-renderer-client.tsx

Flow:

  1. Source snapshot is compiled to UiComponentRecipeV1.
  2. Catalog preview renders the recipe with generated controls from propSchema, apiSchema, and harnessSchema.
  3. Block runtime resolves published recipe revisions and uses the same renderer path.

Runtime-only preview policy:

  • catalog preview always uses the internal recipe renderer
  • no external docs iframe is embedded in the preview panel
  • preview parity checks happen through variant tabs when multiple libraries expose the same component key

Publication gating:

  • compiled + smoke render OK => published (auto-publication for imports/recompile)
  • otherwise => draft_blocked

Soft delete:

  • imported components are removed from catalog with publication status deleted
  • source snapshots remain in DB for audit/replay

AI SDK Integration

AI-driven compile fallback and classification now use Vercel AI SDK:

  • src/lib/server/services/components/ui-component-ai-client.ts
  • src/lib/server/services/components/ui-component-recipe-ai-fallback.ts
  • src/lib/server/services/components/ui-component-import-classifier.ts

Rules:

  • all AI outputs are validated with strict zod schemas
  • model usage follows a built-in resilient fallback chain; page/block builders can still request a preferred model from UI controls
  • deterministic fallback is always available if AI is unavailable
  • no AI failure blocks import or compile pipelines

Library and Category Classification

Imported components are classified with a hybrid strategy:

  1. cache by sourceHash (reuse previous classification metadata)
  2. deterministic heuristics (library + group)
  3. AI SDK enrichment (library/category refinement)

Metadata persisted on registry rows:

  • library
  • group
  • classificationSource
  • classificationVersion
  • classificationModel (when AI is used)

Category policy:

  • normalized to lowercase kebab-case
  • new categories are accepted automatically after normalization

Library policy:

  • controlled values: shadcn-ui, kibo-ui, yayaw, ai-sdk, custom

AI Elements Vendored Components

AI Elements is vendored under a dedicated namespace:

  • src/components/ui/ai-elements/*
  • catalog local registry ids use ai-elements-* to avoid collisions with core shadcn ids

Install/update script:

  • bun run components:install-ai-elements

Script behavior:

  • resolves @ai-elements registry index
  • installs each registry item into src/components/ui/ai-elements
  • skips existing files by default (--all to reinstall every item)
  • regenerates src/components/ui/ai-elements/index.ts
  • regenerates deterministic composite preview overrides in src/lib/server/services/components/ui-component-ai-elements-preview-overrides.generated.ts
  • continues on per-item failure and reports a summary

Catalog behavior:

  • vendored AI Elements files are listed in src/components/ui/catalog/registry.ts
  • they are tagged as library ai-sdk
  • unknown AI Elements families compile to composite recipes by default to keep previews available
  • local ai-elements-* composite recipes are enriched by deterministic overrides generated from source snapshots (components:generate-ai-elements-previews)
  • imported AI Elements items automatically use ai-elements-* slug prefix when their base slug would collide with an existing local catalog id
  • when multiple libraries expose the same canonical component key, preview tabs let users switch variants and display whether their normalized sources are identical or different
  • the dashboard loads only catalog summaries first; the selected variant's recipe and source are loaded on demand so opening the Components page does not compile or transfer every component preview

Unified Entries and Variant Tabs

The inventory is grouped by logical component key, not by raw registry id.

Rules:

  • one inventory row per canonical component key
  • each row can expose multiple library variants (tabs in preview)
  • selecting a library filter keeps a row visible when it has at least one variant from that library
  • selecting a category filter keeps a row visible when at least one variant matches that category

Canonical Key Grouping Rules

Canonical key resolution is defined in:

  • src/components/ui/catalog/catalog-identity.ts

Current normalization:

  • ai-elements-* ids are grouped under their stripped base key
  • all other ids keep their original value as canonical key

Library variant order is deterministic:

  • shadcn-ui
  • ai-sdk
  • kibo-ui
  • yayaw
  • custom

Import Flows and Registry Sync

V2 supports component management from the catalog UI for users with components:manage.

Supported add flows:

  • shadcn command input
  • full registry alias sync import (defaults to onlyNew=true)
  • source snapshot paste (name, sourceFile, sourceSnapshot)
  • MCP source snapshot import through yayaw_component_import

Registry sync action:

  • syncRegistryAliasComponents(registryAlias, { onlyNew: true })

Non-blocking policy for new library releases:

  • registry discovery uses index payload candidates (index.json and registry.json)
  • items not yet vendored locally can still be imported through DB snapshot pipeline
  • allowlist validation remains enforced for source domains

MCP component tools expose the same DB-backed catalog boundary:

  • yayaw_components_list and yayaw_component_get inspect component inventory
  • yayaw_component_import stores and compiles a source snapshot
  • yayaw_component_recompile recompiles a stored snapshot
  • yayaw_component_publish publishes a compiled smoke-renderable revision
  • yayaw_component_delete soft-deletes an imported entry

These tools do not mutate repository-local source files in production. If an agent needs to add or modify first-party React component files, that is a code change and should happen through a branch and pull request.

Block Planner Usage Hints

The block AI planner consumes catalog usage hints when available:

  • short example snippet from CLI/persisted context
  • key registry dependencies
  • docs/examples links

This metadata is read-only and passed in prompt payload to improve component and prop selection in generated block trees. It does not execute any DB source code.

CLI-First Context Enrichment

Imports now resolve context from the official shadcn CLI first, then apply deterministic fallbacks.

Implementation points:

  • src/lib/server/actions/components/component-registry-actions.ts
  • src/lib/server/services/components/ui-component-shadcn-cli-context.ts
  • src/lib/server/services/components/shadcn-cli-runner.ts
  • src/lib/server/services/components/ui-component-recipe-import-enrichment.ts
  • src/lib/server/services/components/ui-component-import-preview-evidence.ts

Behavior:

  • CLI runner is local-first (bunx shadcn) with npx -y shadcn@latest fallback, timeout, retry, and structured logs
  • resolver aggregates:
    • shadcn view payload metadata/files
    • shadcn docs --json links for core shadcn components
    • shadcn search + shadcn view for registry example blocks
  • resolved context includes:
    • sourceTitle / sourceDescription
    • exampleSnippets
    • registryDependencies
    • docs links (docs, examples)
    • interaction hint (click-trigger, selection, or inline fallback)
  • preview evidence priority is deterministic: CLI -> payload -> web -> source snapshot
  • context is cached in import metadata by sourceHash (contextVersion, links, snippets, dependencies), so repeated imports avoid repeated CLI calls
  • when CLI context is unavailable, import remains non-blocking and compile/publish gating behavior is unchanged
  • no external source code is executed; only metadata and snapshots are parsed

Interaction-first policy:

  • overlay-like previews should prefer explicit click triggers over always-open states
  • composite AI blueprints are neutral by default (no AI/chat-specific microcopy unless source evidence explicitly requires it)

Design Token Behavior

The catalog preview does not rely only on baseline CSS.

It resolves effective runtime tokens for the current session (global + organization overrides) and applies scoped CSS variables to the preview surface. This lets dashboard users validate UI components against the same semantic token values used at runtime.

Validation

Registry consistency is validated by tests:

  • unique entry ids
  • source file existence
  • demoId references resolved by the demo map

Runtime/catalog guards:

  • no DB code execution (source snapshots are never evaluated)
  • publication blocked when compile diagnostics or smoke render fails

Useful commands:

bun test src/components/ui/catalog/registry.test.ts
bun test src/lib/server/services/components/ui-component-recipe-compiler.test.ts
bun test src/lib/server/services/components/ui-component-catalog-query.test.ts
bun run components:generate-ai-elements-previews

Environment Variables

  • OPENAI_API_KEY
  • OPENAI_COMPONENTS_AI_FALLBACK

These OpenAI variables are optional and only affect AI SDK enrichment for imported components. Local AI Elements preview overrides are fully deterministic and do not require OPENAI_API_KEY.

Contract Direction

  • global product scope
  • source snapshot storage for audit/replay
  • no runtime execution of DB-stored code

Reference type:

  • UiComponentRegistryItemV1 in src/components/ui/catalog/types.ts

DB tables:

  • ui_component_registry_items
  • ui_component_recipe_revisions
  • ui_component_publications