/** * The Foundry app-UI component catalog (startsim app-builder). * * A curated, machine-readable index of the @startsimpli/ui building blocks a * Foundry tenant app can use on its home / sections — the surface the AI app * builder reads to decide what to compose, and the source of truth for how each * gets scaffolded into a tenant's forked repo. * * This module is PURE DATA (no React imports) so it's cheap to pull into an LLM * route or a Node scaffolder without dragging component code. The heavy, curated * catalog is deliberately SMALL — the ~dozen blocks that make sense in a * data-driven tenant app, not the ~300 exports of the kit. The AI is told to * reach past it only when asked. */ /** * How a block is used in a tenant app: * - `widget`: a home-dashboard block, referenced by `kind` in foundry.dashboard.ts. * - `view`: a full section/page for one entity type (board, table, calendar…). * - `component`: an app-shell/embeddable primitive (command palette, chat…). */ export type CatalogCategory = 'widget' | 'view' | 'component'; export interface CatalogEntry { /** Stable id. For widgets this IS the foundry.dashboard.ts `kind`. */ id: string; category: CatalogCategory; /** Human title shown to the owner. */ title: string; /** What it is + when to reach for it — written for the AI builder to reason over. */ description: string; /** * The schema shape this block wants, in one plain phrase (e.g. "a type with a * status/enum field", "a type with a date field"). The AI only offers a block * when the tenant's live schema satisfies this. */ dataNeeds: string; /** * Pulls a big transitive dependency (calendar, kanban dnd, xlsx, gantt). The AI * is instructed to avoid heavy blocks unless the user explicitly asks — this is * how "don't just throw every component in" is enforced at the catalog level. */ heavy?: boolean; /** * Already shipped in the base template's widget registry — configuring it needs * only a foundry.dashboard.ts entry (no new files). Absent = must be scaffolded * into the fork on demand (keeps the base template thin). */ builtIn?: boolean; /** Where the underlying component comes from, for a scaffolded wrapper's import. */ source: { export: string; from: string }; /** * An example foundry.dashboard.ts entry for this block, so the AI emits valid * config. `kind` matches `id` for widgets. */ configExample?: Record; } /** A block plus the concrete files to add to a fork to enable it (scaffolding). */ export interface ScaffoldFile { /** Repo-relative path within the tenant fork, e.g. src/components/dashboard/calendar-widget.tsx */ path: string; /** Full file contents. */ content: string; }