@cascivo/mcp 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,20 @@
1
1
  <!-- generated by scripts/readme/generate.ts — edit readme.body.md, not this file -->
2
2
 
3
- # @cascivo/mcp
3
+ <div align="center">
4
+ <a href="https://cascivo.com"><img src="https://cascivo.com/favicon.svg" width="72" height="72" alt="cascivo logo"></a>
5
+ <h1>@cascivo/mcp</h1>
6
+ <p><strong>MCP server exposing the cascivo component registry to AI agents</strong></p>
4
7
 
5
- > MCP server exposing the cascivo component registry to AI agents
8
+ [![npm](https://img.shields.io/npm/v/%40cascivo%2Fmcp?style=flat-square&color=0079bf)](https://www.npmjs.com/package/@cascivo/mcp)
9
+ [![downloads](https://img.shields.io/npm/dm/%40cascivo%2Fmcp?style=flat-square&color=0079bf)](https://www.npmjs.com/package/@cascivo/mcp)
10
+ [![license](https://img.shields.io/npm/l/%40cascivo%2Fmcp?style=flat-square&color=0079bf)](https://github.com/cascivo/cascivo/blob/main/LICENSE)
11
+ ![types](https://img.shields.io/badge/types-included-0079bf?style=flat-square&logo=typescript&logoColor=white)
6
12
 
7
- [cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/urbanisierung/cascivo)
13
+ [npm](https://www.npmjs.com/package/@cascivo/mcp) · [cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/cascivo/cascivo)
14
+
15
+ </div>
16
+
17
+ ---
8
18
 
9
19
  ## Usage
10
20
 
@@ -79,4 +89,6 @@ pnpm add @cascivo/mcp
79
89
 
80
90
  ---
81
91
 
82
- [cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/urbanisierung/cascivo) · AI agents: use [`@cascivo/mcp`](https://github.com/urbanisierung/cascivo/tree/main/packages/mcp) and [`registry.json`](https://github.com/urbanisierung/cascivo/blob/main/registry.json) · MIT
92
+ [cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/cascivo/cascivo) · AI agents: use [`@cascivo/mcp`](https://github.com/cascivo/cascivo/tree/main/packages/mcp) and [`registry.json`](https://github.com/cascivo/cascivo/blob/main/registry.json) · MIT
93
+
94
+ <div align="center"><a href="https://cascivo.com"><img src="https://cascivo.com/favicon.svg" width="28" height="28" alt="cascivo"></a></div>
package/dist/index.mjs CHANGED
@@ -436,7 +436,7 @@ function scaffoldView(input, registry) {
436
436
  const layout = pickLayout(input.description);
437
437
  const componentNames = pickComponents(input.description, registry, input.components);
438
438
  const config = {
439
- $schema: "https://raw.githubusercontent.com/urbanisierung/cascivo/main/packages/render/schema/view.v1.json",
439
+ $schema: "https://raw.githubusercontent.com/cascivo/cascivo/main/packages/render/schema/view.v1.json",
440
440
  version: 1,
441
441
  view: {
442
442
  ...layout !== "none" ? { layout } : {},
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["HERE","c","v","HERE"],"sources":["../src/registry.ts","../src/theme.ts","../src/scaffold.ts","../src/validate.ts","../src/grammar.ts","../src/scaffold-view.ts","../src/prompt.ts","../src/tokens.ts","../src/context.ts","../src/select.ts","../src/server.ts","../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface PropManifest {\n name: string\n type: string\n required: boolean\n default?: string\n description?: string\n}\n\nexport interface ComponentManifest {\n name: string\n description: string\n category: string\n states: string[]\n variants: string[]\n sizes: string[]\n props: PropManifest[]\n tokens: string[]\n accessibility: { role: string; wcag: string; keyboard: string[] }\n examples: { title: string; code: string; description?: string }[]\n dependencies: string[]\n tags: string[]\n}\n\nexport interface RegistryComponent {\n name: string\n type?: 'component' | 'layout' | 'block' | 'chart' | 'section'\n description: string\n category: string\n version: string\n files: string[]\n dependencies: string[]\n tags: string[]\n meta: ComponentManifest\n}\n\nexport interface Registry {\n version: string\n generatedAt: string\n components: RegistryComponent[]\n}\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\n\n/**\n * Resolve the registry.json location. Checks, in order: an explicit path, the\n * `CASCIVO_REGISTRY_PATH` env var, a copy bundled next to the built server\n * (published package), and the monorepo root (dev).\n */\nexport function resolveRegistryPath(explicit?: string): string {\n const candidates = [\n explicit,\n process.env.CASCIVO_REGISTRY_PATH,\n join(HERE, 'registry.json'),\n join(HERE, '..', '..', '..', 'registry.json'),\n join(HERE, '..', '..', 'registry.json'),\n ].filter((p): p is string => typeof p === 'string' && p.length > 0)\n\n return (\n candidates.find((p) => existsSync(p)) ?? candidates[candidates.length - 1] ?? 'registry.json'\n )\n}\n\nexport function loadRegistry(path?: string): Registry {\n const resolved = resolveRegistryPath(path)\n const raw = JSON.parse(readFileSync(resolved, 'utf8')) as Registry\n if (!Array.isArray(raw.components)) {\n throw new Error(`Invalid registry at ${resolved}: \"components\" must be an array`)\n }\n return raw\n}\n\n/** List component manifests, optionally filtered by category and/or type. */\nexport function listComponents(\n registry: Registry,\n category?: string,\n type?: string,\n): ComponentManifest[] {\n let entries = registry.components\n if (category) entries = entries.filter((c) => c.category === category)\n if (type) entries = entries.filter((c) => c.type === type)\n return entries.map((c) => c.meta)\n}\n\n/** Find one component manifest by name (matches registry name or meta name). */\nexport function getComponent(registry: Registry, name: string): ComponentManifest | undefined {\n const target = name.toLowerCase()\n return registry.components.find(\n (c) => c.name.toLowerCase() === target || c.meta.name.toLowerCase() === target,\n )?.meta\n}\n\n// ---------------------------------------------------------------------------\n// Multi-registry support\n// ---------------------------------------------------------------------------\n\nexport interface RegistryDirectoryEntry {\n namespace: string\n name: string\n description?: string\n registryUrl: string\n verified?: boolean\n homepage?: string\n}\n\nconst DIRECTORY_URL = 'https://cascivo.com/r/registries.json'\nconst FETCH_TIMEOUT_MS = 15_000\nconst MAX_BODY_BYTES = 1_048_576 // 1 MB\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nasync function fetchWithGuards(url: string, fetchFn: FetchFn = fetch): Promise<string | null> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS)\n try {\n const res = await fetchFn(url, { signal: controller.signal })\n if (!res.ok) return null\n const buf = await res.arrayBuffer()\n if (buf.byteLength > MAX_BODY_BYTES) return null\n return new TextDecoder().decode(buf)\n } catch {\n return null\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Fetch the central cascade registry directory. Returns empty array on failure. */\nexport async function fetchDirectory(fetchFn?: FetchFn): Promise<RegistryDirectoryEntry[]> {\n const raw = await fetchWithGuards(DIRECTORY_URL, fetchFn)\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed as RegistryDirectoryEntry[]\n } catch {\n return []\n }\n}\n\n/** Fetch the component index from a namespace's registryUrl. Returns null on failure. */\nexport async function fetchRegistryIndex(\n registryUrl: string,\n fetchFn?: FetchFn,\n): Promise<Registry | null> {\n // Resolve the registry.json URL: replace trailing `{name}` template or append /registry.json\n const indexUrl = registryUrl.includes('{name}')\n ? registryUrl.replace('{name}', 'registry').replace(/\\/registry$/, '/registry.json')\n : registryUrl.replace(/\\/?$/, '/registry.json').replace(/\\/\\/registry\\.json$/, '/registry.json')\n const raw = await fetchWithGuards(indexUrl, fetchFn)\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw) as Registry\n if (!Array.isArray(parsed.components)) return null\n return parsed\n } catch {\n return null\n }\n}\n\n/** Parse CASCADE_REGISTRIES env var — returns empty array on failure. */\nexport function getEnvRegistries(): RegistryDirectoryEntry[] {\n const raw = process.env['CASCADE_REGISTRIES']\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed as RegistryDirectoryEntry[]\n } catch {\n return []\n }\n}\n\n/** Merge directory entries with env entries (env wins on namespace collision). */\nexport function mergeRegistries(\n directory: RegistryDirectoryEntry[],\n env: RegistryDirectoryEntry[],\n): RegistryDirectoryEntry[] {\n const map = new Map<string, RegistryDirectoryEntry>()\n for (const entry of directory) map.set(entry.namespace, entry)\n for (const entry of env) map.set(entry.namespace, entry)\n return Array.from(map.values())\n}\n\n/** Fuzzy search over name, tags, and description. */\nexport function searchComponents(registry: Registry, query: string): ComponentManifest[] {\n const q = query.toLowerCase().trim()\n if (q === '') return []\n return registry.components\n .filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.description.toLowerCase().includes(q) ||\n c.tags.some((t) => t.toLowerCase().includes(q)),\n )\n .map((c) => c.meta)\n}\n","export interface ThemeColors {\n /** Main brand / interactive color (maps to the accent token family). */\n primary: string\n /** Base gray used to derive surfaces, borders, and text. */\n neutral: string\n /** Secondary highlight color (info / focus ring). */\n accent: string\n}\n\n/** Darken a color by mixing in black (modern CSS, no preprocessor). */\nfunction darken(color: string, amount: number): string {\n return `color-mix(in oklab, ${color}, black ${amount}%)`\n}\n\n/** Lighten a color by mixing in white. */\nfunction lighten(color: string, amount: number): string {\n return `color-mix(in oklab, ${color}, white ${amount}%)`\n}\n\n/**\n * Generate a custom cascivo theme as CSS. Maps the three input colors onto the\n * semantic token layer; component tokens inherit automatically.\n */\nexport function generateThemeCss(colors: ThemeColors, name = 'custom'): string {\n const { primary, neutral, accent } = colors\n return `/* cascivo — Generated theme: ${name} */\n\n@layer cascivo.theme {\n [data-theme='${name}'] {\n color-scheme: light;\n\n /* ── Surface (derived from neutral) ───────────────── */\n --cascivo-color-bg: ${lighten(neutral, 96)};\n --cascivo-color-bg-subtle: ${lighten(neutral, 92)};\n --cascivo-color-surface: ${lighten(neutral, 98)};\n --cascivo-color-surface-raised: ${lighten(neutral, 94)};\n --cascivo-color-surface-overlay: ${lighten(neutral, 98)};\n --cascivo-color-border: ${lighten(neutral, 80)};\n --cascivo-color-border-strong: ${lighten(neutral, 65)};\n\n /* ── Text (derived from neutral) ──────────────────── */\n --cascivo-color-text: ${darken(neutral, 80)};\n --cascivo-color-text-subtle: ${darken(neutral, 50)};\n --cascivo-color-text-muted: ${lighten(neutral, 30)};\n --cascivo-color-text-on-accent: #ffffff;\n --cascivo-color-text-on-destructive: #ffffff;\n\n /* ── Accent / primary interactive ─────────────────── */\n --cascivo-color-accent: ${primary};\n --cascivo-color-accent-hover: ${darken(primary, 12)};\n --cascivo-color-accent-active: ${darken(primary, 24)};\n --cascivo-color-accent-subtle: ${lighten(primary, 88)};\n --cascivo-color-accent-muted: ${lighten(primary, 76)};\n\n /* ── Secondary accent (info / focus) ──────────────── */\n --cascivo-color-info: ${accent};\n --cascivo-color-info-subtle: ${lighten(accent, 88)};\n --cascivo-color-focus-ring: ${accent};\n --cascivo-focus-ring: 0 0 0 3px ${lighten(accent, 20)};\n\n /* ── Status ───────────────────────────────────────── */\n --cascivo-color-destructive: #dc2626;\n --cascivo-color-destructive-hover: ${darken('#dc2626', 12)};\n --cascivo-color-destructive-subtle: ${lighten('#dc2626', 88)};\n --cascivo-color-success: #16a34a;\n --cascivo-color-success-subtle: ${lighten('#16a34a', 88)};\n --cascivo-color-warning: #f59e0b;\n --cascivo-color-warning-subtle: ${lighten('#f59e0b', 88)};\n }\n}\n`\n}\n","export interface ScaffoldOptions {\n description: string\n components?: string[]\n}\n\nconst DEFAULT_COMPONENTS = ['card', 'input', 'button']\n\nfunction pascalCase(name: string): string {\n return name\n .split(/[-_\\s]+/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n}\n\n/** A reasonable default usage snippet per component for the scaffold. */\nfunction usage(component: string, Tag: string): string {\n switch (component) {\n case 'button':\n return ` <${Tag}>Get started</${Tag}>`\n case 'input':\n return ` <${Tag} label=\"Email\" placeholder=\"you@example.com\" />`\n case 'card':\n return ` <${Tag}>\\n <h2>Card title</h2>\\n <p>Card content goes here.</p>\\n </${Tag}>`\n case 'badge':\n return ` <${Tag}>New</${Tag}>`\n default:\n return ` <${Tag} />`\n }\n}\n\n/**\n * Generate a JSX page layout string from a natural-language description and an\n * optional list of cascade components to include.\n */\nexport function scaffoldPage(options: ScaffoldOptions): string {\n const components = options.components?.length ? options.components : DEFAULT_COMPONENTS\n const unique = [...new Set(components.map((c) => c.toLowerCase()))]\n\n const imports = unique\n .map((c) => `import { ${pascalCase(c)} } from './components/ui/${c}/${c}'`)\n .join('\\n')\n\n const body = unique.map((c) => usage(c, pascalCase(c))).join('\\n')\n\n return `${imports}\n\n/* ${options.description} */\nexport function Page() {\n return (\n <main\n data-theme=\"light\"\n style={{ maxWidth: '48rem', margin: '0 auto', padding: '2rem', display: 'grid', gap: '1rem' }}\n >\n${body}\n </main>\n )\n}\n`\n}\n","// Inlined from @cascivo/render — avoids a Node.js binary depending on React components at runtime.\n// Component name validation uses the registry (passed by caller) instead of the React component map.\n\nexport interface ValidationError {\n path: string\n message: string\n}\n\nexport interface ComponentNode {\n component: string\n props?: Record<string, unknown>\n bind?: Record<string, string>\n events?: Record<string, string>\n children?: ComponentNode[] | string\n}\n\nexport interface ViewConfig {\n $schema?: string\n version?: 1\n view: {\n layout?: string\n regions: Record<string, ComponentNode[]>\n }\n}\n\nconst DATA_REF_RE = /^\\$data\\./\nconst ACTION_REF_RE = /^\\$actions\\./\n\nfunction closestName(name: string, candidates: string[]): string | undefined {\n const target = name.toLowerCase()\n let best: string | undefined\n let bestDist = 3\n for (const candidate of candidates) {\n const dist = levenshtein(target, candidate.toLowerCase())\n if (dist < bestDist) {\n bestDist = dist\n best = candidate\n }\n }\n return best\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n )\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i]![j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1]![j - 1]!\n : 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n return dp[m]![n]!\n}\n\nfunction validateNode(\n node: unknown,\n path: string,\n errors: ValidationError[],\n componentNames: Set<string>,\n): void {\n if (typeof node !== 'object' || node === null) {\n errors.push({ path, message: 'Expected a component node object' })\n return\n }\n const n = node as Record<string, unknown>\n if (typeof n['component'] !== 'string') {\n errors.push({ path: `${path}.component`, message: 'component must be a string' })\n return\n }\n const componentName = n['component'] as string\n if (!componentNames.has(componentName)) {\n const suggestion = closestName(componentName, [...componentNames])\n const hint = suggestion ? ` Did you mean \"${suggestion}\"?` : ''\n errors.push({\n path: `${path}.component`,\n message: `Unknown component \"${componentName}\".${hint}`,\n })\n return\n }\n\n const nodeBind = (n['bind'] ?? {}) as Record<string, string>\n for (const [key, value] of Object.entries(nodeBind)) {\n if (typeof value !== 'string' || !DATA_REF_RE.test(value)) {\n errors.push({\n path: `${path}.bind.${key}`,\n message: `bind values must start with \"$data.\" — got \"${value}\"`,\n })\n }\n }\n\n const nodeEvents = (n['events'] ?? {}) as Record<string, string>\n for (const [key, value] of Object.entries(nodeEvents)) {\n if (typeof value !== 'string' || !ACTION_REF_RE.test(value)) {\n errors.push({\n path: `${path}.events.${key}`,\n message: `events values must start with \"$actions.\" — got \"${value}\"`,\n })\n }\n }\n\n if (Array.isArray(n['children'])) {\n for (let i = 0; i < n['children'].length; i++) {\n validateNode(\n n['children'][i] as ComponentNode,\n `${path}.children[${i}]`,\n errors,\n componentNames,\n )\n }\n }\n}\n\n/** Validate a ViewConfig object. Component names are checked against the provided set. */\nexport function validateView(\n config: unknown,\n componentNames: Set<string>,\n): { valid: boolean; errors: ValidationError[] } {\n const errors: ValidationError[] = []\n\n if (typeof config !== 'object' || config === null) {\n return { valid: false, errors: [{ path: '', message: 'Config must be an object' }] }\n }\n\n const c = config as Record<string, unknown>\n const view = c['view']\n\n if (typeof view !== 'object' || view === null) {\n return { valid: false, errors: [{ path: 'view', message: 'view must be an object' }] }\n }\n\n const v = view as Record<string, unknown>\n const regions = v['regions']\n\n if (typeof regions !== 'object' || regions === null) {\n errors.push({ path: 'view.regions', message: 'view.regions must be an object' })\n return { valid: false, errors }\n }\n\n for (const [regionName, nodes] of Object.entries(regions as Record<string, unknown>)) {\n if (!Array.isArray(nodes)) {\n errors.push({\n path: `view.regions.${regionName}`,\n message: `Region \"${regionName}\" must be an array of component nodes`,\n })\n continue\n }\n for (let i = 0; i < nodes.length; i++) {\n validateNode(\n nodes[i] as ComponentNode,\n `view.regions.${regionName}[${i}]`,\n errors,\n componentNames,\n )\n }\n }\n\n return { valid: errors.length === 0, errors }\n}\n","// Library-derived bound vocabulary (v40 T1).\n//\n// OpenUI's anti-hallucination mechanism is a system prompt generated from the\n// component library so a model can only emit registered components/props. This\n// module derives that bound vocabulary from the cascade manifests\n// (component.meta.ts → registry.json): per component → its props (name, type,\n// allowed enum values, required) plus variants/sizes. Because it is *derived*,\n// it can never drift from the components (grammar.test.ts asserts every name it\n// references exists in the registry).\n\nimport type { Registry } from './registry.js'\n\nexport interface GrammarProp {\n name: string\n required: boolean\n /** Raw TypeScript type string from the manifest. */\n type: string\n /** Allowed values, when `type` is a string-literal union (e.g. `'sm' | 'md'`). */\n enum?: string[]\n}\n\nexport interface GrammarComponent {\n name: string\n category: string\n props: GrammarProp[]\n variants: string[]\n sizes: string[]\n}\n\nexport interface ViewGrammar {\n components: GrammarComponent[]\n}\n\n/**\n * Parse a string-literal union type (`'a' | 'b' | \"c\"`) into its allowed\n * values. Returns `undefined` for any non-enum type (primitives, functions,\n * named types, object shapes) so the grammar only constrains what it can.\n */\nexport function parseEnum(type: string): string[] | undefined {\n const branches = type\n .split('|')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n if (branches.length === 0) return undefined\n const values: string[] = []\n for (const branch of branches) {\n const quoted = branch.match(/^['\"](.+)['\"]$/)\n if (!quoted?.[1]) return undefined\n values.push(quoted[1])\n }\n return values\n}\n\n/**\n * Build the bound-vocabulary descriptor from the registry, optionally scoped to\n * a subset of component names (case-insensitive). Output is deterministic\n * (components and props sorted by name) for reproducible prompts and tests.\n */\n// Preference when two registry entries share a meta.name (e.g. a `component`\n// and a `layout` both named \"AppShell\"): the node-usable component wins.\nconst TYPE_RANK: Record<string, number> = {\n component: 0,\n block: 1,\n chart: 2,\n section: 3,\n layout: 4,\n}\n\nexport function buildGrammar(registry: Registry, subset?: string[]): ViewGrammar {\n const wanted = subset && subset.length > 0 ? new Set(subset.map((n) => n.toLowerCase())) : null\n\n // Dedupe by meta.name, keeping the highest-ranked (node-usable) entry.\n const canonical = new Map<string, (typeof registry.components)[number]>()\n for (const c of registry.components) {\n const key = c.meta.name.toLowerCase()\n const current = canonical.get(key)\n if (!current || (TYPE_RANK[c.type ?? ''] ?? 9) < (TYPE_RANK[current.type ?? ''] ?? 9)) {\n canonical.set(key, c)\n }\n }\n\n const components: GrammarComponent[] = [...canonical.values()]\n .filter(\n (c) => !wanted || wanted.has(c.meta.name.toLowerCase()) || wanted.has(c.name.toLowerCase()),\n )\n .map((c) => {\n const props: GrammarProp[] = (c.meta.props ?? [])\n .map((p) => {\n const values = parseEnum(p.type)\n return {\n name: p.name,\n required: p.required === true,\n type: p.type,\n ...(values ? { enum: values } : {}),\n }\n })\n .sort((a, b) => a.name.localeCompare(b.name))\n return {\n name: c.meta.name,\n category: c.category,\n props,\n variants: c.meta.variants ?? [],\n sizes: c.meta.sizes ?? [],\n }\n })\n .sort((a, b) => a.name.localeCompare(b.name))\n\n return { components }\n}\n\n/** Render one prop as `name`, `name*` (required), with enum choices or its type. */\nfunction formatProp(prop: GrammarProp): string {\n const mark = prop.required ? '*' : ''\n const value = prop.enum ? prop.enum.join('|') : prop.type\n return `${prop.name}${mark}: ${value}`\n}\n\n/**\n * Render the grammar as a compact, model-friendly table: one line per\n * component. Terser than verbose JSON; a `*` marks a required prop.\n *\n * Badge(size: sm|md, variant: default|secondary|success|warning|destructive|outline)\n */\nexport function formatGrammar(grammar: ViewGrammar): string {\n return grammar.components\n .map((c) => `${c.name}(${c.props.map(formatProp).join(', ')})`)\n .join('\\n')\n}\n","import type { ViewConfig } from './validate.js'\nimport { validateView } from './validate.js'\nimport type { Registry } from './registry.js'\nimport { buildGrammar, formatGrammar } from './grammar.js'\n\ninterface ScaffoldViewInput {\n description: string\n components?: string[]\n}\n\n/** Simple keyword matcher — returns region layout name based on description keywords. */\nfunction pickLayout(description: string): string {\n const d = description.toLowerCase()\n if (d.includes('dashboard') || d.includes('stats') || d.includes('kpi')) return 'dashboard'\n if (d.includes('settings') || d.includes('preferences') || d.includes('config')) return 'settings'\n if (d.includes('login') || d.includes('auth') || d.includes('sign')) return 'auth'\n return 'none'\n}\n\n/** Pick sensible components from the registry matching keywords in description. */\nfunction pickComponents(description: string, registry: Registry, explicit?: string[]): string[] {\n if (explicit && explicit.length > 0) return explicit.map((c) => c.toLowerCase())\n const d = description.toLowerCase()\n const candidates: string[] = []\n for (const entry of registry.components) {\n const name = entry.meta.name.toLowerCase()\n const tags = entry.tags.join(' ').toLowerCase()\n if (d.includes(name) || tags.split(' ').some((t) => d.includes(t))) {\n candidates.push(entry.meta.name)\n }\n }\n // Always add at least one component\n if (candidates.length === 0) candidates.push('Badge')\n return candidates.slice(0, 4)\n}\n\nfunction makeNode(\n componentName: string,\n registry: Registry,\n): { component: string; props?: Record<string, string | number | boolean> } {\n const entry = registry.components.find(\n (c) => c.meta.name.toLowerCase() === componentName.toLowerCase(),\n )\n if (!entry) return { component: componentName }\n const props: Record<string, string | number | boolean> = {}\n for (const prop of entry.meta.props ?? []) {\n if (prop.required && prop.default !== undefined) {\n props[prop.name] = prop.default\n } else if (\n prop.default !== undefined &&\n ['string', 'number', 'boolean'].includes(typeof prop.default)\n ) {\n // Skip defaults that are complex\n }\n }\n return Object.keys(props).length > 0\n ? { component: entry.meta.name, props }\n : { component: entry.meta.name }\n}\n\nexport function scaffoldView(\n input: ScaffoldViewInput,\n registry: Registry,\n): {\n config: ViewConfig\n errors: { path: string; message: string }[]\n /** Bound-vocabulary grammar (v40 T1) for the scaffolded components, so a caller gets both a starter scaffold and the allowed props/enums to refine it. */\n grammar: string\n} {\n const layout = pickLayout(input.description)\n const componentNames = pickComponents(input.description, registry, input.components)\n\n const config: ViewConfig = {\n $schema:\n 'https://raw.githubusercontent.com/urbanisierung/cascivo/main/packages/render/schema/view.v1.json',\n version: 1,\n view: {\n ...(layout !== 'none' ? { layout } : {}),\n regions: {\n main: componentNames.map((name) => makeNode(name, registry)),\n },\n },\n }\n\n const validNames = new Set(registry.components.map((c) => c.meta.name))\n const { errors } = validateView(config, validNames)\n const grammar = formatGrammar(buildGrammar(registry, componentNames))\n return { config, errors, grammar }\n}\n","// Generation prompt derived from the bound vocabulary (v40 T1).\n//\n// Composes the system prompt an LLM needs to emit valid `ViewConfig` JSON that\n// is restricted to cascivo's real components, props, and enum values — the\n// OpenUI \"system prompt from the component library\" anti-hallucination\n// mechanism, applied to the format cascivo already ships and dogfoods\n// (@cascivo/render). See docs/ROADMAP-V40.md.\n\nimport { buildGrammar, formatGrammar } from './grammar.js'\nimport type { Registry } from './registry.js'\n\nexport interface GenerationPromptOptions {\n /** Scope the vocabulary to a subset of component names. Defaults to all. */\n components?: string[]\n}\n\nconst SCHEMA_DOC = `A ViewConfig is a JSON object:\n\n{\n \"version\": 1,\n \"view\": {\n \"layout\": \"<optional layout name, e.g. dashboard | settings | auth>\",\n \"regions\": {\n \"<regionName>\": [ <ComponentNode>, ... ]\n }\n }\n}\n\nA ComponentNode is:\n\n{\n \"component\": \"<one of the registered component names below>\",\n \"props\": { \"<propName>\": <value> },\n \"bind\": { \"<propName>\": \"$data.<path>\" },\n \"events\": { \"<eventPropName>\": \"$actions.<name>\" },\n \"children\": <ComponentNode[] | string | { \"$t\": \"<i18n.key>\" }>\n}\n\nRules:\n- \"component\" MUST be one of the registered components listed below — never invent one.\n- Only use props listed for that component; enum props MUST use one of the listed values.\n- \"bind\" values are host-data references and MUST start with \"$data.\".\n- \"events\" values are host-action references and MUST start with \"$actions.\".\n- \"children\" is an array of nodes, a plain string, or an i18n ref { \"$t\": \"key\" }.\n- Output ONLY the JSON ViewConfig — no prose, no markdown fences.`\n\n/**\n * Build the bound-vocabulary system prompt for emitting `ViewConfig` JSON.\n * Parameterizable by an optional component subset (defaults to the full\n * registry).\n */\nexport function buildGenerationPrompt(\n registry: Registry,\n options: GenerationPromptOptions = {},\n): string {\n const grammar = buildGrammar(registry, options.components)\n const vocabulary = formatGrammar(grammar)\n\n const sections = [\n 'You generate UI as a cascivo ViewConfig — a JSON description rendered by @cascivo/render <CascadeView />.',\n SCHEMA_DOC,\n 'Registered components (allowed vocabulary — `name*` marks a required prop):',\n vocabulary,\n // EXTENSION POINT (v40 T3, optional): when the `cvl` compact DSL ships, append a\n // \"cvl syntax\" section here so an agent can be asked to emit cvl instead of JSON.\n ]\n\n return sections.join('\\n\\n')\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface TokenCatalogEntry {\n name: string\n value: string\n layer: 'primitive' | 'semantic' | 'component'\n group: string\n resolvedDefault: string | null\n resolvesPerTheme: boolean\n}\n\nexport interface TokenCatalog {\n generatedAt: string\n count: number\n tokens: TokenCatalogEntry[]\n}\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\nconst CATALOG_BASE_URL = 'https://cascivo.com'\n\nexport async function loadTokenCatalog(fetchFn?: FetchFn): Promise<TokenCatalog> {\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'tokens.catalog.json'),\n join(HERE, 'tokens.catalog.json'),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return JSON.parse(readFileSync(p, 'utf8')) as TokenCatalog\n }\n const url = `${CATALOG_BASE_URL}/tokens.catalog.json`\n const fn = fetchFn ?? fetch\n const res = await fn(url)\n if (!res.ok) throw new Error(`Failed to fetch token catalog: ${res.status}`)\n return res.json() as Promise<TokenCatalog>\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface ContextRelated {\n name: string\n relationship: string\n reason: string\n}\n\nexport interface ContextAntiPattern {\n bad: string\n good: string\n why: string\n}\n\nexport interface ContextFlexibility {\n area: string\n level: string\n note: string\n}\n\nexport interface ComponentIntent {\n whenToUse: string[]\n whenNotToUse: string[]\n antiPatterns: ContextAntiPattern[]\n related: ContextRelated[]\n a11yRationale?: string\n flexibility?: ContextFlexibility[]\n}\n\nexport interface ContextComponent {\n name: string\n category: string\n description: string\n intent: ComponentIntent\n contextUrl: string\n}\n\nexport interface ContextBundle {\n generatedAt: string\n tagline: string\n authoringRules: string[]\n tokenCatalogUrl: string\n components: ContextComponent[]\n}\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\nconst CONTEXT_BASE_URL = 'https://cascivo.com'\n\nexport async function loadContext(fetchFn?: FetchFn): Promise<ContextBundle> {\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'context.json'),\n join(HERE, 'context.json'),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return JSON.parse(readFileSync(p, 'utf8')) as ContextBundle\n }\n const url = `${CONTEXT_BASE_URL}/context.json`\n const fn = fetchFn ?? fetch\n const res = await fn(url)\n if (!res.ok) throw new Error(`Failed to fetch context bundle: ${res.status}`)\n return res.json() as Promise<ContextBundle>\n}\n\nexport async function loadComponentMarkdown(\n name: string,\n fetchFn?: FetchFn,\n): Promise<string | null> {\n const slug = name.toLowerCase().replace(/\\s+/g, '-')\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'context', `${slug}.md`),\n join(HERE, 'context', `${slug}.md`),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return readFileSync(p, 'utf8')\n }\n const url = `${CONTEXT_BASE_URL}/context/${slug}.md`\n const fn = fetchFn ?? fetch\n try {\n const res = await fn(url)\n if (!res.ok) return null\n return res.text()\n } catch {\n return null\n }\n}\n","import type { ContextComponent } from './context.js'\n\nexport interface SelectRelated {\n name: string\n relationship: string\n reason: string\n}\n\nexport interface SelectResult {\n name: string\n score: number\n why: string\n /** When NOT to use this pick — lets an agent disqualify a wrong match. */\n whenNotToUse: string[]\n /** Related components (alternatives, pairs-with) to consider instead/alongside. */\n related: SelectRelated[]\n}\n\n// Minimum length for a need word to be scored (filters out articles, prepositions, etc.)\nconst MIN_WORD_LEN = 3\n\nfunction words(text: string): string[] {\n return (text.toLowerCase().match(/\\b\\w+\\b/g) ?? []).filter((w) => w.length >= MIN_WORD_LEN)\n}\n\nfunction countMatches(needWords: string[], text: string): string[] {\n const lower = text.toLowerCase()\n return needWords.filter((w) => lower.includes(w))\n}\n\nexport function selectComponent(need: string, components: ContextComponent[]): SelectResult[] {\n const needWords = words(need)\n if (needWords.length === 0) return []\n\n const scored = components.map((c) => {\n const whenToUseText = c.intent.whenToUse.join(' ')\n const whenNotToUseText = c.intent.whenNotToUse.join(' ')\n\n const whenToUseMatches = countMatches(needWords, whenToUseText)\n const descMatches = countMatches(needWords, c.description)\n const penaltyMatches = countMatches(needWords, whenNotToUseText)\n\n const score = whenToUseMatches.length * 2 + descMatches.length - penaltyMatches.length * 3\n\n // Build why from the best-matching whenToUse sentence\n let why = ''\n if (whenToUseMatches.length > 0) {\n const bestSentence = c.intent.whenToUse\n .map((s) => ({ s, count: countMatches(needWords, s).length }))\n .filter((x) => x.count > 0)\n .sort((a, b) => b.count - a.count)[0]?.s\n why = bestSentence\n ? `Matched: ${whenToUseMatches.map((w) => `'${w}'`).join(', ')} in whenToUse — \"${bestSentence}\"`\n : `Matched: ${whenToUseMatches.map((w) => `'${w}'`).join(', ')} in description`\n } else if (descMatches.length > 0) {\n why = `Matched: ${descMatches.map((w) => `'${w}'`).join(', ')} in description`\n }\n\n return {\n name: c.name,\n score,\n why,\n whenNotToUse: c.intent.whenNotToUse ?? [],\n related: c.intent.related ?? [],\n }\n })\n\n // First pass: top 3 by score for related bonus\n const top3Names = new Set(\n [...scored]\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, 3)\n .map((r) => r.name),\n )\n\n // Apply related bonus: +1 if a top-3 component points at this component\n const relatedBonus = new Map<string, number>()\n for (const r of scored) {\n if (!top3Names.has(r.name)) continue\n for (const rel of r.related) {\n relatedBonus.set(rel.name, (relatedBonus.get(rel.name) ?? 0) + 1)\n }\n }\n\n const final = scored.map((r) => ({\n name: r.name,\n score: r.score + (relatedBonus.get(r.name) ?? 0),\n why: r.why,\n whenNotToUse: r.whenNotToUse,\n related: r.related,\n }))\n\n return final\n .filter((r) => r.score >= 0)\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, 5)\n}\n","import { spawnSync } from 'node:child_process'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport {\n fetchDirectory,\n fetchRegistryIndex,\n getComponent,\n getEnvRegistries,\n listComponents,\n loadRegistry,\n mergeRegistries,\n searchComponents,\n type Registry,\n} from './registry.js'\nimport { generateThemeCss } from './theme.js'\nimport { scaffoldPage } from './scaffold.js'\nimport { validateView } from './validate.js'\nimport { scaffoldView } from './scaffold-view.js'\nimport { buildGrammar, formatGrammar } from './grammar.js'\nimport { buildGenerationPrompt } from './prompt.js'\nimport { loadTokenCatalog } from './tokens.js'\nimport { loadContext, loadComponentMarkdown } from './context.js'\nimport { selectComponent } from './select.js'\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nexport interface ServerOptions {\n registryPath?: string\n version?: string\n /** Injectable fetch function — used for testing multi-registry features. */\n fetchFn?: FetchFn\n}\n\nconst json = (value: unknown) => ({\n content: [{ type: 'text' as const, text: JSON.stringify(value, null, 2) }],\n})\n\nconst text = (value: string) => ({ content: [{ type: 'text' as const, text: value }] })\n\nconst error = (message: string) => ({\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n})\n\n/** Build a configured McpServer exposing the cascade component registry. */\nexport function createServer(options: ServerOptions = {}): McpServer {\n const registry: Registry = loadRegistry(options.registryPath)\n const fetchFn = options.fetchFn\n\n const server = new McpServer({\n name: '@cascivo/mcp',\n version: options.version ?? '0.0.0',\n })\n\n server.registerTool(\n 'list_registries',\n {\n title: 'List registries',\n description:\n 'List available component registries: the cascade directory plus any configured via CASCADE_REGISTRIES env.',\n inputSchema: {},\n },\n async () => {\n const directory = await fetchDirectory(fetchFn)\n const env = getEnvRegistries()\n const entries = mergeRegistries(directory, env)\n return json(\n entries.map(({ namespace, name, description, verified, homepage }) => ({\n namespace,\n name,\n description,\n verified: verified ?? false,\n homepage,\n })),\n )\n },\n )\n\n server.registerTool(\n 'list_components',\n {\n title: 'List components',\n description: 'List all cascade components, optionally filtered by category and/or type.',\n inputSchema: {\n category: z\n .enum(['inputs', 'display', 'overlay', 'navigation', 'feedback', 'chart'])\n .optional()\n .describe('Filter by component category'),\n type: z\n .enum(['component', 'layout', 'block', 'chart'])\n .optional()\n .describe('Filter by entry type'),\n },\n },\n ({ category, type }) => json(listComponents(registry, category, type)),\n )\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component',\n description:\n 'Get the full manifest (props, states, tokens, a11y, examples) for one component.',\n inputSchema: {\n name: z.string().describe('Component name, e.g. \"button\"'),\n registry: z\n .string()\n .optional()\n .describe('Namespace of an external registry, e.g. \"@myns\". Omit for the default.'),\n },\n },\n async ({ name, registry: ns }) => {\n if (ns) {\n const env = getEnvRegistries()\n const directory = await fetchDirectory(fetchFn)\n const entries = mergeRegistries(directory, env)\n const entry = entries.find((e) => e.namespace === ns)\n if (!entry) return error(`Registry \"${ns}\" not found.`)\n const remoteRegistry = await fetchRegistryIndex(entry.registryUrl, fetchFn)\n if (!remoteRegistry) return error(`Failed to fetch registry index for \"${ns}\".`)\n const meta = getComponent(remoteRegistry, name)\n return meta ? json(meta) : error(`Component \"${name}\" not found in registry \"${ns}\".`)\n }\n const meta = getComponent(registry, name)\n return meta ? json(meta) : error(`Component \"${name}\" not found.`)\n },\n )\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search components',\n description: 'Fuzzy search components by name, tags, or description.',\n inputSchema: {\n query: z.string().describe('Search query'),\n registry: z\n .string()\n .optional()\n .describe('Namespace of an external registry, e.g. \"@myns\". Omit for the default.'),\n },\n },\n async ({ query, registry: ns }) => {\n if (ns) {\n const env = getEnvRegistries()\n const directory = await fetchDirectory(fetchFn)\n const entries = mergeRegistries(directory, env)\n const entry = entries.find((e) => e.namespace === ns)\n if (!entry) return error(`Registry \"${ns}\" not found.`)\n const remoteRegistry = await fetchRegistryIndex(entry.registryUrl, fetchFn)\n if (!remoteRegistry) return error(`Failed to fetch registry index for \"${ns}\".`)\n return json(searchComponents(remoteRegistry, query))\n }\n return json(searchComponents(registry, query))\n },\n )\n\n server.registerTool(\n 'add_to_project',\n {\n title: 'Add to project',\n description: 'Add a component to the current project by running the cascade CLI.',\n inputSchema: {\n name: z.string().describe('Component name to add'),\n outputDir: z.string().optional().describe('Directory to write the component into'),\n },\n },\n ({ name, outputDir }) => {\n const env = outputDir ? { ...process.env, CASCIVO_OUTPUT_DIR: outputDir } : process.env\n const result = spawnSync('npx', ['-y', 'cascivo', 'add', name], { encoding: 'utf8', env })\n if (result.status !== 0) {\n return error(result.stderr || result.error?.message || `Failed to add \"${name}\".`)\n }\n return text(result.stdout || `Added ${name}.`)\n },\n )\n\n server.registerTool(\n 'create_theme',\n {\n title: 'Create theme',\n description: 'Generate a cascade theme CSS file from three colors.',\n inputSchema: {\n primary: z.string().describe('Primary / interactive color (any CSS color)'),\n neutral: z.string().describe('Base neutral color for surfaces and text'),\n accent: z.string().describe('Secondary accent color (info / focus)'),\n name: z.string().optional().describe('Theme name (default: \"custom\")'),\n },\n },\n ({ primary, neutral, accent, name }) =>\n text(generateThemeCss({ primary, neutral, accent }, name)),\n )\n\n server.registerTool(\n 'scaffold_page',\n {\n title: 'Scaffold page (deprecated)',\n description:\n '[Deprecated — use scaffold_view instead] Generate a JSX page layout from a description.',\n inputSchema: {\n description: z.string().describe('What the page is for'),\n components: z.array(z.string()).optional().describe('Components to include'),\n },\n },\n ({ description, components }) => {\n const { config } = scaffoldView(\n { description, ...(components ? { components } : {}) },\n registry,\n )\n return text(\n `[Deprecated] Use scaffold_view for config-first output. JSX scaffold:\\n\\n${scaffoldPage(components ? { description, components } : { description })}\\n\\n--- scaffold_view output ---\\n${JSON.stringify(config, null, 2)}`,\n )\n },\n )\n\n server.registerTool(\n 'validate_view',\n {\n title: 'Validate view config',\n description:\n 'Validate a CascadeView JSON config against the registry. Returns errors with exact paths.',\n inputSchema: {\n config: z.record(z.string(), z.unknown()).describe('The ViewConfig object to validate'),\n },\n },\n ({ config }) => {\n const componentNames = new Set(registry.components.map((c) => c.meta.name))\n const result = validateView(config, componentNames)\n return json(result)\n },\n )\n\n server.registerTool(\n 'scaffold_view',\n {\n title: 'Scaffold view config',\n description:\n 'Generate a valid starter ViewConfig from a description. Always validates before returning.',\n inputSchema: {\n description: z.string().describe('What the page/view is for'),\n components: z.array(z.string()).optional().describe('Component names to include'),\n },\n },\n ({ description, components }) => {\n const { config, errors, grammar } = scaffoldView(\n { description, ...(components ? { components } : {}) },\n registry,\n )\n if (errors.length > 0) {\n return json({ valid: false, errors, config, grammar })\n }\n return json({ valid: true, config, grammar })\n },\n )\n\n server.registerTool(\n 'get_view_grammar',\n {\n title: 'Get view grammar',\n description:\n \"Get the bound-vocabulary grammar + system prompt for generating valid ViewConfig JSON, derived from the component manifests. Use this to constrain an LLM to cascivo's real components, props, and enum values (anti-hallucination). Optionally scope to a subset of components.\",\n inputSchema: {\n components: z\n .array(z.string())\n .optional()\n .describe('Scope the vocabulary to these component names. Omit for the full registry.'),\n },\n },\n ({ components }) => {\n const grammar = buildGrammar(registry, components)\n return json({\n grammar: formatGrammar(grammar),\n prompt: buildGenerationPrompt(registry, components ? { components } : {}),\n components: grammar.components,\n })\n },\n )\n\n server.registerTool(\n 'get_tokens',\n {\n title: 'Get tokens',\n description:\n 'Get the cascade token catalog (closed set). Agents must select from this catalog rather than hard-coding values.',\n inputSchema: {\n group: z\n .string()\n .optional()\n .describe('Filter by token group, e.g. \"color\", \"space\", \"radius\"'),\n layer: z\n .enum(['primitive', 'semantic', 'component'])\n .optional()\n .describe('Filter by layer'),\n },\n },\n async ({ group, layer }) => {\n try {\n const catalog = await loadTokenCatalog(fetchFn)\n let tokens = catalog.tokens\n if (group) tokens = tokens.filter((t) => t.group === group)\n if (layer) tokens = tokens.filter((t) => t.layer === layer)\n return json({ count: tokens.length, tokens })\n } catch (e) {\n return error(`Token catalog unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n server.registerTool(\n 'get_context',\n {\n title: 'Get context',\n description:\n 'Get intent, whenToUse/whenNotToUse, and authoring guidance for one component by name.',\n inputSchema: {\n name: z.string().describe('Component name, e.g. \"Toast\"'),\n },\n },\n async ({ name }) => {\n try {\n const ctx = await loadContext(fetchFn)\n const target = name.toLowerCase()\n const component = ctx.components.find((c) => c.name.toLowerCase() === target)\n if (!component) {\n const available = ctx.components.map((c) => c.name).join(', ')\n return error(`Component \"${name}\" not found. Available: ${available}`)\n }\n const md = await loadComponentMarkdown(component.name, fetchFn)\n return json({\n name: component.name,\n category: component.category,\n description: component.description,\n intent: component.intent,\n contextUrl: component.contextUrl,\n ...(md ? { markdown: md } : {}),\n })\n } catch (e) {\n return error(`Context bundle unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n server.registerTool(\n 'select_component',\n {\n title: 'Select component',\n description:\n 'Heuristic ranking of cascade components by natural language need. Returns top matches with scores and reasons. Note: heuristic ranking, not a model call.',\n inputSchema: {\n need: z.string().describe('Natural language description of what the component should do'),\n },\n },\n async ({ need }) => {\n try {\n const ctx = await loadContext(fetchFn)\n const results = selectComponent(need, ctx.components)\n return json({\n note: 'Heuristic ranking — not a model call. Verify with get_context before using.',\n results,\n })\n } catch (e) {\n return error(`Context bundle unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n return server\n}\n","import { argv } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nexport const VERSION = '0.0.0'\n\nexport { createServer } from './server.js'\nexport type { ServerOptions } from './server.js'\nexport { generateThemeCss, type ThemeColors } from './theme.js'\nexport { scaffoldPage, type ScaffoldOptions } from './scaffold.js'\nexport {\n buildGrammar,\n formatGrammar,\n parseEnum,\n type GrammarComponent,\n type GrammarProp,\n type ViewGrammar,\n} from './grammar.js'\nexport { buildGenerationPrompt, type GenerationPromptOptions } from './prompt.js'\nexport {\n getComponent,\n listComponents,\n loadRegistry,\n searchComponents,\n type ComponentManifest,\n type Registry,\n type RegistryComponent,\n} from './registry.js'\n\n/** Start the MCP server over stdio. */\nexport async function main(): Promise<void> {\n const server = createServer({ version: VERSION })\n await server.connect(new StdioServerTransport())\n}\n\nconst isMain = argv[1] !== undefined && import.meta.url === pathToFileURL(argv[1]).href\n\nif (isMain) {\n main().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err))\n process.exitCode = 1\n })\n}\n"],"mappings":";;;;;;;;;AA6CA,MAAMA,SAAO,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;;;;;;AAOnD,SAAgB,oBAAoB,UAA2B;CAC7D,MAAM,aAAa;EACjB;EACA,QAAQ,IAAI;EACZ,KAAKA,QAAM,eAAe;EAC1B,KAAKA,QAAM,MAAM,MAAM,MAAM,eAAe;EAC5C,KAAKA,QAAM,MAAM,MAAM,eAAe;CACxC,CAAC,CAAC,QAAQ,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS,CAAC;CAElE,OACE,WAAW,MAAM,MAAM,WAAW,CAAC,CAAC,KAAK,WAAW,WAAW,SAAS,MAAM;AAElF;AAEA,SAAgB,aAAa,MAAyB;CACpD,MAAM,WAAW,oBAAoB,IAAI;CACzC,MAAM,MAAM,KAAK,MAAM,aAAa,UAAU,MAAM,CAAC;CACrD,IAAI,CAAC,MAAM,QAAQ,IAAI,UAAU,GAC/B,MAAM,IAAI,MAAM,uBAAuB,SAAS,gCAAgC;CAElF,OAAO;AACT;;AAGA,SAAgB,eACd,UACA,UACA,MACqB;CACrB,IAAI,UAAU,SAAS;CACvB,IAAI,UAAU,UAAU,QAAQ,QAAQ,MAAM,EAAE,aAAa,QAAQ;CACrE,IAAI,MAAM,UAAU,QAAQ,QAAQ,MAAM,EAAE,SAAS,IAAI;CACzD,OAAO,QAAQ,KAAK,MAAM,EAAE,IAAI;AAClC;;AAGA,SAAgB,aAAa,UAAoB,MAA6C;CAC5F,MAAM,SAAS,KAAK,YAAY;CAChC,OAAO,SAAS,WAAW,MACxB,MAAM,EAAE,KAAK,YAAY,MAAM,UAAU,EAAE,KAAK,KAAK,YAAY,MAAM,MAC1E,CAAC,EAAE;AACL;AAeA,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AACzB,MAAM,iBAAiB;AAIvB,eAAe,gBAAgB,KAAa,UAAmB,OAA+B;CAC5F,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,gBAAgB;CACnE,IAAI;EACF,MAAM,MAAM,MAAM,QAAQ,KAAK,EAAE,QAAQ,WAAW,OAAO,CAAC;EAC5D,IAAI,CAAC,IAAI,IAAI,OAAO;EACpB,MAAM,MAAM,MAAM,IAAI,YAAY;EAClC,IAAI,IAAI,aAAa,gBAAgB,OAAO;EAC5C,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG;CACrC,QAAQ;EACN,OAAO;CACT,UAAU;EACR,aAAa,KAAK;CACpB;AACF;;AAGA,eAAsB,eAAe,SAAsD;CACzF,MAAM,MAAM,MAAM,gBAAgB,eAAe,OAAO;CACxD,IAAI,CAAC,KAAK,OAAO,CAAC;CAClB,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;EACpC,OAAO;CACT,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;AAGA,eAAsB,mBACpB,aACA,SAC0B;CAK1B,MAAM,MAAM,MAAM,gBAHD,YAAY,SAAS,QAAQ,IAC1C,YAAY,QAAQ,UAAU,UAAU,CAAC,CAAC,QAAQ,eAAe,gBAAgB,IACjF,YAAY,QAAQ,QAAQ,gBAAgB,CAAC,CAAC,QAAQ,uBAAuB,gBAAgB,GACrD,OAAO;CACnD,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,CAAC,MAAM,QAAQ,OAAO,UAAU,GAAG,OAAO;EAC9C,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF;;AAGA,SAAgB,mBAA6C;CAC3D,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,CAAC,KAAK,OAAO,CAAC;CAClB,IAAI;EACF,MAAM,SAAS,KAAK,MAAM,GAAG;EAC7B,IAAI,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC;EACpC,OAAO;CACT,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;AAGA,SAAgB,gBACd,WACA,KAC0B;CAC1B,MAAM,sBAAM,IAAI,IAAoC;CACpD,KAAK,MAAM,SAAS,WAAW,IAAI,IAAI,MAAM,WAAW,KAAK;CAC7D,KAAK,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM,WAAW,KAAK;CACvD,OAAO,MAAM,KAAK,IAAI,OAAO,CAAC;AAChC;;AAGA,SAAgB,iBAAiB,UAAoB,OAAoC;CACvF,MAAM,IAAI,MAAM,YAAY,CAAC,CAAC,KAAK;CACnC,IAAI,MAAM,IAAI,OAAO,CAAC;CACtB,OAAO,SAAS,WACb,QACE,MACC,EAAE,KAAK,YAAY,CAAC,CAAC,SAAS,CAAC,KAC/B,EAAE,YAAY,YAAY,CAAC,CAAC,SAAS,CAAC,KACtC,EAAE,KAAK,MAAM,MAAM,EAAE,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,CAClD,CAAC,CACA,KAAK,MAAM,EAAE,IAAI;AACtB;;;;AC7LA,SAAS,OAAO,OAAe,QAAwB;CACrD,OAAO,uBAAuB,MAAM,UAAU,OAAO;AACvD;;AAGA,SAAS,QAAQ,OAAe,QAAwB;CACtD,OAAO,uBAAuB,MAAM,UAAU,OAAO;AACvD;;;;;AAMA,SAAgB,iBAAiB,QAAqB,OAAO,UAAkB;CAC7E,MAAM,EAAE,SAAS,SAAS,WAAW;CACrC,OAAO,iCAAiC,KAAK;;;iBAG9B,KAAK;;;;0BAII,QAAQ,SAAS,EAAE,EAAE;iCACd,QAAQ,SAAS,EAAE,EAAE;+BACvB,QAAQ,SAAS,EAAE,EAAE;sCACd,QAAQ,SAAS,EAAE,EAAE;uCACpB,QAAQ,SAAS,EAAE,EAAE;8BAC9B,QAAQ,SAAS,EAAE,EAAE;qCACd,QAAQ,SAAS,EAAE,EAAE;;;4BAG9B,OAAO,SAAS,EAAE,EAAE;mCACb,OAAO,SAAS,EAAE,EAAE;kCACrB,QAAQ,SAAS,EAAE,EAAE;;;;;8BAKzB,QAAQ;oCACF,OAAO,SAAS,EAAE,EAAE;qCACnB,OAAO,SAAS,EAAE,EAAE;qCACpB,QAAQ,SAAS,EAAE,EAAE;oCACtB,QAAQ,SAAS,EAAE,EAAE;;;4BAG7B,OAAO;mCACA,QAAQ,QAAQ,EAAE,EAAE;kCACrB,OAAO;sCACH,QAAQ,QAAQ,EAAE,EAAE;;;;yCAIjB,OAAO,WAAW,EAAE,EAAE;0CACrB,QAAQ,WAAW,EAAE,EAAE;;sCAE3B,QAAQ,WAAW,EAAE,EAAE;;sCAEvB,QAAQ,WAAW,EAAE,EAAE;;;;AAI7D;;;AClEA,MAAM,qBAAqB;CAAC;CAAQ;CAAS;AAAQ;AAErD,SAAS,WAAW,MAAsB;CACxC,OAAO,KACJ,MAAM,SAAS,CAAC,CAChB,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAC3D,KAAK,EAAE;AACZ;;AAGA,SAAS,MAAM,WAAmB,KAAqB;CACrD,QAAQ,WAAR;EACE,KAAK,UACH,OAAO,UAAU,IAAI,gBAAgB,IAAI;EAC3C,KAAK,SACH,OAAO,UAAU,IAAI;EACvB,KAAK,QACH,OAAO,UAAU,IAAI,kFAAkF,IAAI;EAC7G,KAAK,SACH,OAAO,UAAU,IAAI,QAAQ,IAAI;EACnC,SACE,OAAO,UAAU,IAAI;CACzB;AACF;;;;;AAMA,SAAgB,aAAa,SAAkC;CAC7D,MAAM,aAAa,QAAQ,YAAY,SAAS,QAAQ,aAAa;CACrE,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,WAAW,KAAK,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;CAElE,MAAM,UAAU,OACb,KAAK,MAAM,YAAY,WAAW,CAAC,EAAE,2BAA2B,EAAE,GAAG,EAAE,EAAE,CAAC,CAC1E,KAAK,IAAI;CAEZ,MAAM,OAAO,OAAO,KAAK,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;CAEjE,OAAO,GAAG,QAAQ;;KAEf,QAAQ,YAAY;;;;;;;EAOvB,KAAK;;;;;AAKP;;;ACjCA,MAAM,cAAc;AACpB,MAAM,gBAAgB;AAEtB,SAAS,YAAY,MAAc,YAA0C;CAC3E,MAAM,SAAS,KAAK,YAAY;CAChC,IAAI;CACJ,IAAI,WAAW;CACf,KAAK,MAAM,aAAa,YAAY;EAClC,MAAM,OAAO,YAAY,QAAQ,UAAU,YAAY,CAAC;EACxD,IAAI,OAAO,UAAU;GACnB,WAAW;GACX,OAAO;EACT;CACF;CACA,OAAO;AACT;AAEA,SAAS,YAAY,GAAW,GAAmB;CACjD,MAAM,IAAI,EAAE;CACZ,MAAM,IAAI,EAAE;CACZ,MAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MACvD,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,CAAE,CACzE;CACA,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KACtB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KACtB,GAAG,EAAE,CAAE,KACL,EAAE,IAAI,OAAO,EAAE,IAAI,KACf,GAAG,IAAI,EAAE,CAAE,IAAI,KACf,IAAI,KAAK,IAAI,GAAG,IAAI,EAAE,CAAE,IAAK,GAAG,EAAE,CAAE,IAAI,IAAK,GAAG,IAAI,EAAE,CAAE,IAAI,EAAG;CAGzE,OAAO,GAAG,EAAE,CAAE;AAChB;AAEA,SAAS,aACP,MACA,MACA,QACA,gBACM;CACN,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;EAC7C,OAAO,KAAK;GAAE;GAAM,SAAS;EAAmC,CAAC;EACjE;CACF;CACA,MAAM,IAAI;CACV,IAAI,OAAO,EAAE,iBAAiB,UAAU;EACtC,OAAO,KAAK;GAAE,MAAM,GAAG,KAAK;GAAa,SAAS;EAA6B,CAAC;EAChF;CACF;CACA,MAAM,gBAAgB,EAAE;CACxB,IAAI,CAAC,eAAe,IAAI,aAAa,GAAG;EACtC,MAAM,aAAa,YAAY,eAAe,CAAC,GAAG,cAAc,CAAC;EACjE,MAAM,OAAO,aAAa,kBAAkB,WAAW,MAAM;EAC7D,OAAO,KAAK;GACV,MAAM,GAAG,KAAK;GACd,SAAS,sBAAsB,cAAc,IAAI;EACnD,CAAC;EACD;CACF;CAEA,MAAM,WAAY,EAAE,WAAW,CAAC;CAChC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,IAAI,OAAO,UAAU,YAAY,CAAC,YAAY,KAAK,KAAK,GACtD,OAAO,KAAK;EACV,MAAM,GAAG,KAAK,QAAQ;EACtB,SAAS,+CAA+C,MAAM;CAChE,CAAC;CAIL,MAAM,aAAc,EAAE,aAAa,CAAC;CACpC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,UAAU,GAClD,IAAI,OAAO,UAAU,YAAY,CAAC,cAAc,KAAK,KAAK,GACxD,OAAO,KAAK;EACV,MAAM,GAAG,KAAK,UAAU;EACxB,SAAS,oDAAoD,MAAM;CACrE,CAAC;CAIL,IAAI,MAAM,QAAQ,EAAE,WAAW,GAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,WAAW,CAAC,QAAQ,KACxC,aACE,EAAE,WAAW,CAAC,IACd,GAAG,KAAK,YAAY,EAAE,IACtB,QACA,cACF;AAGN;;AAGA,SAAgB,aACd,QACA,gBAC+C;CAC/C,MAAM,SAA4B,CAAC;CAEnC,IAAI,OAAO,WAAW,YAAY,WAAW,MAC3C,OAAO;EAAE,OAAO;EAAO,QAAQ,CAAC;GAAE,MAAM;GAAI,SAAS;EAA2B,CAAC;CAAE;CAIrF,MAAM,OAAOC,OAAE;CAEf,IAAI,OAAO,SAAS,YAAY,SAAS,MACvC,OAAO;EAAE,OAAO;EAAO,QAAQ,CAAC;GAAE,MAAM;GAAQ,SAAS;EAAyB,CAAC;CAAE;CAIvF,MAAM,UAAUC,KAAE;CAElB,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;EACnD,OAAO,KAAK;GAAE,MAAM;GAAgB,SAAS;EAAiC,CAAC;EAC/E,OAAO;GAAE,OAAO;GAAO;EAAO;CAChC;CAEA,KAAK,MAAM,CAAC,YAAY,UAAU,OAAO,QAAQ,OAAkC,GAAG;EACpF,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;GACzB,OAAO,KAAK;IACV,MAAM,gBAAgB;IACtB,SAAS,WAAW,WAAW;GACjC,CAAC;GACD;EACF;EACA,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAChC,aACE,MAAM,IACN,gBAAgB,WAAW,GAAG,EAAE,IAChC,QACA,cACF;CAEJ;CAEA,OAAO;EAAE,OAAO,OAAO,WAAW;EAAG;CAAO;AAC9C;;;;;;;;AC5HA,SAAgB,UAAU,MAAoC;CAC5D,MAAM,WAAW,KACd,MAAM,GAAG,CAAC,CACV,KAAK,MAAM,EAAE,KAAK,CAAC,CAAC,CACpB,QAAQ,MAAM,EAAE,SAAS,CAAC;CAC7B,IAAI,SAAS,WAAW,GAAG,OAAO,KAAA;CAClC,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,UAAU,UAAU;EAC7B,MAAM,SAAS,OAAO,MAAM,gBAAgB;EAC5C,IAAI,CAAC,SAAS,IAAI,OAAO,KAAA;EACzB,OAAO,KAAK,OAAO,EAAE;CACvB;CACA,OAAO;AACT;;;;;;AASA,MAAM,YAAoC;CACxC,WAAW;CACX,OAAO;CACP,OAAO;CACP,SAAS;CACT,QAAQ;AACV;AAEA,SAAgB,aAAa,UAAoB,QAAgC;CAC/E,MAAM,SAAS,UAAU,OAAO,SAAS,IAAI,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,YAAY,CAAC,CAAC,IAAI;CAG3F,MAAM,4BAAY,IAAI,IAAkD;CACxE,KAAK,MAAM,KAAK,SAAS,YAAY;EACnC,MAAM,MAAM,EAAE,KAAK,KAAK,YAAY;EACpC,MAAM,UAAU,UAAU,IAAI,GAAG;EACjC,IAAI,CAAC,YAAY,UAAU,EAAE,QAAQ,OAAO,MAAM,UAAU,QAAQ,QAAQ,OAAO,IACjF,UAAU,IAAI,KAAK,CAAC;CAExB;CA4BA,OAAO,EAAE,YA1B8B,CAAC,GAAG,UAAU,OAAO,CAAC,CAAC,CAC3D,QACE,MAAM,CAAC,UAAU,OAAO,IAAI,EAAE,KAAK,KAAK,YAAY,CAAC,KAAK,OAAO,IAAI,EAAE,KAAK,YAAY,CAAC,CAC5F,CAAC,CACA,KAAK,MAAM;EACV,MAAM,SAAwB,EAAE,KAAK,SAAS,CAAC,EAAA,CAC5C,KAAK,MAAM;GACV,MAAM,SAAS,UAAU,EAAE,IAAI;GAC/B,OAAO;IACL,MAAM,EAAE;IACR,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE;IACR,GAAI,SAAS,EAAE,MAAM,OAAO,IAAI,CAAC;GACnC;EACF,CAAC,CAAC,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;EAC9C,OAAO;GACL,MAAM,EAAE,KAAK;GACb,UAAU,EAAE;GACZ;GACA,UAAU,EAAE,KAAK,YAAY,CAAC;GAC9B,OAAO,EAAE,KAAK,SAAS,CAAC;EAC1B;CACF,CAAC,CAAC,CACD,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAE3B,EAAE;AACtB;;AAGA,SAAS,WAAW,MAA2B;CAC7C,MAAM,OAAO,KAAK,WAAW,MAAM;CACnC,MAAM,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,GAAG,IAAI,KAAK;CACrD,OAAO,GAAG,KAAK,OAAO,KAAK,IAAI;AACjC;;;;;;;AAQA,SAAgB,cAAc,SAA8B;CAC1D,OAAO,QAAQ,WACZ,KAAK,MAAM,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,IAAI,UAAU,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAC9D,KAAK,IAAI;AACd;;;;ACpHA,SAAS,WAAW,aAA6B;CAC/C,MAAM,IAAI,YAAY,YAAY;CAClC,IAAI,EAAE,SAAS,WAAW,KAAK,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS,KAAK,GAAG,OAAO;CAChF,IAAI,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,aAAa,KAAK,EAAE,SAAS,QAAQ,GAAG,OAAO;CACxF,IAAI,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,MAAM,GAAG,OAAO;CAC5E,OAAO;AACT;;AAGA,SAAS,eAAe,aAAqB,UAAoB,UAA+B;CAC9F,IAAI,YAAY,SAAS,SAAS,GAAG,OAAO,SAAS,KAAK,MAAM,EAAE,YAAY,CAAC;CAC/E,MAAM,IAAI,YAAY,YAAY;CAClC,MAAM,aAAuB,CAAC;CAC9B,KAAK,MAAM,SAAS,SAAS,YAAY;EACvC,MAAM,OAAO,MAAM,KAAK,KAAK,YAAY;EACzC,MAAM,OAAO,MAAM,KAAK,KAAK,GAAG,CAAC,CAAC,YAAY;EAC9C,IAAI,EAAE,SAAS,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,SAAS,CAAC,CAAC,GAC/D,WAAW,KAAK,MAAM,KAAK,IAAI;CAEnC;CAEA,IAAI,WAAW,WAAW,GAAG,WAAW,KAAK,OAAO;CACpD,OAAO,WAAW,MAAM,GAAG,CAAC;AAC9B;AAEA,SAAS,SACP,eACA,UAC0E;CAC1E,MAAM,QAAQ,SAAS,WAAW,MAC/B,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY,CACjE;CACA,IAAI,CAAC,OAAO,OAAO,EAAE,WAAW,cAAc;CAC9C,MAAM,QAAmD,CAAC;CAC1D,KAAK,MAAM,QAAQ,MAAM,KAAK,SAAS,CAAC,GACtC,IAAI,KAAK,YAAY,KAAK,YAAY,KAAA,GACpC,MAAM,KAAK,QAAQ,KAAK;MACnB,IACL,KAAK,YAAY,KAAA,KACjB;EAAC;EAAU;EAAU;CAAS,CAAC,CAAC,SAAS,OAAO,KAAK,OAAO,GAC5D,CAEF;CAEF,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,SAAS,IAC/B;EAAE,WAAW,MAAM,KAAK;EAAM;CAAM,IACpC,EAAE,WAAW,MAAM,KAAK,KAAK;AACnC;AAEA,SAAgB,aACd,OACA,UAMA;CACA,MAAM,SAAS,WAAW,MAAM,WAAW;CAC3C,MAAM,iBAAiB,eAAe,MAAM,aAAa,UAAU,MAAM,UAAU;CAEnF,MAAM,SAAqB;EACzB,SACE;EACF,SAAS;EACT,MAAM;GACJ,GAAI,WAAW,SAAS,EAAE,OAAO,IAAI,CAAC;GACtC,SAAS,EACP,MAAM,eAAe,KAAK,SAAS,SAAS,MAAM,QAAQ,CAAC,EAC7D;EACF;CACF;CAGA,MAAM,EAAE,WAAW,aAAa,QAAQ,IADjB,IAAI,SAAS,WAAW,KAAK,MAAM,EAAE,KAAK,IAAI,CACpB,CAAC;CAElD,OAAO;EAAE;EAAQ;EAAQ,SADT,cAAc,aAAa,UAAU,cAAc,CACpC;CAAE;AACnC;;;ACxEA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCnB,SAAgB,sBACd,UACA,UAAmC,CAAC,GAC5B;CAaR,OAAO;EARL;EACA;EACA;EALiB,cADH,aAAa,UAAU,QAAQ,UACR,CAM5B;CAKG,CAAC,CAAC,KAAK,MAAM;AAC7B;;;AC/CA,MAAMC,SAAO,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AACnD,MAAM,mBAAmB;AAEzB,eAAsB,iBAAiB,SAA0C;CAC/E,MAAM,aAAa,CACjB,KAAKA,QAAM,MAAM,MAAM,MAAM,QAAQ,QAAQ,UAAU,qBAAqB,GAC5E,KAAKA,QAAM,qBAAqB,CAClC;CACA,KAAK,MAAM,KAAK,YACd,IAAI,WAAW,CAAC,GAAG,OAAO,KAAK,MAAM,aAAa,GAAG,MAAM,CAAC;CAI9D,MAAM,MAAM,OADD,WAAW,MAAA,CACD,GAFN,iBAAiB,qBAER;CACxB,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,kCAAkC,IAAI,QAAQ;CAC3E,OAAO,IAAI,KAAK;AAClB;;;ACYA,MAAM,OAAO,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AACnD,MAAM,mBAAmB;AAEzB,eAAsB,YAAY,SAA2C;CAC3E,MAAM,aAAa,CACjB,KAAK,MAAM,MAAM,MAAM,MAAM,QAAQ,QAAQ,UAAU,cAAc,GACrE,KAAK,MAAM,cAAc,CAC3B;CACA,KAAK,MAAM,KAAK,YACd,IAAI,WAAW,CAAC,GAAG,OAAO,KAAK,MAAM,aAAa,GAAG,MAAM,CAAC;CAI9D,MAAM,MAAM,OADD,WAAW,MAAA,CACD,GAFN,iBAAiB,cAER;CACxB,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,mCAAmC,IAAI,QAAQ;CAC5E,OAAO,IAAI,KAAK;AAClB;AAEA,eAAsB,sBACpB,MACA,SACwB;CACxB,MAAM,OAAO,KAAK,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG;CACnD,MAAM,aAAa,CACjB,KAAK,MAAM,MAAM,MAAM,MAAM,QAAQ,QAAQ,UAAU,WAAW,GAAG,KAAK,IAAI,GAC9E,KAAK,MAAM,WAAW,GAAG,KAAK,IAAI,CACpC;CACA,KAAK,MAAM,KAAK,YACd,IAAI,WAAW,CAAC,GAAG,OAAO,aAAa,GAAG,MAAM;CAElD,MAAM,MAAM,GAAG,iBAAiB,WAAW,KAAK;CAChD,MAAM,KAAK,WAAW;CACtB,IAAI;EACF,MAAM,MAAM,MAAM,GAAG,GAAG;EACxB,IAAI,CAAC,IAAI,IAAI,OAAO;EACpB,OAAO,IAAI,KAAK;CAClB,QAAQ;EACN,OAAO;CACT;AACF;;;ACrEA,MAAM,eAAe;AAErB,SAAS,MAAM,MAAwB;CACrC,QAAQ,KAAK,YAAY,CAAC,CAAC,MAAM,UAAU,KAAK,CAAC,EAAA,CAAG,QAAQ,MAAM,EAAE,UAAU,YAAY;AAC5F;AAEA,SAAS,aAAa,WAAqB,MAAwB;CACjE,MAAM,QAAQ,KAAK,YAAY;CAC/B,OAAO,UAAU,QAAQ,MAAM,MAAM,SAAS,CAAC,CAAC;AAClD;AAEA,SAAgB,gBAAgB,MAAc,YAAgD;CAC5F,MAAM,YAAY,MAAM,IAAI;CAC5B,IAAI,UAAU,WAAW,GAAG,OAAO,CAAC;CAEpC,MAAM,SAAS,WAAW,KAAK,MAAM;EACnC,MAAM,gBAAgB,EAAE,OAAO,UAAU,KAAK,GAAG;EACjD,MAAM,mBAAmB,EAAE,OAAO,aAAa,KAAK,GAAG;EAEvD,MAAM,mBAAmB,aAAa,WAAW,aAAa;EAC9D,MAAM,cAAc,aAAa,WAAW,EAAE,WAAW;EACzD,MAAM,iBAAiB,aAAa,WAAW,gBAAgB;EAE/D,MAAM,QAAQ,iBAAiB,SAAS,IAAI,YAAY,SAAS,eAAe,SAAS;EAGzF,IAAI,MAAM;EACV,IAAI,iBAAiB,SAAS,GAAG;GAC/B,MAAM,eAAe,EAAE,OAAO,UAC3B,KAAK,OAAO;IAAE;IAAG,OAAO,aAAa,WAAW,CAAC,CAAC,CAAC;GAAO,EAAE,CAAC,CAC7D,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,CAC1B,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE;GACzC,MAAM,eACF,YAAY,iBAAiB,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,mBAAmB,aAAa,KAC7F,YAAY,iBAAiB,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;EACnE,OAAO,IAAI,YAAY,SAAS,GAC9B,MAAM,YAAY,YAAY,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE;EAGhE,OAAO;GACL,MAAM,EAAE;GACR;GACA;GACA,cAAc,EAAE,OAAO,gBAAgB,CAAC;GACxC,SAAS,EAAE,OAAO,WAAW,CAAC;EAChC;CACF,CAAC;CAGD,MAAM,YAAY,IAAI,IACpB,CAAC,GAAG,MAAM,CAAC,CACR,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,CAAC,CACjE,MAAM,GAAG,CAAC,CAAC,CACX,KAAK,MAAM,EAAE,IAAI,CACtB;CAGA,MAAM,+BAAe,IAAI,IAAoB;CAC7C,KAAK,MAAM,KAAK,QAAQ;EACtB,IAAI,CAAC,UAAU,IAAI,EAAE,IAAI,GAAG;EAC5B,KAAK,MAAM,OAAO,EAAE,SAClB,aAAa,IAAI,IAAI,OAAO,aAAa,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC;CAEpE;CAUA,OARc,OAAO,KAAK,OAAO;EAC/B,MAAM,EAAE;EACR,OAAO,EAAE,SAAS,aAAa,IAAI,EAAE,IAAI,KAAK;EAC9C,KAAK,EAAE;EACP,cAAc,EAAE;EAChB,SAAS,EAAE;CACb,EAEW,CAAC,CACT,QAAQ,MAAM,EAAE,SAAS,CAAC,CAAC,CAC3B,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,CAAC,CACjE,MAAM,GAAG,CAAC;AACf;;;AC/DA,MAAM,QAAQ,WAAoB,EAChC,SAAS,CAAC;CAAE,MAAM;CAAiB,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAE,CAAC,EAC3E;AAEA,MAAM,QAAQ,WAAmB,EAAE,SAAS,CAAC;CAAE,MAAM;CAAiB,MAAM;AAAM,CAAC,EAAE;AAErF,MAAM,SAAS,aAAqB;CAClC,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM;CAAQ,CAAC;CAClD,SAAS;AACX;;AAGA,SAAgB,aAAa,UAAyB,CAAC,GAAc;CACnE,MAAM,WAAqB,aAAa,QAAQ,YAAY;CAC5D,MAAM,UAAU,QAAQ;CAExB,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS,QAAQ,WAAW;CAC9B,CAAC;CAED,OAAO,aACL,mBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,CAAC;CAChB,GACA,YAAY;EAIV,OAAO,KADS,gBAAgB,MAFR,eAAe,OAAO,GAClC,iBACiC,CAErC,CAAC,CAAC,KAAK,EAAE,WAAW,MAAM,aAAa,UAAU,gBAAgB;GACrE;GACA;GACA;GACA,UAAU,YAAY;GACtB;EACF,EAAE,CACJ;CACF,CACF;CAEA,OAAO,aACL,mBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,UAAU,EACP,KAAK;IAAC;IAAU;IAAW;IAAW;IAAc;IAAY;GAAO,CAAC,CAAC,CACzE,SAAS,CAAC,CACV,SAAS,8BAA8B;GAC1C,MAAM,EACH,KAAK;IAAC;IAAa;IAAU;IAAS;GAAO,CAAC,CAAC,CAC/C,SAAS,CAAC,CACV,SAAS,sBAAsB;EACpC;CACF,IACC,EAAE,UAAU,WAAW,KAAK,eAAe,UAAU,UAAU,IAAI,CAAC,CACvE;CAEA,OAAO,aACL,iBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,iCAA+B;GACzD,UAAU,EACP,OAAO,CAAC,CACR,SAAS,CAAC,CACV,SAAS,0EAAwE;EACtF;CACF,GACA,OAAO,EAAE,MAAM,UAAU,SAAS;EAChC,IAAI,IAAI;GACN,MAAM,MAAM,iBAAiB;GAG7B,MAAM,QADU,gBAAgB,MADR,eAAe,OAAO,GACH,GACvB,CAAC,CAAC,MAAM,MAAM,EAAE,cAAc,EAAE;GACpD,IAAI,CAAC,OAAO,OAAO,MAAM,aAAa,GAAG,aAAa;GACtD,MAAM,iBAAiB,MAAM,mBAAmB,MAAM,aAAa,OAAO;GAC1E,IAAI,CAAC,gBAAgB,OAAO,MAAM,uCAAuC,GAAG,GAAG;GAC/E,MAAM,OAAO,aAAa,gBAAgB,IAAI;GAC9C,OAAO,OAAO,KAAK,IAAI,IAAI,MAAM,cAAc,KAAK,2BAA2B,GAAG,GAAG;EACvF;EACA,MAAM,OAAO,aAAa,UAAU,IAAI;EACxC,OAAO,OAAO,KAAK,IAAI,IAAI,MAAM,cAAc,KAAK,aAAa;CACnE,CACF;CAEA,OAAO,aACL,qBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,OAAO,EAAE,OAAO,CAAC,CAAC,SAAS,cAAc;GACzC,UAAU,EACP,OAAO,CAAC,CACR,SAAS,CAAC,CACV,SAAS,0EAAwE;EACtF;CACF,GACA,OAAO,EAAE,OAAO,UAAU,SAAS;EACjC,IAAI,IAAI;GACN,MAAM,MAAM,iBAAiB;GAG7B,MAAM,QADU,gBAAgB,MADR,eAAe,OAAO,GACH,GACvB,CAAC,CAAC,MAAM,MAAM,EAAE,cAAc,EAAE;GACpD,IAAI,CAAC,OAAO,OAAO,MAAM,aAAa,GAAG,aAAa;GACtD,MAAM,iBAAiB,MAAM,mBAAmB,MAAM,aAAa,OAAO;GAC1E,IAAI,CAAC,gBAAgB,OAAO,MAAM,uCAAuC,GAAG,GAAG;GAC/E,OAAO,KAAK,iBAAiB,gBAAgB,KAAK,CAAC;EACrD;EACA,OAAO,KAAK,iBAAiB,UAAU,KAAK,CAAC;CAC/C,CACF;CAEA,OAAO,aACL,kBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,uBAAuB;GACjD,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,uCAAuC;EACnF;CACF,IACC,EAAE,MAAM,gBAAgB;EACvB,MAAM,MAAM,YAAY;GAAE,GAAG,QAAQ;GAAK,oBAAoB;EAAU,IAAI,QAAQ;EACpF,MAAM,SAAS,UAAU,OAAO;GAAC;GAAM;GAAW;GAAO;EAAI,GAAG;GAAE,UAAU;GAAQ;EAAI,CAAC;EACzF,IAAI,OAAO,WAAW,GACpB,OAAO,MAAM,OAAO,UAAU,OAAO,OAAO,WAAW,kBAAkB,KAAK,GAAG;EAEnF,OAAO,KAAK,OAAO,UAAU,SAAS,KAAK,EAAE;CAC/C,CACF;CAEA,OAAO,aACL,gBACA;EACE,OAAO;EACP,aAAa;EACb,aAAa;GACX,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS,6CAA6C;GAC1E,SAAS,EAAE,OAAO,CAAC,CAAC,SAAS,0CAA0C;GACvE,QAAQ,EAAE,OAAO,CAAC,CAAC,SAAS,uCAAuC;GACnE,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,kCAAgC;EACvE;CACF,IACC,EAAE,SAAS,SAAS,QAAQ,WAC3B,KAAK,iBAAiB;EAAE;EAAS;EAAS;CAAO,GAAG,IAAI,CAAC,CAC7D;CAEA,OAAO,aACL,iBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,sBAAsB;GACvD,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,uBAAuB;EAC7E;CACF,IACC,EAAE,aAAa,iBAAiB;EAC/B,MAAM,EAAE,WAAW,aACjB;GAAE;GAAa,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EAAG,GACrD,QACF;EACA,OAAO,KACL,4EAA4E,aAAa,aAAa;GAAE;GAAa;EAAW,IAAI,EAAE,YAAY,CAAC,EAAE,oCAAoC,KAAK,UAAU,QAAQ,MAAM,CAAC,GACzN;CACF,CACF;CAEA,OAAO,aACL,iBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,mCAAmC,EACxF;CACF,IACC,EAAE,aAAa;EAGd,OAAO,KADQ,aAAa,QAAQ,IADT,IAAI,SAAS,WAAW,KAAK,MAAM,EAAE,KAAK,IAAI,CACxB,CAChC,CAAC;CACpB,CACF;CAEA,OAAO,aACL,iBACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,2BAA2B;GAC5D,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,4BAA4B;EAClF;CACF,IACC,EAAE,aAAa,iBAAiB;EAC/B,MAAM,EAAE,QAAQ,QAAQ,YAAY,aAClC;GAAE;GAAa,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EAAG,GACrD,QACF;EACA,IAAI,OAAO,SAAS,GAClB,OAAO,KAAK;GAAE,OAAO;GAAO;GAAQ;GAAQ;EAAQ,CAAC;EAEvD,OAAO,KAAK;GAAE,OAAO;GAAM;GAAQ;EAAQ,CAAC;CAC9C,CACF;CAEA,OAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,YAAY,EACT,MAAM,EAAE,OAAO,CAAC,CAAC,CACjB,SAAS,CAAC,CACV,SAAS,4EAA4E,EAC1F;CACF,IACC,EAAE,iBAAiB;EAClB,MAAM,UAAU,aAAa,UAAU,UAAU;EACjD,OAAO,KAAK;GACV,SAAS,cAAc,OAAO;GAC9B,QAAQ,sBAAsB,UAAU,aAAa,EAAE,WAAW,IAAI,CAAC,CAAC;GACxE,YAAY,QAAQ;EACtB,CAAC;CACH,CACF;CAEA,OAAO,aACL,cACA;EACE,OAAO;EACP,aACE;EACF,aAAa;GACX,OAAO,EACJ,OAAO,CAAC,CACR,SAAS,CAAC,CACV,SAAS,8DAAwD;GACpE,OAAO,EACJ,KAAK;IAAC;IAAa;IAAY;GAAW,CAAC,CAAC,CAC5C,SAAS,CAAC,CACV,SAAS,iBAAiB;EAC/B;CACF,GACA,OAAO,EAAE,OAAO,YAAY;EAC1B,IAAI;GAEF,IAAI,UAAS,MADS,iBAAiB,OAAO,EAAA,CACzB;GACrB,IAAI,OAAO,SAAS,OAAO,QAAQ,MAAM,EAAE,UAAU,KAAK;GAC1D,IAAI,OAAO,SAAS,OAAO,QAAQ,MAAM,EAAE,UAAU,KAAK;GAC1D,OAAO,KAAK;IAAE,OAAO,OAAO;IAAQ;GAAO,CAAC;EAC9C,SAAS,GAAG;GACV,OAAO,MAAM,8BAA8B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG;EACzF;CACF,CACF;CAEA,OAAO,aACL,eACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,gCAA8B,EAC1D;CACF,GACA,OAAO,EAAE,WAAW;EAClB,IAAI;GACF,MAAM,MAAM,MAAM,YAAY,OAAO;GACrC,MAAM,SAAS,KAAK,YAAY;GAChC,MAAM,YAAY,IAAI,WAAW,MAAM,MAAM,EAAE,KAAK,YAAY,MAAM,MAAM;GAC5E,IAAI,CAAC,WAEH,OAAO,MAAM,cAAc,KAAK,0BADd,IAAI,WAAW,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IACS,GAAG;GAEvE,MAAM,KAAK,MAAM,sBAAsB,UAAU,MAAM,OAAO;GAC9D,OAAO,KAAK;IACV,MAAM,UAAU;IAChB,UAAU,UAAU;IACpB,aAAa,UAAU;IACvB,QAAQ,UAAU;IAClB,YAAY,UAAU;IACtB,GAAI,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;GAC/B,CAAC;EACH,SAAS,GAAG;GACV,OAAO,MAAM,+BAA+B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG;EAC1F;CACF,CACF;CAEA,OAAO,aACL,oBACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,8DAA8D,EAC1F;CACF,GACA,OAAO,EAAE,WAAW;EAClB,IAAI;GAGF,OAAO,KAAK;IACV,MAAM;IACN,SAHc,gBAAgB,OAAM,MADpB,YAAY,OAAO,EAAA,CACK,UAGlC;GACR,CAAC;EACH,SAAS,GAAG;GACV,OAAO,MAAM,+BAA+B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG;EAC1F;CACF,CACF;CAEA,OAAO;AACT;;;ACzWA,MAAa,UAAU;;AA0BvB,eAAsB,OAAsB;CAE1C,MADe,aAAa,EAAE,SAAS,QAAQ,CACpC,CAAC,CAAC,QAAQ,IAAI,qBAAqB,CAAC;AACjD;AAIA,IAFe,KAAK,OAAO,KAAA,KAAa,OAAO,KAAK,QAAQ,cAAc,KAAK,EAAE,CAAC,CAAC,MAGjF,KAAK,CAAC,CAAC,OAAO,QAAiB;CAC7B,QAAQ,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;CAC9D,QAAQ,WAAW;AACrB,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["HERE","c","v","HERE"],"sources":["../src/registry.ts","../src/theme.ts","../src/scaffold.ts","../src/validate.ts","../src/grammar.ts","../src/scaffold-view.ts","../src/prompt.ts","../src/tokens.ts","../src/context.ts","../src/select.ts","../src/server.ts","../src/index.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface PropManifest {\n name: string\n type: string\n required: boolean\n default?: string\n description?: string\n}\n\nexport interface ComponentManifest {\n name: string\n description: string\n category: string\n states: string[]\n variants: string[]\n sizes: string[]\n props: PropManifest[]\n tokens: string[]\n accessibility: { role: string; wcag: string; keyboard: string[] }\n examples: { title: string; code: string; description?: string }[]\n dependencies: string[]\n tags: string[]\n}\n\nexport interface RegistryComponent {\n name: string\n type?: 'component' | 'layout' | 'block' | 'chart' | 'section'\n description: string\n category: string\n version: string\n files: string[]\n dependencies: string[]\n tags: string[]\n meta: ComponentManifest\n}\n\nexport interface Registry {\n version: string\n generatedAt: string\n components: RegistryComponent[]\n}\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\n\n/**\n * Resolve the registry.json location. Checks, in order: an explicit path, the\n * `CASCIVO_REGISTRY_PATH` env var, a copy bundled next to the built server\n * (published package), and the monorepo root (dev).\n */\nexport function resolveRegistryPath(explicit?: string): string {\n const candidates = [\n explicit,\n process.env.CASCIVO_REGISTRY_PATH,\n join(HERE, 'registry.json'),\n join(HERE, '..', '..', '..', 'registry.json'),\n join(HERE, '..', '..', 'registry.json'),\n ].filter((p): p is string => typeof p === 'string' && p.length > 0)\n\n return (\n candidates.find((p) => existsSync(p)) ?? candidates[candidates.length - 1] ?? 'registry.json'\n )\n}\n\nexport function loadRegistry(path?: string): Registry {\n const resolved = resolveRegistryPath(path)\n const raw = JSON.parse(readFileSync(resolved, 'utf8')) as Registry\n if (!Array.isArray(raw.components)) {\n throw new Error(`Invalid registry at ${resolved}: \"components\" must be an array`)\n }\n return raw\n}\n\n/** List component manifests, optionally filtered by category and/or type. */\nexport function listComponents(\n registry: Registry,\n category?: string,\n type?: string,\n): ComponentManifest[] {\n let entries = registry.components\n if (category) entries = entries.filter((c) => c.category === category)\n if (type) entries = entries.filter((c) => c.type === type)\n return entries.map((c) => c.meta)\n}\n\n/** Find one component manifest by name (matches registry name or meta name). */\nexport function getComponent(registry: Registry, name: string): ComponentManifest | undefined {\n const target = name.toLowerCase()\n return registry.components.find(\n (c) => c.name.toLowerCase() === target || c.meta.name.toLowerCase() === target,\n )?.meta\n}\n\n// ---------------------------------------------------------------------------\n// Multi-registry support\n// ---------------------------------------------------------------------------\n\nexport interface RegistryDirectoryEntry {\n namespace: string\n name: string\n description?: string\n registryUrl: string\n verified?: boolean\n homepage?: string\n}\n\nconst DIRECTORY_URL = 'https://cascivo.com/r/registries.json'\nconst FETCH_TIMEOUT_MS = 15_000\nconst MAX_BODY_BYTES = 1_048_576 // 1 MB\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nasync function fetchWithGuards(url: string, fetchFn: FetchFn = fetch): Promise<string | null> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS)\n try {\n const res = await fetchFn(url, { signal: controller.signal })\n if (!res.ok) return null\n const buf = await res.arrayBuffer()\n if (buf.byteLength > MAX_BODY_BYTES) return null\n return new TextDecoder().decode(buf)\n } catch {\n return null\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** Fetch the central cascade registry directory. Returns empty array on failure. */\nexport async function fetchDirectory(fetchFn?: FetchFn): Promise<RegistryDirectoryEntry[]> {\n const raw = await fetchWithGuards(DIRECTORY_URL, fetchFn)\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed as RegistryDirectoryEntry[]\n } catch {\n return []\n }\n}\n\n/** Fetch the component index from a namespace's registryUrl. Returns null on failure. */\nexport async function fetchRegistryIndex(\n registryUrl: string,\n fetchFn?: FetchFn,\n): Promise<Registry | null> {\n // Resolve the registry.json URL: replace trailing `{name}` template or append /registry.json\n const indexUrl = registryUrl.includes('{name}')\n ? registryUrl.replace('{name}', 'registry').replace(/\\/registry$/, '/registry.json')\n : registryUrl.replace(/\\/?$/, '/registry.json').replace(/\\/\\/registry\\.json$/, '/registry.json')\n const raw = await fetchWithGuards(indexUrl, fetchFn)\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw) as Registry\n if (!Array.isArray(parsed.components)) return null\n return parsed\n } catch {\n return null\n }\n}\n\n/** Parse CASCADE_REGISTRIES env var — returns empty array on failure. */\nexport function getEnvRegistries(): RegistryDirectoryEntry[] {\n const raw = process.env['CASCADE_REGISTRIES']\n if (!raw) return []\n try {\n const parsed = JSON.parse(raw) as unknown\n if (!Array.isArray(parsed)) return []\n return parsed as RegistryDirectoryEntry[]\n } catch {\n return []\n }\n}\n\n/** Merge directory entries with env entries (env wins on namespace collision). */\nexport function mergeRegistries(\n directory: RegistryDirectoryEntry[],\n env: RegistryDirectoryEntry[],\n): RegistryDirectoryEntry[] {\n const map = new Map<string, RegistryDirectoryEntry>()\n for (const entry of directory) map.set(entry.namespace, entry)\n for (const entry of env) map.set(entry.namespace, entry)\n return Array.from(map.values())\n}\n\n/** Fuzzy search over name, tags, and description. */\nexport function searchComponents(registry: Registry, query: string): ComponentManifest[] {\n const q = query.toLowerCase().trim()\n if (q === '') return []\n return registry.components\n .filter(\n (c) =>\n c.name.toLowerCase().includes(q) ||\n c.description.toLowerCase().includes(q) ||\n c.tags.some((t) => t.toLowerCase().includes(q)),\n )\n .map((c) => c.meta)\n}\n","export interface ThemeColors {\n /** Main brand / interactive color (maps to the accent token family). */\n primary: string\n /** Base gray used to derive surfaces, borders, and text. */\n neutral: string\n /** Secondary highlight color (info / focus ring). */\n accent: string\n}\n\n/** Darken a color by mixing in black (modern CSS, no preprocessor). */\nfunction darken(color: string, amount: number): string {\n return `color-mix(in oklab, ${color}, black ${amount}%)`\n}\n\n/** Lighten a color by mixing in white. */\nfunction lighten(color: string, amount: number): string {\n return `color-mix(in oklab, ${color}, white ${amount}%)`\n}\n\n/**\n * Generate a custom cascivo theme as CSS. Maps the three input colors onto the\n * semantic token layer; component tokens inherit automatically.\n */\nexport function generateThemeCss(colors: ThemeColors, name = 'custom'): string {\n const { primary, neutral, accent } = colors\n return `/* cascivo — Generated theme: ${name} */\n\n@layer cascivo.theme {\n [data-theme='${name}'] {\n color-scheme: light;\n\n /* ── Surface (derived from neutral) ───────────────── */\n --cascivo-color-bg: ${lighten(neutral, 96)};\n --cascivo-color-bg-subtle: ${lighten(neutral, 92)};\n --cascivo-color-surface: ${lighten(neutral, 98)};\n --cascivo-color-surface-raised: ${lighten(neutral, 94)};\n --cascivo-color-surface-overlay: ${lighten(neutral, 98)};\n --cascivo-color-border: ${lighten(neutral, 80)};\n --cascivo-color-border-strong: ${lighten(neutral, 65)};\n\n /* ── Text (derived from neutral) ──────────────────── */\n --cascivo-color-text: ${darken(neutral, 80)};\n --cascivo-color-text-subtle: ${darken(neutral, 50)};\n --cascivo-color-text-muted: ${lighten(neutral, 30)};\n --cascivo-color-text-on-accent: #ffffff;\n --cascivo-color-text-on-destructive: #ffffff;\n\n /* ── Accent / primary interactive ─────────────────── */\n --cascivo-color-accent: ${primary};\n --cascivo-color-accent-hover: ${darken(primary, 12)};\n --cascivo-color-accent-active: ${darken(primary, 24)};\n --cascivo-color-accent-subtle: ${lighten(primary, 88)};\n --cascivo-color-accent-muted: ${lighten(primary, 76)};\n\n /* ── Secondary accent (info / focus) ──────────────── */\n --cascivo-color-info: ${accent};\n --cascivo-color-info-subtle: ${lighten(accent, 88)};\n --cascivo-color-focus-ring: ${accent};\n --cascivo-focus-ring: 0 0 0 3px ${lighten(accent, 20)};\n\n /* ── Status ───────────────────────────────────────── */\n --cascivo-color-destructive: #dc2626;\n --cascivo-color-destructive-hover: ${darken('#dc2626', 12)};\n --cascivo-color-destructive-subtle: ${lighten('#dc2626', 88)};\n --cascivo-color-success: #16a34a;\n --cascivo-color-success-subtle: ${lighten('#16a34a', 88)};\n --cascivo-color-warning: #f59e0b;\n --cascivo-color-warning-subtle: ${lighten('#f59e0b', 88)};\n }\n}\n`\n}\n","export interface ScaffoldOptions {\n description: string\n components?: string[]\n}\n\nconst DEFAULT_COMPONENTS = ['card', 'input', 'button']\n\nfunction pascalCase(name: string): string {\n return name\n .split(/[-_\\s]+/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('')\n}\n\n/** A reasonable default usage snippet per component for the scaffold. */\nfunction usage(component: string, Tag: string): string {\n switch (component) {\n case 'button':\n return ` <${Tag}>Get started</${Tag}>`\n case 'input':\n return ` <${Tag} label=\"Email\" placeholder=\"you@example.com\" />`\n case 'card':\n return ` <${Tag}>\\n <h2>Card title</h2>\\n <p>Card content goes here.</p>\\n </${Tag}>`\n case 'badge':\n return ` <${Tag}>New</${Tag}>`\n default:\n return ` <${Tag} />`\n }\n}\n\n/**\n * Generate a JSX page layout string from a natural-language description and an\n * optional list of cascade components to include.\n */\nexport function scaffoldPage(options: ScaffoldOptions): string {\n const components = options.components?.length ? options.components : DEFAULT_COMPONENTS\n const unique = [...new Set(components.map((c) => c.toLowerCase()))]\n\n const imports = unique\n .map((c) => `import { ${pascalCase(c)} } from './components/ui/${c}/${c}'`)\n .join('\\n')\n\n const body = unique.map((c) => usage(c, pascalCase(c))).join('\\n')\n\n return `${imports}\n\n/* ${options.description} */\nexport function Page() {\n return (\n <main\n data-theme=\"light\"\n style={{ maxWidth: '48rem', margin: '0 auto', padding: '2rem', display: 'grid', gap: '1rem' }}\n >\n${body}\n </main>\n )\n}\n`\n}\n","// Inlined from @cascivo/render — avoids a Node.js binary depending on React components at runtime.\n// Component name validation uses the registry (passed by caller) instead of the React component map.\n\nexport interface ValidationError {\n path: string\n message: string\n}\n\nexport interface ComponentNode {\n component: string\n props?: Record<string, unknown>\n bind?: Record<string, string>\n events?: Record<string, string>\n children?: ComponentNode[] | string\n}\n\nexport interface ViewConfig {\n $schema?: string\n version?: 1\n view: {\n layout?: string\n regions: Record<string, ComponentNode[]>\n }\n}\n\nconst DATA_REF_RE = /^\\$data\\./\nconst ACTION_REF_RE = /^\\$actions\\./\n\nfunction closestName(name: string, candidates: string[]): string | undefined {\n const target = name.toLowerCase()\n let best: string | undefined\n let bestDist = 3\n for (const candidate of candidates) {\n const dist = levenshtein(target, candidate.toLowerCase())\n if (dist < bestDist) {\n bestDist = dist\n best = candidate\n }\n }\n return best\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n )\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i]![j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1]![j - 1]!\n : 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n return dp[m]![n]!\n}\n\nfunction validateNode(\n node: unknown,\n path: string,\n errors: ValidationError[],\n componentNames: Set<string>,\n): void {\n if (typeof node !== 'object' || node === null) {\n errors.push({ path, message: 'Expected a component node object' })\n return\n }\n const n = node as Record<string, unknown>\n if (typeof n['component'] !== 'string') {\n errors.push({ path: `${path}.component`, message: 'component must be a string' })\n return\n }\n const componentName = n['component'] as string\n if (!componentNames.has(componentName)) {\n const suggestion = closestName(componentName, [...componentNames])\n const hint = suggestion ? ` Did you mean \"${suggestion}\"?` : ''\n errors.push({\n path: `${path}.component`,\n message: `Unknown component \"${componentName}\".${hint}`,\n })\n return\n }\n\n const nodeBind = (n['bind'] ?? {}) as Record<string, string>\n for (const [key, value] of Object.entries(nodeBind)) {\n if (typeof value !== 'string' || !DATA_REF_RE.test(value)) {\n errors.push({\n path: `${path}.bind.${key}`,\n message: `bind values must start with \"$data.\" — got \"${value}\"`,\n })\n }\n }\n\n const nodeEvents = (n['events'] ?? {}) as Record<string, string>\n for (const [key, value] of Object.entries(nodeEvents)) {\n if (typeof value !== 'string' || !ACTION_REF_RE.test(value)) {\n errors.push({\n path: `${path}.events.${key}`,\n message: `events values must start with \"$actions.\" — got \"${value}\"`,\n })\n }\n }\n\n if (Array.isArray(n['children'])) {\n for (let i = 0; i < n['children'].length; i++) {\n validateNode(\n n['children'][i] as ComponentNode,\n `${path}.children[${i}]`,\n errors,\n componentNames,\n )\n }\n }\n}\n\n/** Validate a ViewConfig object. Component names are checked against the provided set. */\nexport function validateView(\n config: unknown,\n componentNames: Set<string>,\n): { valid: boolean; errors: ValidationError[] } {\n const errors: ValidationError[] = []\n\n if (typeof config !== 'object' || config === null) {\n return { valid: false, errors: [{ path: '', message: 'Config must be an object' }] }\n }\n\n const c = config as Record<string, unknown>\n const view = c['view']\n\n if (typeof view !== 'object' || view === null) {\n return { valid: false, errors: [{ path: 'view', message: 'view must be an object' }] }\n }\n\n const v = view as Record<string, unknown>\n const regions = v['regions']\n\n if (typeof regions !== 'object' || regions === null) {\n errors.push({ path: 'view.regions', message: 'view.regions must be an object' })\n return { valid: false, errors }\n }\n\n for (const [regionName, nodes] of Object.entries(regions as Record<string, unknown>)) {\n if (!Array.isArray(nodes)) {\n errors.push({\n path: `view.regions.${regionName}`,\n message: `Region \"${regionName}\" must be an array of component nodes`,\n })\n continue\n }\n for (let i = 0; i < nodes.length; i++) {\n validateNode(\n nodes[i] as ComponentNode,\n `view.regions.${regionName}[${i}]`,\n errors,\n componentNames,\n )\n }\n }\n\n return { valid: errors.length === 0, errors }\n}\n","// Library-derived bound vocabulary (v40 T1).\n//\n// OpenUI's anti-hallucination mechanism is a system prompt generated from the\n// component library so a model can only emit registered components/props. This\n// module derives that bound vocabulary from the cascade manifests\n// (component.meta.ts → registry.json): per component → its props (name, type,\n// allowed enum values, required) plus variants/sizes. Because it is *derived*,\n// it can never drift from the components (grammar.test.ts asserts every name it\n// references exists in the registry).\n\nimport type { Registry } from './registry.js'\n\nexport interface GrammarProp {\n name: string\n required: boolean\n /** Raw TypeScript type string from the manifest. */\n type: string\n /** Allowed values, when `type` is a string-literal union (e.g. `'sm' | 'md'`). */\n enum?: string[]\n}\n\nexport interface GrammarComponent {\n name: string\n category: string\n props: GrammarProp[]\n variants: string[]\n sizes: string[]\n}\n\nexport interface ViewGrammar {\n components: GrammarComponent[]\n}\n\n/**\n * Parse a string-literal union type (`'a' | 'b' | \"c\"`) into its allowed\n * values. Returns `undefined` for any non-enum type (primitives, functions,\n * named types, object shapes) so the grammar only constrains what it can.\n */\nexport function parseEnum(type: string): string[] | undefined {\n const branches = type\n .split('|')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n if (branches.length === 0) return undefined\n const values: string[] = []\n for (const branch of branches) {\n const quoted = branch.match(/^['\"](.+)['\"]$/)\n if (!quoted?.[1]) return undefined\n values.push(quoted[1])\n }\n return values\n}\n\n/**\n * Build the bound-vocabulary descriptor from the registry, optionally scoped to\n * a subset of component names (case-insensitive). Output is deterministic\n * (components and props sorted by name) for reproducible prompts and tests.\n */\n// Preference when two registry entries share a meta.name (e.g. a `component`\n// and a `layout` both named \"AppShell\"): the node-usable component wins.\nconst TYPE_RANK: Record<string, number> = {\n component: 0,\n block: 1,\n chart: 2,\n section: 3,\n layout: 4,\n}\n\nexport function buildGrammar(registry: Registry, subset?: string[]): ViewGrammar {\n const wanted = subset && subset.length > 0 ? new Set(subset.map((n) => n.toLowerCase())) : null\n\n // Dedupe by meta.name, keeping the highest-ranked (node-usable) entry.\n const canonical = new Map<string, (typeof registry.components)[number]>()\n for (const c of registry.components) {\n const key = c.meta.name.toLowerCase()\n const current = canonical.get(key)\n if (!current || (TYPE_RANK[c.type ?? ''] ?? 9) < (TYPE_RANK[current.type ?? ''] ?? 9)) {\n canonical.set(key, c)\n }\n }\n\n const components: GrammarComponent[] = [...canonical.values()]\n .filter(\n (c) => !wanted || wanted.has(c.meta.name.toLowerCase()) || wanted.has(c.name.toLowerCase()),\n )\n .map((c) => {\n const props: GrammarProp[] = (c.meta.props ?? [])\n .map((p) => {\n const values = parseEnum(p.type)\n return {\n name: p.name,\n required: p.required === true,\n type: p.type,\n ...(values ? { enum: values } : {}),\n }\n })\n .sort((a, b) => a.name.localeCompare(b.name))\n return {\n name: c.meta.name,\n category: c.category,\n props,\n variants: c.meta.variants ?? [],\n sizes: c.meta.sizes ?? [],\n }\n })\n .sort((a, b) => a.name.localeCompare(b.name))\n\n return { components }\n}\n\n/** Render one prop as `name`, `name*` (required), with enum choices or its type. */\nfunction formatProp(prop: GrammarProp): string {\n const mark = prop.required ? '*' : ''\n const value = prop.enum ? prop.enum.join('|') : prop.type\n return `${prop.name}${mark}: ${value}`\n}\n\n/**\n * Render the grammar as a compact, model-friendly table: one line per\n * component. Terser than verbose JSON; a `*` marks a required prop.\n *\n * Badge(size: sm|md, variant: default|secondary|success|warning|destructive|outline)\n */\nexport function formatGrammar(grammar: ViewGrammar): string {\n return grammar.components\n .map((c) => `${c.name}(${c.props.map(formatProp).join(', ')})`)\n .join('\\n')\n}\n","import type { ViewConfig } from './validate.js'\nimport { validateView } from './validate.js'\nimport type { Registry } from './registry.js'\nimport { buildGrammar, formatGrammar } from './grammar.js'\n\ninterface ScaffoldViewInput {\n description: string\n components?: string[]\n}\n\n/** Simple keyword matcher — returns region layout name based on description keywords. */\nfunction pickLayout(description: string): string {\n const d = description.toLowerCase()\n if (d.includes('dashboard') || d.includes('stats') || d.includes('kpi')) return 'dashboard'\n if (d.includes('settings') || d.includes('preferences') || d.includes('config')) return 'settings'\n if (d.includes('login') || d.includes('auth') || d.includes('sign')) return 'auth'\n return 'none'\n}\n\n/** Pick sensible components from the registry matching keywords in description. */\nfunction pickComponents(description: string, registry: Registry, explicit?: string[]): string[] {\n if (explicit && explicit.length > 0) return explicit.map((c) => c.toLowerCase())\n const d = description.toLowerCase()\n const candidates: string[] = []\n for (const entry of registry.components) {\n const name = entry.meta.name.toLowerCase()\n const tags = entry.tags.join(' ').toLowerCase()\n if (d.includes(name) || tags.split(' ').some((t) => d.includes(t))) {\n candidates.push(entry.meta.name)\n }\n }\n // Always add at least one component\n if (candidates.length === 0) candidates.push('Badge')\n return candidates.slice(0, 4)\n}\n\nfunction makeNode(\n componentName: string,\n registry: Registry,\n): { component: string; props?: Record<string, string | number | boolean> } {\n const entry = registry.components.find(\n (c) => c.meta.name.toLowerCase() === componentName.toLowerCase(),\n )\n if (!entry) return { component: componentName }\n const props: Record<string, string | number | boolean> = {}\n for (const prop of entry.meta.props ?? []) {\n if (prop.required && prop.default !== undefined) {\n props[prop.name] = prop.default\n } else if (\n prop.default !== undefined &&\n ['string', 'number', 'boolean'].includes(typeof prop.default)\n ) {\n // Skip defaults that are complex\n }\n }\n return Object.keys(props).length > 0\n ? { component: entry.meta.name, props }\n : { component: entry.meta.name }\n}\n\nexport function scaffoldView(\n input: ScaffoldViewInput,\n registry: Registry,\n): {\n config: ViewConfig\n errors: { path: string; message: string }[]\n /** Bound-vocabulary grammar (v40 T1) for the scaffolded components, so a caller gets both a starter scaffold and the allowed props/enums to refine it. */\n grammar: string\n} {\n const layout = pickLayout(input.description)\n const componentNames = pickComponents(input.description, registry, input.components)\n\n const config: ViewConfig = {\n $schema:\n 'https://raw.githubusercontent.com/cascivo/cascivo/main/packages/render/schema/view.v1.json',\n version: 1,\n view: {\n ...(layout !== 'none' ? { layout } : {}),\n regions: {\n main: componentNames.map((name) => makeNode(name, registry)),\n },\n },\n }\n\n const validNames = new Set(registry.components.map((c) => c.meta.name))\n const { errors } = validateView(config, validNames)\n const grammar = formatGrammar(buildGrammar(registry, componentNames))\n return { config, errors, grammar }\n}\n","// Generation prompt derived from the bound vocabulary (v40 T1).\n//\n// Composes the system prompt an LLM needs to emit valid `ViewConfig` JSON that\n// is restricted to cascivo's real components, props, and enum values — the\n// OpenUI \"system prompt from the component library\" anti-hallucination\n// mechanism, applied to the format cascivo already ships and dogfoods\n// (@cascivo/render). See docs/ROADMAP-V40.md.\n\nimport { buildGrammar, formatGrammar } from './grammar.js'\nimport type { Registry } from './registry.js'\n\nexport interface GenerationPromptOptions {\n /** Scope the vocabulary to a subset of component names. Defaults to all. */\n components?: string[]\n}\n\nconst SCHEMA_DOC = `A ViewConfig is a JSON object:\n\n{\n \"version\": 1,\n \"view\": {\n \"layout\": \"<optional layout name, e.g. dashboard | settings | auth>\",\n \"regions\": {\n \"<regionName>\": [ <ComponentNode>, ... ]\n }\n }\n}\n\nA ComponentNode is:\n\n{\n \"component\": \"<one of the registered component names below>\",\n \"props\": { \"<propName>\": <value> },\n \"bind\": { \"<propName>\": \"$data.<path>\" },\n \"events\": { \"<eventPropName>\": \"$actions.<name>\" },\n \"children\": <ComponentNode[] | string | { \"$t\": \"<i18n.key>\" }>\n}\n\nRules:\n- \"component\" MUST be one of the registered components listed below — never invent one.\n- Only use props listed for that component; enum props MUST use one of the listed values.\n- \"bind\" values are host-data references and MUST start with \"$data.\".\n- \"events\" values are host-action references and MUST start with \"$actions.\".\n- \"children\" is an array of nodes, a plain string, or an i18n ref { \"$t\": \"key\" }.\n- Output ONLY the JSON ViewConfig — no prose, no markdown fences.`\n\n/**\n * Build the bound-vocabulary system prompt for emitting `ViewConfig` JSON.\n * Parameterizable by an optional component subset (defaults to the full\n * registry).\n */\nexport function buildGenerationPrompt(\n registry: Registry,\n options: GenerationPromptOptions = {},\n): string {\n const grammar = buildGrammar(registry, options.components)\n const vocabulary = formatGrammar(grammar)\n\n const sections = [\n 'You generate UI as a cascivo ViewConfig — a JSON description rendered by @cascivo/render <CascadeView />.',\n SCHEMA_DOC,\n 'Registered components (allowed vocabulary — `name*` marks a required prop):',\n vocabulary,\n // EXTENSION POINT (v40 T3, optional): when the `cvl` compact DSL ships, append a\n // \"cvl syntax\" section here so an agent can be asked to emit cvl instead of JSON.\n ]\n\n return sections.join('\\n\\n')\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface TokenCatalogEntry {\n name: string\n value: string\n layer: 'primitive' | 'semantic' | 'component'\n group: string\n resolvedDefault: string | null\n resolvesPerTheme: boolean\n}\n\nexport interface TokenCatalog {\n generatedAt: string\n count: number\n tokens: TokenCatalogEntry[]\n}\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\nconst CATALOG_BASE_URL = 'https://cascivo.com'\n\nexport async function loadTokenCatalog(fetchFn?: FetchFn): Promise<TokenCatalog> {\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'tokens.catalog.json'),\n join(HERE, 'tokens.catalog.json'),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return JSON.parse(readFileSync(p, 'utf8')) as TokenCatalog\n }\n const url = `${CATALOG_BASE_URL}/tokens.catalog.json`\n const fn = fetchFn ?? fetch\n const res = await fn(url)\n if (!res.ok) throw new Error(`Failed to fetch token catalog: ${res.status}`)\n return res.json() as Promise<TokenCatalog>\n}\n","import { existsSync, readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nexport interface ContextRelated {\n name: string\n relationship: string\n reason: string\n}\n\nexport interface ContextAntiPattern {\n bad: string\n good: string\n why: string\n}\n\nexport interface ContextFlexibility {\n area: string\n level: string\n note: string\n}\n\nexport interface ComponentIntent {\n whenToUse: string[]\n whenNotToUse: string[]\n antiPatterns: ContextAntiPattern[]\n related: ContextRelated[]\n a11yRationale?: string\n flexibility?: ContextFlexibility[]\n}\n\nexport interface ContextComponent {\n name: string\n category: string\n description: string\n intent: ComponentIntent\n contextUrl: string\n}\n\nexport interface ContextBundle {\n generatedAt: string\n tagline: string\n authoringRules: string[]\n tokenCatalogUrl: string\n components: ContextComponent[]\n}\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nconst HERE = dirname(fileURLToPath(import.meta.url))\nconst CONTEXT_BASE_URL = 'https://cascivo.com'\n\nexport async function loadContext(fetchFn?: FetchFn): Promise<ContextBundle> {\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'context.json'),\n join(HERE, 'context.json'),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return JSON.parse(readFileSync(p, 'utf8')) as ContextBundle\n }\n const url = `${CONTEXT_BASE_URL}/context.json`\n const fn = fetchFn ?? fetch\n const res = await fn(url)\n if (!res.ok) throw new Error(`Failed to fetch context bundle: ${res.status}`)\n return res.json() as Promise<ContextBundle>\n}\n\nexport async function loadComponentMarkdown(\n name: string,\n fetchFn?: FetchFn,\n): Promise<string | null> {\n const slug = name.toLowerCase().replace(/\\s+/g, '-')\n const localPaths = [\n join(HERE, '..', '..', '..', 'apps', 'docs', 'public', 'context', `${slug}.md`),\n join(HERE, 'context', `${slug}.md`),\n ]\n for (const p of localPaths) {\n if (existsSync(p)) return readFileSync(p, 'utf8')\n }\n const url = `${CONTEXT_BASE_URL}/context/${slug}.md`\n const fn = fetchFn ?? fetch\n try {\n const res = await fn(url)\n if (!res.ok) return null\n return res.text()\n } catch {\n return null\n }\n}\n","import type { ContextComponent } from './context.js'\n\nexport interface SelectRelated {\n name: string\n relationship: string\n reason: string\n}\n\nexport interface SelectResult {\n name: string\n score: number\n why: string\n /** When NOT to use this pick — lets an agent disqualify a wrong match. */\n whenNotToUse: string[]\n /** Related components (alternatives, pairs-with) to consider instead/alongside. */\n related: SelectRelated[]\n}\n\n// Minimum length for a need word to be scored (filters out articles, prepositions, etc.)\nconst MIN_WORD_LEN = 3\n\nfunction words(text: string): string[] {\n return (text.toLowerCase().match(/\\b\\w+\\b/g) ?? []).filter((w) => w.length >= MIN_WORD_LEN)\n}\n\nfunction countMatches(needWords: string[], text: string): string[] {\n const lower = text.toLowerCase()\n return needWords.filter((w) => lower.includes(w))\n}\n\nexport function selectComponent(need: string, components: ContextComponent[]): SelectResult[] {\n const needWords = words(need)\n if (needWords.length === 0) return []\n\n const scored = components.map((c) => {\n const whenToUseText = c.intent.whenToUse.join(' ')\n const whenNotToUseText = c.intent.whenNotToUse.join(' ')\n\n const whenToUseMatches = countMatches(needWords, whenToUseText)\n const descMatches = countMatches(needWords, c.description)\n const penaltyMatches = countMatches(needWords, whenNotToUseText)\n\n const score = whenToUseMatches.length * 2 + descMatches.length - penaltyMatches.length * 3\n\n // Build why from the best-matching whenToUse sentence\n let why = ''\n if (whenToUseMatches.length > 0) {\n const bestSentence = c.intent.whenToUse\n .map((s) => ({ s, count: countMatches(needWords, s).length }))\n .filter((x) => x.count > 0)\n .sort((a, b) => b.count - a.count)[0]?.s\n why = bestSentence\n ? `Matched: ${whenToUseMatches.map((w) => `'${w}'`).join(', ')} in whenToUse — \"${bestSentence}\"`\n : `Matched: ${whenToUseMatches.map((w) => `'${w}'`).join(', ')} in description`\n } else if (descMatches.length > 0) {\n why = `Matched: ${descMatches.map((w) => `'${w}'`).join(', ')} in description`\n }\n\n return {\n name: c.name,\n score,\n why,\n whenNotToUse: c.intent.whenNotToUse ?? [],\n related: c.intent.related ?? [],\n }\n })\n\n // First pass: top 3 by score for related bonus\n const top3Names = new Set(\n [...scored]\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, 3)\n .map((r) => r.name),\n )\n\n // Apply related bonus: +1 if a top-3 component points at this component\n const relatedBonus = new Map<string, number>()\n for (const r of scored) {\n if (!top3Names.has(r.name)) continue\n for (const rel of r.related) {\n relatedBonus.set(rel.name, (relatedBonus.get(rel.name) ?? 0) + 1)\n }\n }\n\n const final = scored.map((r) => ({\n name: r.name,\n score: r.score + (relatedBonus.get(r.name) ?? 0),\n why: r.why,\n whenNotToUse: r.whenNotToUse,\n related: r.related,\n }))\n\n return final\n .filter((r) => r.score >= 0)\n .sort((a, b) => b.score - a.score || a.name.localeCompare(b.name))\n .slice(0, 5)\n}\n","import { spawnSync } from 'node:child_process'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport {\n fetchDirectory,\n fetchRegistryIndex,\n getComponent,\n getEnvRegistries,\n listComponents,\n loadRegistry,\n mergeRegistries,\n searchComponents,\n type Registry,\n} from './registry.js'\nimport { generateThemeCss } from './theme.js'\nimport { scaffoldPage } from './scaffold.js'\nimport { validateView } from './validate.js'\nimport { scaffoldView } from './scaffold-view.js'\nimport { buildGrammar, formatGrammar } from './grammar.js'\nimport { buildGenerationPrompt } from './prompt.js'\nimport { loadTokenCatalog } from './tokens.js'\nimport { loadContext, loadComponentMarkdown } from './context.js'\nimport { selectComponent } from './select.js'\n\ntype FetchFn = (url: string, init?: RequestInit) => Promise<Response>\n\nexport interface ServerOptions {\n registryPath?: string\n version?: string\n /** Injectable fetch function — used for testing multi-registry features. */\n fetchFn?: FetchFn\n}\n\nconst json = (value: unknown) => ({\n content: [{ type: 'text' as const, text: JSON.stringify(value, null, 2) }],\n})\n\nconst text = (value: string) => ({ content: [{ type: 'text' as const, text: value }] })\n\nconst error = (message: string) => ({\n content: [{ type: 'text' as const, text: message }],\n isError: true,\n})\n\n/** Build a configured McpServer exposing the cascade component registry. */\nexport function createServer(options: ServerOptions = {}): McpServer {\n const registry: Registry = loadRegistry(options.registryPath)\n const fetchFn = options.fetchFn\n\n const server = new McpServer({\n name: '@cascivo/mcp',\n version: options.version ?? '0.0.0',\n })\n\n server.registerTool(\n 'list_registries',\n {\n title: 'List registries',\n description:\n 'List available component registries: the cascade directory plus any configured via CASCADE_REGISTRIES env.',\n inputSchema: {},\n },\n async () => {\n const directory = await fetchDirectory(fetchFn)\n const env = getEnvRegistries()\n const entries = mergeRegistries(directory, env)\n return json(\n entries.map(({ namespace, name, description, verified, homepage }) => ({\n namespace,\n name,\n description,\n verified: verified ?? false,\n homepage,\n })),\n )\n },\n )\n\n server.registerTool(\n 'list_components',\n {\n title: 'List components',\n description: 'List all cascade components, optionally filtered by category and/or type.',\n inputSchema: {\n category: z\n .enum(['inputs', 'display', 'overlay', 'navigation', 'feedback', 'chart'])\n .optional()\n .describe('Filter by component category'),\n type: z\n .enum(['component', 'layout', 'block', 'chart'])\n .optional()\n .describe('Filter by entry type'),\n },\n },\n ({ category, type }) => json(listComponents(registry, category, type)),\n )\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component',\n description:\n 'Get the full manifest (props, states, tokens, a11y, examples) for one component.',\n inputSchema: {\n name: z.string().describe('Component name, e.g. \"button\"'),\n registry: z\n .string()\n .optional()\n .describe('Namespace of an external registry, e.g. \"@myns\". Omit for the default.'),\n },\n },\n async ({ name, registry: ns }) => {\n if (ns) {\n const env = getEnvRegistries()\n const directory = await fetchDirectory(fetchFn)\n const entries = mergeRegistries(directory, env)\n const entry = entries.find((e) => e.namespace === ns)\n if (!entry) return error(`Registry \"${ns}\" not found.`)\n const remoteRegistry = await fetchRegistryIndex(entry.registryUrl, fetchFn)\n if (!remoteRegistry) return error(`Failed to fetch registry index for \"${ns}\".`)\n const meta = getComponent(remoteRegistry, name)\n return meta ? json(meta) : error(`Component \"${name}\" not found in registry \"${ns}\".`)\n }\n const meta = getComponent(registry, name)\n return meta ? json(meta) : error(`Component \"${name}\" not found.`)\n },\n )\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search components',\n description: 'Fuzzy search components by name, tags, or description.',\n inputSchema: {\n query: z.string().describe('Search query'),\n registry: z\n .string()\n .optional()\n .describe('Namespace of an external registry, e.g. \"@myns\". Omit for the default.'),\n },\n },\n async ({ query, registry: ns }) => {\n if (ns) {\n const env = getEnvRegistries()\n const directory = await fetchDirectory(fetchFn)\n const entries = mergeRegistries(directory, env)\n const entry = entries.find((e) => e.namespace === ns)\n if (!entry) return error(`Registry \"${ns}\" not found.`)\n const remoteRegistry = await fetchRegistryIndex(entry.registryUrl, fetchFn)\n if (!remoteRegistry) return error(`Failed to fetch registry index for \"${ns}\".`)\n return json(searchComponents(remoteRegistry, query))\n }\n return json(searchComponents(registry, query))\n },\n )\n\n server.registerTool(\n 'add_to_project',\n {\n title: 'Add to project',\n description: 'Add a component to the current project by running the cascade CLI.',\n inputSchema: {\n name: z.string().describe('Component name to add'),\n outputDir: z.string().optional().describe('Directory to write the component into'),\n },\n },\n ({ name, outputDir }) => {\n const env = outputDir ? { ...process.env, CASCIVO_OUTPUT_DIR: outputDir } : process.env\n const result = spawnSync('npx', ['-y', 'cascivo', 'add', name], { encoding: 'utf8', env })\n if (result.status !== 0) {\n return error(result.stderr || result.error?.message || `Failed to add \"${name}\".`)\n }\n return text(result.stdout || `Added ${name}.`)\n },\n )\n\n server.registerTool(\n 'create_theme',\n {\n title: 'Create theme',\n description: 'Generate a cascade theme CSS file from three colors.',\n inputSchema: {\n primary: z.string().describe('Primary / interactive color (any CSS color)'),\n neutral: z.string().describe('Base neutral color for surfaces and text'),\n accent: z.string().describe('Secondary accent color (info / focus)'),\n name: z.string().optional().describe('Theme name (default: \"custom\")'),\n },\n },\n ({ primary, neutral, accent, name }) =>\n text(generateThemeCss({ primary, neutral, accent }, name)),\n )\n\n server.registerTool(\n 'scaffold_page',\n {\n title: 'Scaffold page (deprecated)',\n description:\n '[Deprecated — use scaffold_view instead] Generate a JSX page layout from a description.',\n inputSchema: {\n description: z.string().describe('What the page is for'),\n components: z.array(z.string()).optional().describe('Components to include'),\n },\n },\n ({ description, components }) => {\n const { config } = scaffoldView(\n { description, ...(components ? { components } : {}) },\n registry,\n )\n return text(\n `[Deprecated] Use scaffold_view for config-first output. JSX scaffold:\\n\\n${scaffoldPage(components ? { description, components } : { description })}\\n\\n--- scaffold_view output ---\\n${JSON.stringify(config, null, 2)}`,\n )\n },\n )\n\n server.registerTool(\n 'validate_view',\n {\n title: 'Validate view config',\n description:\n 'Validate a CascadeView JSON config against the registry. Returns errors with exact paths.',\n inputSchema: {\n config: z.record(z.string(), z.unknown()).describe('The ViewConfig object to validate'),\n },\n },\n ({ config }) => {\n const componentNames = new Set(registry.components.map((c) => c.meta.name))\n const result = validateView(config, componentNames)\n return json(result)\n },\n )\n\n server.registerTool(\n 'scaffold_view',\n {\n title: 'Scaffold view config',\n description:\n 'Generate a valid starter ViewConfig from a description. Always validates before returning.',\n inputSchema: {\n description: z.string().describe('What the page/view is for'),\n components: z.array(z.string()).optional().describe('Component names to include'),\n },\n },\n ({ description, components }) => {\n const { config, errors, grammar } = scaffoldView(\n { description, ...(components ? { components } : {}) },\n registry,\n )\n if (errors.length > 0) {\n return json({ valid: false, errors, config, grammar })\n }\n return json({ valid: true, config, grammar })\n },\n )\n\n server.registerTool(\n 'get_view_grammar',\n {\n title: 'Get view grammar',\n description:\n \"Get the bound-vocabulary grammar + system prompt for generating valid ViewConfig JSON, derived from the component manifests. Use this to constrain an LLM to cascivo's real components, props, and enum values (anti-hallucination). Optionally scope to a subset of components.\",\n inputSchema: {\n components: z\n .array(z.string())\n .optional()\n .describe('Scope the vocabulary to these component names. Omit for the full registry.'),\n },\n },\n ({ components }) => {\n const grammar = buildGrammar(registry, components)\n return json({\n grammar: formatGrammar(grammar),\n prompt: buildGenerationPrompt(registry, components ? { components } : {}),\n components: grammar.components,\n })\n },\n )\n\n server.registerTool(\n 'get_tokens',\n {\n title: 'Get tokens',\n description:\n 'Get the cascade token catalog (closed set). Agents must select from this catalog rather than hard-coding values.',\n inputSchema: {\n group: z\n .string()\n .optional()\n .describe('Filter by token group, e.g. \"color\", \"space\", \"radius\"'),\n layer: z\n .enum(['primitive', 'semantic', 'component'])\n .optional()\n .describe('Filter by layer'),\n },\n },\n async ({ group, layer }) => {\n try {\n const catalog = await loadTokenCatalog(fetchFn)\n let tokens = catalog.tokens\n if (group) tokens = tokens.filter((t) => t.group === group)\n if (layer) tokens = tokens.filter((t) => t.layer === layer)\n return json({ count: tokens.length, tokens })\n } catch (e) {\n return error(`Token catalog unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n server.registerTool(\n 'get_context',\n {\n title: 'Get context',\n description:\n 'Get intent, whenToUse/whenNotToUse, and authoring guidance for one component by name.',\n inputSchema: {\n name: z.string().describe('Component name, e.g. \"Toast\"'),\n },\n },\n async ({ name }) => {\n try {\n const ctx = await loadContext(fetchFn)\n const target = name.toLowerCase()\n const component = ctx.components.find((c) => c.name.toLowerCase() === target)\n if (!component) {\n const available = ctx.components.map((c) => c.name).join(', ')\n return error(`Component \"${name}\" not found. Available: ${available}`)\n }\n const md = await loadComponentMarkdown(component.name, fetchFn)\n return json({\n name: component.name,\n category: component.category,\n description: component.description,\n intent: component.intent,\n contextUrl: component.contextUrl,\n ...(md ? { markdown: md } : {}),\n })\n } catch (e) {\n return error(`Context bundle unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n server.registerTool(\n 'select_component',\n {\n title: 'Select component',\n description:\n 'Heuristic ranking of cascade components by natural language need. Returns top matches with scores and reasons. Note: heuristic ranking, not a model call.',\n inputSchema: {\n need: z.string().describe('Natural language description of what the component should do'),\n },\n },\n async ({ need }) => {\n try {\n const ctx = await loadContext(fetchFn)\n const results = selectComponent(need, ctx.components)\n return json({\n note: 'Heuristic ranking — not a model call. Verify with get_context before using.',\n results,\n })\n } catch (e) {\n return error(`Context bundle unavailable: ${e instanceof Error ? e.message : String(e)}`)\n }\n },\n )\n\n return server\n}\n","import { argv } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nexport const VERSION = '0.0.0'\n\nexport { createServer } from './server.js'\nexport type { ServerOptions } from './server.js'\nexport { generateThemeCss, type ThemeColors } from './theme.js'\nexport { scaffoldPage, type ScaffoldOptions } from './scaffold.js'\nexport {\n buildGrammar,\n formatGrammar,\n parseEnum,\n type GrammarComponent,\n type GrammarProp,\n type ViewGrammar,\n} from './grammar.js'\nexport { buildGenerationPrompt, type GenerationPromptOptions } from './prompt.js'\nexport {\n getComponent,\n listComponents,\n loadRegistry,\n searchComponents,\n type ComponentManifest,\n type Registry,\n type RegistryComponent,\n} from './registry.js'\n\n/** Start the MCP server over stdio. */\nexport async function main(): Promise<void> {\n const server = createServer({ version: VERSION })\n await server.connect(new StdioServerTransport())\n}\n\nconst isMain = argv[1] !== undefined && import.meta.url === pathToFileURL(argv[1]).href\n\nif (isMain) {\n main().catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err))\n process.exitCode = 1\n })\n}\n"],"mappings":"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"}