/** * Foundry app-UI catalog — public surface. * * Import from `@startsimpli/ui/catalog` (a pure-data subpath; no component code). * The AI app builder uses `renderCatalogForPrompt()` to "see" what it can build; * `getCatalogEntry`/`UI_CATALOG` back the scaffolder and any component picker UI. */ export { UI_CATALOG } from './catalog'; export type { CatalogEntry, CatalogCategory, ScaffoldFile } from './types'; export { renderDashboardConfig, widgetsNeedingScaffold, type DashboardWidgetConfig, type RenderResult, } from './scaffold'; import { UI_CATALOG } from './catalog'; import type { CatalogCategory, CatalogEntry } from './types'; /** Look up one block by id (the foundry.dashboard.ts `kind` for widgets). */ export function getCatalogEntry(id: string): CatalogEntry | undefined { return UI_CATALOG.find((e) => e.id === id); } /** All blocks in a category. */ export function catalogByCategory(category: CatalogCategory): CatalogEntry[] { return UI_CATALOG.filter((e) => e.category === category); } /** The blocks the base template already ships (config-only, no scaffolding). */ export function builtInWidgets(): CatalogEntry[] { return UI_CATALOG.filter((e) => e.builtIn); } /** * A compact, token-frugal rendering of the catalog for an LLM system prompt: one * line per block — id, category, a ⚠ heavy marker, what it needs, and the gist. * Deterministic (catalog order) so prompts stay cache-stable. */ export function renderCatalogForPrompt(): string { const line = (e: CatalogEntry) => { const flags = [e.builtIn ? 'built-in' : 'scaffolded', e.heavy ? '⚠ heavy' : null] .filter(Boolean) .join(', '); return `- ${e.id} (${e.category}${flags ? `; ${flags}` : ''}) — ${e.title}: ${e.description} Needs: ${e.dataNeeds}`; }; return UI_CATALOG.map(line).join('\n'); }