@frontic/ui 0.3.1 → 0.5.1

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/spawn-shadcn.ts","../src/utils/config.ts","../src/utils/constants.ts","../src/utils/colors.ts","../src/utils/css.ts","../src/commands/add.ts","../src/commands/mcp.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerMcpCommand } from \"./commands/mcp.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"frontic-ui\")\n .description(\"CLI for adding Frontic UI components to your Nuxt project\")\n .version(\"0.3.1\");\n\nregisterInitCommand(program);\nregisterAddCommand(program);\nregisterMcpCommand(program);\n\nexport function run() {\n program.parse();\n}\n\nexport { program };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport { join } from \"path\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { updateConfig, configExists, readConfig } from \"../utils/config.js\";\nimport {\n FRONTIC_REGISTRY_URL,\n DEFAULT_BRAND_COLOR,\n DEFAULT_RADIUS,\n RADIUS_OPTIONS,\n type RadiusOption,\n} from \"../utils/constants.js\";\nimport { hexToOklch, isValidHex, getForegroundColor } from \"../utils/colors.js\";\nimport { injectCssVars } from \"../utils/css.js\";\n\ninterface InitOptions {\n yes?: boolean;\n defaults?: boolean;\n force?: boolean;\n brand?: string;\n radius?: string;\n}\n\nexport function registerInitCommand(program: Command) {\n program\n .command(\"init\")\n .description(\"Initialize Frontic UI in your Nuxt project\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-d, --defaults\", \"Use default configuration\")\n .option(\"-f, --force\", \"Force overwrite of existing configuration\")\n .option(\"-b, --brand <color>\", \"Brand color in hex format (e.g., #6366f1)\")\n .option(\n \"-r, --radius <option>\",\n \"Border radius (none, small, medium, large, full)\"\n )\n .action(async (options: InitOptions) => {\n await init(options);\n });\n}\n\nasync function init(options: InitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI\"));\n console.log(chalk.dim(\"Initializing your project...\"));\n console.log();\n\n const hasConfig = await configExists();\n\n // Collect preferences BEFORE running shadcn-vue init\n let brandColor = DEFAULT_BRAND_COLOR;\n let radiusValue = DEFAULT_RADIUS;\n\n if (!hasConfig) {\n // Get brand color from CLI flag or prompt\n if (options.brand) {\n if (isValidHex(options.brand)) {\n brandColor = hexToOklch(options.brand);\n console.log(\n chalk.dim(`Using brand color: ${options.brand} → ${brandColor}`)\n );\n } else {\n console.log(\n chalk.yellow(`Invalid hex color: ${options.brand}, using default`)\n );\n }\n }\n\n // Get radius from CLI flag or validate it\n if (options.radius) {\n const radiusKey = options.radius.toLowerCase() as RadiusOption;\n if (radiusKey in RADIUS_OPTIONS) {\n radiusValue = RADIUS_OPTIONS[radiusKey];\n console.log(chalk.dim(`Using border radius: ${options.radius}`));\n } else {\n console.log(\n chalk.yellow(\n `Invalid radius option: ${options.radius}, using default (medium)`\n )\n );\n }\n }\n\n // Interactive prompts if not using --yes or --defaults\n if (!options.yes && !options.defaults) {\n const response = await prompts([\n {\n type: options.brand ? null : \"text\",\n name: \"brand\",\n message: \"Brand color (hex, e.g., #6366f1)\",\n initial: \"#6366f1\",\n validate: (value: string) => {\n if (!value) return true;\n return (\n isValidHex(value) ||\n \"Please enter a valid hex color (e.g., #6366f1)\"\n );\n },\n },\n {\n type: options.radius ? null : \"select\",\n name: \"radius\",\n message: \"Border radius\",\n choices: [\n { title: \"None\", value: \"none\" },\n { title: \"Small\", value: \"small\" },\n { title: \"Medium (recommended)\", value: \"medium\" },\n { title: \"Large\", value: \"large\" },\n { title: \"Full\", value: \"full\" },\n ],\n initial: 2,\n },\n ]);\n\n if (response.brand && isValidHex(response.brand)) {\n brandColor = hexToOklch(response.brand);\n console.log(chalk.dim(`Converted: ${response.brand} → ${brandColor}`));\n }\n\n if (response.radius) {\n radiusValue = RADIUS_OPTIONS[response.radius as RadiusOption];\n }\n }\n\n // Now run shadcn-vue init with output filtering\n console.log();\n console.log(chalk.blue(\"Setting up your project...\"));\n console.log();\n\n const args = [\"init\"];\n if (options.yes) args.push(\"--yes\");\n if (options.defaults) args.push(\"--defaults\");\n if (options.force) args.push(\"--force\");\n\n try {\n await spawnShadcn(args, { filterOutput: true });\n } catch {\n console.log();\n console.log(chalk.red(\"Failed to initialize project.\"));\n console.log();\n console.log(chalk.yellow(\"Common issues:\"));\n console.log(\n chalk.dim(\n \" • Tailwind CSS not installed - run: npx nuxi module add @nuxtjs/tailwindcss\"\n )\n );\n console.log(chalk.dim(\" • Not in a Vue/Nuxt project root directory\"));\n console.log(\n chalk.dim(\n \" • Existing components.json with invalid config - try: npx @frontic/ui init --force\"\n )\n );\n console.log();\n process.exit(1);\n }\n console.log();\n }\n\n // Calculate foreground color based on brand\n const brandForeground = getForegroundColor(brandColor);\n\n // Read config to get CSS file path\n const config = await readConfig();\n const cssPath = config?.tailwind?.css;\n\n // Inject CSS variables into the user's CSS file\n if (cssPath) {\n const cssSpinner = ora(\"Injecting theme variables...\").start();\n try {\n const fullCssPath = join(process.cwd(), cssPath);\n await injectCssVars(fullCssPath, {\n brand: brandColor,\n brandForeground: brandForeground,\n radius: radiusValue,\n });\n cssSpinner.succeed(\"Theme variables injected\");\n } catch {\n cssSpinner.warn(\n \"Could not inject theme variables (you may need to add them manually)\"\n );\n }\n }\n\n // Update components.json with Frontic registry\n const spinner = ora(\"Configuring Frontic registry...\").start();\n\n try {\n await updateConfig({\n registries: {\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n spinner.succeed(\"Frontic registry configured\");\n } catch (error) {\n spinner.fail(\"Failed to configure registry\");\n throw error;\n }\n\n // Install Frontic theme from registry\n const themeSpinner = ora(\"Installing Frontic theme...\").start();\n try {\n await spawnShadcn([\"add\", \"@frontic/theme\", \"--yes\"], { silent: true });\n themeSpinner.succeed(\"Frontic theme installed\");\n } catch {\n themeSpinner.warn(\n \"Theme installation skipped (may already exist or registry not available)\"\n );\n }\n\n console.log();\n console.log(chalk.green(\"✓ Frontic UI initialized successfully!\"));\n console.log();\n console.log(chalk.dim(\"Your theme settings:\"));\n console.log(` --brand: ${chalk.cyan(brandColor)}`);\n console.log(` --brand-foreground: ${chalk.cyan(brandForeground)}`);\n console.log(` --radius: ${chalk.cyan(radiusValue)}`);\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.dim(\" 1. Add components:\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log();\n console.log(chalk.dim(\" 2. Set up MCP for AI assistants (optional):\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui mcp init\")}`);\n console.log();\n}\n","import { execa } from \"execa\";\n\ninterface SpawnOptions {\n silent?: boolean;\n filterOutput?: boolean;\n}\n\nexport async function spawnShadcn(\n args: string[],\n options: SpawnOptions = {}\n): Promise<void> {\n const { silent = false, filterOutput = false } = options;\n\n try {\n if (filterOutput) {\n // Capture output, replace \"shadcn-vue\" → \"frontic-ui\", forward to stdout\n const proc = execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n shell: true,\n });\n\n proc.stdout?.on(\"data\", (data: Buffer) => {\n process.stdout.write(\n data.toString().replace(/shadcn-vue/gi, \"frontic-ui\")\n );\n });\n\n proc.stderr?.on(\"data\", (data: Buffer) => {\n process.stderr.write(\n data.toString().replace(/shadcn-vue/gi, \"frontic-ui\")\n );\n });\n\n await proc;\n } else {\n await execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: silent ? \"pipe\" : \"inherit\",\n shell: true,\n });\n }\n } catch (error) {\n if (!silent) {\n throw error;\n }\n // Silently ignore errors when silent mode is enabled\n }\n}\n","import { readFile, writeFile, access } from \"fs/promises\";\nimport { join } from \"path\";\nimport { CONFIG_FILE, FRONTIC_REGISTRY_URL } from \"./constants.js\";\n\nexport interface ComponentsConfig {\n $schema?: string;\n style?: string;\n typescript?: boolean;\n tailwind?: {\n css?: string;\n baseColor?: string;\n cssVariables?: boolean;\n };\n aliases?: {\n components?: string;\n utils?: string;\n ui?: string;\n lib?: string;\n composables?: string;\n };\n registries?: {\n [key: string]: {\n url: string;\n };\n };\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await access(join(process.cwd(), CONFIG_FILE));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readConfig(): Promise<ComponentsConfig | null> {\n try {\n const content = await readFile(join(process.cwd(), CONFIG_FILE), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function writeConfig(config: ComponentsConfig): Promise<void> {\n await writeFile(\n join(process.cwd(), CONFIG_FILE),\n JSON.stringify(config, null, 2)\n );\n}\n\nexport async function updateConfig(\n updates: Partial<ComponentsConfig>\n): Promise<void> {\n const existing = await readConfig();\n\n if (!existing) {\n throw new Error(\n \"components.json not found. Run `npx @frontic/ui init` first.\"\n );\n }\n\n const merged = deepMerge(existing, updates);\n await writeConfig(merged);\n}\n\nexport async function ensureFronticRegistry(): Promise<void> {\n const config = await readConfig();\n\n if (!config) {\n throw new Error(\"components.json not found\");\n }\n\n // Check if Frontic registry is already configured\n if (config.registries?.[\"@frontic\"]?.url === FRONTIC_REGISTRY_URL) {\n return;\n }\n\n // Add Frontic registry\n await updateConfig({\n registries: {\n ...config.registries,\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n}\n\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === \"object\" &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return result;\n}\n","// Use FRONTIC_REGISTRY_LOCAL=1 to test with local registry\nexport const FRONTIC_REGISTRY_URL =\n process.env.FRONTIC_REGISTRY_LOCAL === \"1\"\n ? \"http://localhost:3333/r/{name}.json\"\n : \"https://registry.frontic.io/r/{name}.json\";\n\nexport const CONFIG_FILE = \"components.json\";\n\n// Default brand color (purple - similar to Indigo 500)\nexport const DEFAULT_BRAND_COLOR = \"oklch(58% 0.25 265)\";\n\n// Default radius (medium)\nexport const DEFAULT_RADIUS = \"0.5rem\";\n\n// Radius options for CLI prompt\n// These are base values for --radius. The derived Tailwind vars (--radius-sm, etc.)\n// are calculated by shadcn's @theme inline block using calc() offsets.\nexport const RADIUS_OPTIONS = {\n none: \"0\",\n small: \"0.3rem\",\n medium: \"0.5rem\",\n large: \"0.75rem\",\n full: \"1rem\",\n} as const;\n\nexport type RadiusOption = keyof typeof RADIUS_OPTIONS;\n","/**\n * Color conversion utilities for Frontic UI CLI\n * Converts hex colors to OKLCH format for CSS variables\n */\n\n/**\n * Validates a hex color string\n * Accepts formats: #RGB, #RRGGBB, RGB, RRGGBB\n */\nexport function isValidHex(hex: string): boolean {\n const cleanHex = hex.replace(/^#/, \"\");\n return /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/.test(cleanHex);\n}\n\n/**\n * Normalizes a hex color to 6-character format without #\n */\nfunction normalizeHex(hex: string): string {\n const cleanHex = hex.replace(/^#/, \"\");\n if (cleanHex.length === 3) {\n return cleanHex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n return cleanHex;\n}\n\n/**\n * Converts hex color to RGB values (0-255)\n */\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n const normalizedHex = normalizeHex(hex);\n return {\n r: parseInt(normalizedHex.slice(0, 2), 16),\n g: parseInt(normalizedHex.slice(2, 4), 16),\n b: parseInt(normalizedHex.slice(4, 6), 16),\n };\n}\n\n/**\n * Converts sRGB to linear RGB\n */\nfunction srgbToLinear(value: number): number {\n const normalized = value / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n}\n\n/**\n * Converts linear RGB to XYZ color space\n */\nfunction linearRgbToXyz(r: number, g: number, b: number): { x: number; y: number; z: number } {\n return {\n x: 0.4124564 * r + 0.3575761 * g + 0.1804375 * b,\n y: 0.2126729 * r + 0.7151522 * g + 0.0721750 * b,\n z: 0.0193339 * r + 0.1191920 * g + 0.9503041 * b,\n };\n}\n\n/**\n * Converts XYZ to OKLAB color space\n */\nfunction xyzToOklab(x: number, y: number, z: number): { l: number; a: number; b: number } {\n const l_ = Math.cbrt(0.8189330101 * x + 0.3618667424 * y - 0.1288597137 * z);\n const m_ = Math.cbrt(0.0329845436 * x + 0.9293118715 * y + 0.0361456387 * z);\n const s_ = Math.cbrt(-0.0482003018 * x + 0.2643662691 * y + 0.6338517070 * z);\n\n return {\n l: 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,\n a: 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,\n b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_,\n };\n}\n\n/**\n * Converts OKLAB to OKLCH color space\n */\nfunction oklabToOklch(l: number, a: number, b: number): { l: number; c: number; h: number } {\n const c = Math.sqrt(a * a + b * b);\n let h = Math.atan2(b, a) * (180 / Math.PI);\n if (h < 0) h += 360;\n\n return { l, c, h };\n}\n\n/**\n * Converts a hex color to OKLCH format string\n * @param hex - Hex color (e.g., \"#6366f1\" or \"6366f1\")\n * @returns OKLCH string (e.g., \"oklch(55% 0.24 265)\")\n */\nexport function hexToOklch(hex: string): string {\n if (!isValidHex(hex)) {\n throw new Error(`Invalid hex color: ${hex}`);\n }\n\n const { r, g, b } = hexToRgb(hex);\n\n // Convert to linear RGB\n const linearR = srgbToLinear(r);\n const linearG = srgbToLinear(g);\n const linearB = srgbToLinear(b);\n\n // Convert to XYZ\n const { x, y, z } = linearRgbToXyz(linearR, linearG, linearB);\n\n // Convert to OKLAB\n const oklab = xyzToOklab(x, y, z);\n\n // Convert to OKLCH\n const { l, c, h } = oklabToOklch(oklab.l, oklab.a, oklab.b);\n\n // Format as OKLCH string\n // Lightness as percentage, chroma with 2 decimals, hue as integer\n const lightness = Math.round(l * 100);\n const chroma = Math.round(c * 100) / 100;\n const hue = Math.round(h);\n\n return `oklch(${lightness}% ${chroma} ${hue})`;\n}\n\n/**\n * Calculates appropriate foreground color (black or white) based on background lightness\n * @param oklchOrHex - Either an OKLCH string or hex color\n * @returns OKLCH string for foreground (white or dark)\n */\nexport function getForegroundColor(oklchOrHex: string): string {\n let lightness: number;\n\n if (oklchOrHex.startsWith(\"oklch\")) {\n // Parse OKLCH string\n const match = oklchOrHex.match(/oklch\\((\\d+)%/);\n lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;\n } else {\n // Convert hex to get lightness\n const oklch = hexToOklch(oklchOrHex);\n const match = oklch.match(/oklch\\((\\d+)%/);\n lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;\n }\n\n // Use white foreground for dark backgrounds, dark for light backgrounds\n return lightness > 0.6 ? \"oklch(20% 0 0)\" : \"oklch(100% 0 0)\";\n}\n","import { readFile, writeFile } from \"fs/promises\";\n\n/**\n * Upsert a CSS variable in a CSS content string.\n * If the variable exists, replace its value. If not, add it at the end.\n */\nfunction upsertCssVar(content: string, varName: string, value: string): string {\n const varRegex = new RegExp(`(${varName}\\\\s*:\\\\s*)([^;]+)(;)`, \"g\");\n\n if (varRegex.test(content)) {\n // Variable exists, replace its value\n return content.replace(varRegex, `$1${value}$3`);\n } else {\n // Variable doesn't exist, add it before the closing brace area\n // Add with proper indentation\n return content.trimEnd() + `\\n ${varName}: ${value};`;\n }\n}\n\n/**\n * Inject CSS variables into the :root block of a CSS file.\n * Handles both adding new variables and updating existing ones.\n */\nexport async function injectCssVars(\n cssPath: string,\n vars: { brand: string; brandForeground: string; radius: string }\n): Promise<void> {\n const content = await readFile(cssPath, \"utf-8\");\n\n // Match :root { ... } block - use a more robust pattern that handles nested content\n const rootRegex = /:root\\s*\\{([^}]*)\\}/;\n const match = content.match(rootRegex);\n\n if (match && match[1] !== undefined) {\n let rootContent = match[1];\n\n // Add or replace --brand, --brand-foreground, --radius\n rootContent = upsertCssVar(rootContent, \"--brand\", vars.brand);\n rootContent = upsertCssVar(\n rootContent,\n \"--brand-foreground\",\n vars.brandForeground\n );\n rootContent = upsertCssVar(rootContent, \"--radius\", vars.radius);\n\n const newContent = content.replace(rootRegex, `:root {${rootContent}\\n}`);\n await writeFile(cssPath, newContent);\n } else {\n // No :root block found, create one at the beginning\n const rootBlock = `:root {\n --brand: ${vars.brand};\n --brand-foreground: ${vars.brandForeground};\n --radius: ${vars.radius};\n}\n\n`;\n await writeFile(cssPath, rootBlock + content);\n }\n}\n\n/**\n * Get the CSS file path from components.json config.\n */\nexport function getCssPathFromConfig(config: {\n tailwind?: { css?: string };\n}): string | null {\n return config.tailwind?.css || null;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { ensureFronticRegistry } from \"../utils/config.js\";\n\ninterface AddOptions {\n overwrite?: boolean;\n all?: boolean;\n path?: string;\n yes?: boolean;\n}\n\n/**\n * Resolves component names to their @frontic/ prefixed form.\n *\n * All components go through the Frontic registry proxy which:\n * - Serves Frontic components if available (theme, button, fancy-button, etc.)\n * - Proxies to shadcn-vue for all other components (card, dialog, etc.)\n *\n * This allows the proxy to control routing centrally without CLI updates.\n */\nfunction resolveComponentNames(components: string[]): string[] {\n return components.map((component) => {\n // Already has a registry prefix - leave as-is\n if (component.startsWith(\"@\")) {\n return component;\n }\n // Prefix with @frontic/ - proxy handles the routing\n return `@frontic/${component}`;\n });\n}\n\nexport function registerAddCommand(program: Command) {\n program\n .command(\"add\")\n .description(\"Add components to your project\")\n .argument(\"[components...]\", \"Components to add\")\n .option(\"-o, --overwrite\", \"Overwrite existing files\")\n .option(\"-a, --all\", \"Add all available components\")\n .option(\"-p, --path <path>\", \"Custom installation path\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .action(async (components: string[], options: AddOptions) => {\n await add(components, options);\n });\n}\n\nasync function add(components: string[], options: AddOptions) {\n // Validate input\n if (!options.all && components.length === 0) {\n console.log(chalk.red(\"Error: Please specify components to add or use --all\"));\n console.log();\n console.log(\"Usage:\");\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button dialog card\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add --all\")}`);\n process.exit(1);\n }\n\n // Ensure Frontic registry is configured\n const spinner = ora(\"Checking configuration...\").start();\n try {\n await ensureFronticRegistry();\n spinner.succeed(\"Configuration verified\");\n } catch {\n spinner.fail(\"Configuration error\");\n console.log();\n console.log(chalk.yellow(\"Run `npx @frontic/ui init` first to set up your project.\"));\n process.exit(1);\n }\n\n // Resolve component names (prefix with @frontic/ for proxy routing)\n const resolvedComponents = resolveComponentNames(components);\n\n // Show what we're adding\n if (resolvedComponents.length > 0) {\n console.log(\n chalk.cyan(\"Components:\"),\n resolvedComponents.map((c) => c.replace(\"@frontic/\", \"\")).join(\", \")\n );\n }\n\n // Build shadcn-vue arguments\n const args = [\"add\"];\n\n if (options.all) {\n args.push(\"--all\");\n } else {\n args.push(...resolvedComponents);\n }\n\n if (options.overwrite) {\n args.push(\"--overwrite\");\n }\n\n if (options.path) {\n args.push(\"--path\", options.path);\n }\n\n if (options.yes) {\n args.push(\"--yes\");\n }\n\n console.log();\n console.log(chalk.blue(\"Adding components...\"));\n console.log();\n\n // Run shadcn-vue add\n await spawnShadcn(args);\n\n console.log();\n console.log(chalk.green(\"✓ Components added successfully!\"));\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { writeFile, readFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport prompts from \"prompts\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ntype McpClient = \"claude\" | \"cursor\" | \"vscode\";\n\ninterface McpInitOptions {\n client?: McpClient;\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program\n .command(\"mcp\")\n .description(\"MCP (Model Context Protocol) commands\");\n\n mcp\n .command(\"init\")\n .description(\"Set up MCP for AI assistants\")\n .option(\"-c, --client <client>\", \"Target client (claude, cursor, vscode)\")\n .action(async (options: McpInitOptions) => {\n await initMcp(options);\n });\n}\n\nasync function initMcp(options: McpInitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI - MCP Setup\"));\n console.log(chalk.dim(\"Configure AI assistant integration\"));\n console.log();\n\n let client = options.client as McpClient | undefined;\n\n // Prompt for client if not specified\n if (!client) {\n const response = await prompts({\n type: \"select\",\n name: \"client\",\n message: \"Select your AI client:\",\n choices: [\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Cursor\", value: \"cursor\" },\n { title: \"VS Code\", value: \"vscode\" },\n ],\n });\n\n client = response.client;\n\n if (!client) {\n console.log(chalk.yellow(\"Setup cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Creating MCP configuration...\").start();\n\n try {\n await createMcpConfig(client);\n spinner.succeed(\"MCP configuration created\");\n } catch (error) {\n spinner.fail(\"Failed to create MCP configuration\");\n throw error;\n }\n\n console.log();\n console.log(chalk.green(\"✓ MCP configured successfully!\"));\n console.log();\n console.log(\"Your AI assistant can now:\");\n console.log(chalk.dim(\" • Browse available Frontic UI components\"));\n console.log(chalk.dim(\" • Add components using natural language\"));\n console.log(chalk.dim(' • Example: \"Add a button component\"'));\n console.log();\n}\n\nasync function createMcpConfig(client: McpClient) {\n const config = getMcpConfig();\n const configPath = getMcpConfigPath(client);\n const configDir = join(process.cwd(), configPath.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create directory if needed\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n const fullPath = join(process.cwd(), configPath);\n\n // Read existing config or create new\n let existingConfig: Record<string, unknown> = {};\n try {\n const content = await readFile(fullPath, \"utf-8\");\n existingConfig = JSON.parse(content);\n } catch {\n // File doesn't exist, use empty config\n }\n\n // Merge with existing config\n const mergedConfig = {\n ...existingConfig,\n mcpServers: {\n ...(existingConfig.mcpServers as Record<string, unknown> || {}),\n ...config.mcpServers,\n },\n };\n\n await writeFile(fullPath, JSON.stringify(mergedConfig, null, 2));\n\n console.log(chalk.dim(` Config written to: ${configPath}`));\n}\n\nfunction getMcpConfigPath(client: McpClient): string {\n switch (client) {\n case \"claude\":\n return \".mcp.json\";\n case \"cursor\":\n return \".cursor/mcp.json\";\n case \"vscode\":\n return \".vscode/mcp.json\";\n }\n}\n\nfunction getMcpConfig() {\n return {\n mcpServers: {\n \"frontic-ui\": {\n command: \"npx\",\n args: [\"shadcn-vue@latest\", \"mcp\"],\n env: {\n SHADCN_REGISTRY_URL: FRONTIC_REGISTRY_URL,\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["join","readFile","writeFile","program","join","chalk","ora","program","chalk","ora","chalk","ora","writeFile","readFile","join","prompts","program","chalk","prompts","ora","join","readFile","writeFile"]}
1
+ {"version":3,"file":"index.js","names":["errors: Record<string, boolean>","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","ERRORS.UNSUPPORTED_FRAMEWORK","ERRORS.TAILWIND_NOT_CONFIGURED","ERRORS.IMPORT_ALIAS_MISSING","x","z","lightness: number","decodedPath: string","path","fs","keyframesRule: AtRule","fs","key","value","cssVarNode","envVarsAdded: string[]","envFileUpdated: string | null","envFileCreated: string | null","fs","filesCreated: string[]","filesUpdated: string[]","filesSkipped: string[]","registry","foundRegistries: Record<string, string>","fs","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","fs","brandOklch: string | undefined","brandForeground: string | undefined","style","errors: Record<string, boolean>","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","ERRORS.MISSING_CONFIG","updatedConfig","itemType: z.infer<typeof registryItemTypeSchema> | undefined","ERRORS.MISSING_CONFIG","errors: Record<string, boolean>","fs","ERRORS.BUILD_MISSING_REGISTRY_FILE","path","result","component","changes","fs","z","fs","fs","targetedIcons: string[]","errors: Record<string, boolean>","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","ERRORS.MISSING_CONFIG","migration","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","ERRORS.MISSING_CONFIG","packageJson.version"],"sources":["../src/utils/errors.ts","../src/preflights/preflight-init.ts","../src/utils/frontic-colors.ts","../src/utils/is-safe-target.ts","../src/utils/updaters/update-css.ts","../src/utils/updaters/update-css-vars.ts","../src/utils/updaters/update-dependencies.ts","../src/utils/updaters/update-env-vars.ts","../src/utils/add-components.ts","../src/utils/env-loader.ts","../src/utils/file-helper.ts","../src/registry/namespaces.ts","../src/utils/registries.ts","../src/utils/updaters/update-tailwind-content.ts","../src/commands/init.ts","../src/preflights/preflight-add.ts","../src/commands/add.ts","../src/preflights/preflight-build.ts","../src/commands/build.ts","../src/commands/diff.ts","../src/commands/info.ts","../src/commands/mcp.ts","../src/migrations/migrate-icons.ts","../src/preflights/preflight-migrate.ts","../src/commands/migrate.ts","../package.json","../src/index.ts"],"sourcesContent":["export const MISSING_DIR_OR_EMPTY_PROJECT = '1'\nexport const EXISTING_CONFIG = '2'\nexport const MISSING_CONFIG = '3'\nexport const FAILED_CONFIG_READ = '4'\nexport const TAILWIND_NOT_CONFIGURED = '5'\nexport const IMPORT_ALIAS_MISSING = '6'\nexport const UNSUPPORTED_FRAMEWORK = '7'\nexport const COMPONENT_URL_NOT_FOUND = '8'\nexport const COMPONENT_URL_UNAUTHORIZED = '9'\nexport const COMPONENT_URL_FORBIDDEN = '10'\nexport const COMPONENT_URL_BAD_REQUEST = '11'\nexport const COMPONENT_URL_INTERNAL_SERVER_ERROR = '12'\nexport const BUILD_MISSING_REGISTRY_FILE = '13'\n","import type { z } from 'zod'\nimport type { initOptionsSchema } from '@/src/commands/init'\nimport fs from 'fs-extra'\nimport path from 'pathe'\nimport * as ERRORS from '@/src/utils/errors'\nimport { getProjectInfo } from '@/src/utils/get-project-info'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function preFlightInit(\n options: z.infer<typeof initOptionsSchema>,\n) {\n const errors: Record<string, boolean> = {}\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd)\n || !fs.existsSync(path.resolve(options.cwd, 'package.json'))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true\n return {\n errors,\n projectInfo: null,\n }\n }\n\n const projectSpinner = spinner(`Preflight checks.`, {\n silent: options.silent,\n }).start()\n\n if (\n fs.existsSync(path.resolve(options.cwd, 'components.json'))\n && !options.force\n ) {\n projectSpinner?.fail()\n logger.break()\n logger.error(\n `A ${highlighter.info(\n 'components.json',\n )} file already exists at ${highlighter.info(\n options.cwd,\n )}.\\nTo start over, remove the ${highlighter.info(\n 'components.json',\n )} file and run ${highlighter.info('init')} again.`,\n )\n logger.break()\n process.exit(1)\n }\n\n projectSpinner?.succeed()\n\n const frameworkSpinner = spinner(`Verifying framework.`, {\n silent: options.silent,\n }).start()\n const projectInfo = await getProjectInfo(options.cwd)\n if (!projectInfo || projectInfo?.framework.name === 'manual') {\n errors[ERRORS.UNSUPPORTED_FRAMEWORK] = true\n frameworkSpinner?.fail()\n logger.break()\n if (projectInfo?.framework.links.installation) {\n logger.error(\n `We could not detect a supported framework at ${highlighter.info(\n options.cwd,\n )}.\\n`\n + `Visit ${highlighter.info(\n projectInfo?.framework.links.installation,\n )} to manually configure your project.\\nOnce configured, you can use the cli to add components.`,\n )\n }\n logger.break()\n process.exit(1)\n }\n frameworkSpinner?.succeed(\n `Verifying framework. Found ${highlighter.info(\n projectInfo.framework.label,\n )}.`,\n )\n\n let tailwindSpinnerMessage = 'Validating Tailwind CSS.'\n\n if (projectInfo.tailwindVersion === 'v4') {\n tailwindSpinnerMessage = `Validating Tailwind CSS config. Found ${highlighter.info(\n 'v4',\n )}.`\n }\n\n const tailwindSpinner = spinner(tailwindSpinnerMessage, {\n silent: options.silent,\n }).start()\n if (\n projectInfo.tailwindVersion === 'v3'\n && (!projectInfo?.tailwindConfigFile || !projectInfo?.tailwindCssFile)\n ) {\n errors[ERRORS.TAILWIND_NOT_CONFIGURED] = true\n tailwindSpinner?.fail()\n }\n else if (\n projectInfo.tailwindVersion === 'v4'\n && !projectInfo?.tailwindCssFile\n ) {\n errors[ERRORS.TAILWIND_NOT_CONFIGURED] = true\n tailwindSpinner?.fail()\n }\n else if (!projectInfo.tailwindVersion) {\n errors[ERRORS.TAILWIND_NOT_CONFIGURED] = true\n tailwindSpinner?.fail()\n }\n else {\n tailwindSpinner?.succeed()\n }\n\n const tsConfigSpinner = spinner(`Validating import alias.`, {\n silent: options.silent,\n }).start()\n if (!projectInfo?.aliasPrefix) {\n errors[ERRORS.IMPORT_ALIAS_MISSING] = true\n tsConfigSpinner?.fail()\n }\n else {\n tsConfigSpinner?.succeed()\n }\n\n if (Object.keys(errors).length > 0) {\n if (errors[ERRORS.TAILWIND_NOT_CONFIGURED]) {\n logger.break()\n logger.error(\n `No Tailwind CSS configuration found at ${highlighter.info(\n options.cwd,\n )}.`,\n )\n logger.error(\n `It is likely you do not have Tailwind CSS installed or have an invalid configuration.`,\n )\n logger.error(`Install Tailwind CSS then try again.`)\n if (projectInfo?.framework.links.tailwind) {\n logger.error(\n `Visit ${highlighter.info(\n projectInfo?.framework.links.tailwind,\n )} to get started.`,\n )\n }\n }\n\n if (errors[ERRORS.IMPORT_ALIAS_MISSING]) {\n logger.break()\n logger.error(`No import alias found in your tsconfig.json file.`)\n if (projectInfo?.framework.links.installation) {\n logger.error(\n `Visit ${highlighter.info(\n projectInfo?.framework.links.installation,\n )} to learn how to set an import alias.`,\n )\n }\n }\n\n logger.break()\n process.exit(1)\n }\n\n return {\n errors,\n projectInfo,\n }\n}\n","/**\n * Color conversion utilities for Frontic UI CLI\n * Converts hex colors to OKLCH format for CSS variables\n */\n\n/**\n * Validates a hex color string\n * Accepts formats: #RGB, #RRGGBB, RGB, RRGGBB\n */\nexport function isValidHex(hex: string): boolean {\n const cleanHex = hex.replace(/^#/, \"\");\n return /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/.test(cleanHex);\n}\n\n/**\n * Normalizes a hex color to 6-character format without #\n */\nfunction normalizeHex(hex: string): string {\n const cleanHex = hex.replace(/^#/, \"\");\n if (cleanHex.length === 3) {\n return cleanHex\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n return cleanHex;\n}\n\n/**\n * Converts hex color to RGB values (0-255)\n */\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n const normalizedHex = normalizeHex(hex);\n return {\n r: parseInt(normalizedHex.slice(0, 2), 16),\n g: parseInt(normalizedHex.slice(2, 4), 16),\n b: parseInt(normalizedHex.slice(4, 6), 16),\n };\n}\n\n/**\n * Converts sRGB to linear RGB\n */\nfunction srgbToLinear(value: number): number {\n const normalized = value / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n}\n\n/**\n * Converts linear RGB to XYZ color space\n */\nfunction linearRgbToXyz(r: number, g: number, b: number): { x: number; y: number; z: number } {\n return {\n x: 0.4124564 * r + 0.3575761 * g + 0.1804375 * b,\n y: 0.2126729 * r + 0.7151522 * g + 0.0721750 * b,\n z: 0.0193339 * r + 0.1191920 * g + 0.9503041 * b,\n };\n}\n\n/**\n * Converts XYZ to OKLAB color space\n */\nfunction xyzToOklab(x: number, y: number, z: number): { l: number; a: number; b: number } {\n const l_ = Math.cbrt(0.8189330101 * x + 0.3618667424 * y - 0.1288597137 * z);\n const m_ = Math.cbrt(0.0329845436 * x + 0.9293118715 * y + 0.0361456387 * z);\n const s_ = Math.cbrt(-0.0482003018 * x + 0.2643662691 * y + 0.6338517070 * z);\n\n return {\n l: 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,\n a: 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,\n b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_,\n };\n}\n\n/**\n * Converts OKLAB to OKLCH color space\n */\nfunction oklabToOklch(l: number, a: number, b: number): { l: number; c: number; h: number } {\n const c = Math.sqrt(a * a + b * b);\n let h = Math.atan2(b, a) * (180 / Math.PI);\n if (h < 0) h += 360;\n\n return { l, c, h };\n}\n\n/**\n * Converts a hex color to OKLCH format string\n * @param hex - Hex color (e.g., \"#6366f1\" or \"6366f1\")\n * @returns OKLCH string (e.g., \"oklch(55% 0.24 265)\")\n */\nexport function hexToOklch(hex: string): string {\n if (!isValidHex(hex)) {\n throw new Error(`Invalid hex color: ${hex}`);\n }\n\n const { r, g, b } = hexToRgb(hex);\n\n // Convert to linear RGB\n const linearR = srgbToLinear(r);\n const linearG = srgbToLinear(g);\n const linearB = srgbToLinear(b);\n\n // Convert to XYZ\n const { x, y, z } = linearRgbToXyz(linearR, linearG, linearB);\n\n // Convert to OKLAB\n const oklab = xyzToOklab(x, y, z);\n\n // Convert to OKLCH\n const { l, c, h } = oklabToOklch(oklab.l, oklab.a, oklab.b);\n\n // Format as OKLCH string\n // Lightness as percentage, chroma with 2 decimals, hue as integer\n const lightness = Math.round(l * 100);\n const chroma = Math.round(c * 100) / 100;\n const hue = Math.round(h);\n\n return `oklch(${lightness}% ${chroma} ${hue})`;\n}\n\n/**\n * Calculates appropriate foreground color (black or white) based on background lightness\n * @param oklchOrHex - Either an OKLCH string or hex color\n * @returns OKLCH string for foreground (white or dark)\n */\nexport function getForegroundColor(oklchOrHex: string): string {\n let lightness: number;\n\n if (oklchOrHex.startsWith(\"oklch\")) {\n // Parse OKLCH string\n const match = oklchOrHex.match(/oklch\\((\\d+)%/);\n lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;\n } else {\n // Convert hex to get lightness\n const oklch = hexToOklch(oklchOrHex);\n const match = oklch.match(/oklch\\((\\d+)%/);\n lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;\n }\n\n // Use white foreground for dark backgrounds, dark for light backgrounds\n return lightness > 0.6 ? \"oklch(20% 0 0)\" : \"oklch(100% 0 0)\";\n}\n","import {\n isAbsolute,\n normalize,\n resolve,\n sep,\n} from 'pathe'\n\nexport function isSafeTarget(targetPath: string, cwd: string): boolean {\n // Check for null bytes which can be used to bypass validations.\n if (targetPath.includes('\\0')) {\n return false\n }\n\n // Decode URL-encoded sequences to catch encoded traversal attempts.\n let decodedPath: string\n try {\n decodedPath = targetPath\n let prevPath = ''\n while (decodedPath !== prevPath && decodedPath.includes('%')) {\n prevPath = decodedPath\n decodedPath = decodeURIComponent(decodedPath)\n }\n }\n catch {\n return false\n }\n\n // Normalize both paths to handle separators\n const normalizedTarget = normalize(decodedPath)\n const normalizedRoot = normalize(cwd)\n\n // Check for explicit path traversal sequences in both encoded and decoded forms.\n // Allow [...] pattern which is common in framework routing (e.g., [...slug])\n const hasPathTraversal = (path: string) => {\n // Remove [...] patterns before checking for ..\n const withoutBrackets = path.replace(/\\[\\.\\.\\..*?\\]/g, '')\n return withoutBrackets.includes('..')\n }\n\n // Check for explicit traversal indicators\n if (\n hasPathTraversal(normalizedTarget)\n || hasPathTraversal(decodedPath)\n || hasPathTraversal(targetPath)\n ) {\n return false\n }\n\n // Check for current directory references that might be used in traversal.\n // First, remove [...] patterns to avoid false positives\n const cleanPath = (path: string) => path.replace(/\\[\\.\\.\\..*?\\]/g, '')\n const cleanTarget = cleanPath(targetPath)\n const cleanDecoded = cleanPath(decodedPath)\n\n // Check for suspicious patterns\n const suspiciousPatterns = [\n /\\.\\.[/\\\\]/,\n /[/\\\\]\\.\\./,\n /\\.\\./,\n /\\.\\.%/,\n /\\0/,\n // eslint-disable-next-line no-control-regex\n /[\\x01-\\x1F]/,\n ]\n\n if (\n suspiciousPatterns.some(\n pattern => pattern.test(cleanTarget) || pattern.test(cleanDecoded),\n )\n ) {\n return false\n }\n\n // Check for unsafe use of ~\n if (\n (targetPath.includes('~') || decodedPath.includes('~'))\n && (targetPath.includes('../') || decodedPath.includes('../'))\n ) {\n return false\n }\n\n // Reject Windows drive letter absolute paths on non-Windows\n const driveLetterRegex = /^[a-z]:[/\\\\]/i\n if (driveLetterRegex.test(decodedPath)) {\n if (process.platform === 'win32') {\n return decodedPath.toLowerCase().startsWith(cwd.toLowerCase())\n }\n return false\n }\n\n // Final absolute path resolution\n const absoluteTarget = isAbsolute(normalizedTarget)\n ? normalizedTarget\n : resolve(normalizedRoot, normalizedTarget)\n\n const safeRoot = normalizedRoot.endsWith(sep)\n ? normalizedRoot\n : normalizedRoot + sep\n\n return (\n absoluteTarget === normalizedRoot\n || absoluteTarget.startsWith(safeRoot)\n )\n}\n","import type AtRule from 'postcss/lib/at-rule'\nimport type Declaration from 'postcss/lib/declaration'\nimport type Root from 'postcss/lib/root'\nimport type Rule from 'postcss/lib/rule'\nimport type { z } from 'zod'\nimport type { registryItemCssSchema } from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport { promises as fs } from 'node:fs'\nimport path from 'pathe'\nimport postcss from 'postcss'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function updateCss(\n css: z.infer<typeof registryItemCssSchema> | undefined,\n config: Config,\n options: {\n silent?: boolean\n },\n) {\n if (\n !config.resolvedPaths.tailwindCss\n || !css\n || Object.keys(css).length === 0\n ) {\n return\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const cssFilepath = config.resolvedPaths.tailwindCss\n const cssFilepathRelative = path.relative(\n config.resolvedPaths.cwd,\n cssFilepath,\n )\n const cssSpinner = spinner(\n `Updating ${highlighter.info(cssFilepathRelative)}`,\n {\n silent: options.silent,\n },\n ).start()\n\n const raw = await fs.readFile(cssFilepath, 'utf8')\n // eslint-disable-next-line prefer-const\n let output = await transformCss(raw, css)\n await fs.writeFile(cssFilepath, output, 'utf8')\n cssSpinner.succeed()\n}\n\nexport async function transformCss(\n input: string,\n css: z.infer<typeof registryItemCssSchema>,\n) {\n const plugins = [updateCssPlugin(css)]\n\n const result = await postcss(plugins).process(input, {\n from: undefined,\n })\n\n let output = result.css\n\n // PostCSS doesn't add semicolons to at-rules without bodies when they're the last node.\n // We need to manually ensure they have semicolons.\n const root = result.root\n if (root.nodes && root.nodes.length > 0) {\n const lastNode = root.nodes[root.nodes.length - 1]\n if (\n lastNode.type === 'atrule'\n && !lastNode.nodes\n && !output.trimEnd().endsWith(';')\n ) {\n output = `${output.trimEnd()};`\n }\n }\n\n output = output.replace(/\\/\\* ---break--- \\*\\//g, '')\n output = output.replace(/(\\n\\s*\\n)+/g, '\\n\\n')\n output = output.trimEnd()\n\n return output\n}\n\nfunction updateCssPlugin(css: z.infer<typeof registryItemCssSchema>) {\n return {\n postcssPlugin: 'update-css',\n Once(root: Root) {\n for (const [selector, properties] of Object.entries(css)) {\n if (selector.startsWith('@')) {\n // Handle at-rules (@layer, @utility, etc.)\n const atRuleMatch = selector.match(/@([a-z-]+)\\s*(.*)/i)\n if (!atRuleMatch)\n continue\n\n const [, name, params] = atRuleMatch\n\n // Special handling for imports - place them at the top.\n if (name === 'import') {\n // Check if this import already exists.\n const existingImport = root.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === 'import'\n && node.params === params,\n )\n\n if (!existingImport) {\n const importRule = postcss.atRule({\n name: 'import',\n params,\n raws: { semicolon: true },\n })\n\n // Find the last import to insert after, or insert at beginning.\n const importNodes = root.nodes?.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'import',\n )\n\n if (importNodes && importNodes.length > 0) {\n // Insert after the last existing import.\n const lastImport = importNodes[importNodes.length - 1]\n importRule.raws.before = '\\n'\n root.insertAfter(lastImport, importRule)\n }\n else {\n // No imports exist, insert at the very beginning.\n // Check if the file is empty.\n if (!root.nodes || root.nodes.length === 0) {\n importRule.raws.before = ''\n }\n else {\n importRule.raws.before = ''\n }\n root.prepend(importRule)\n }\n }\n }\n // Special handling for plugins - place them after imports.\n else if (name === 'plugin') {\n // Ensure plugin name is quoted if not already.\n let quotedParams = params\n if (params && !params.startsWith('\"') && !params.startsWith('\\'')) {\n quotedParams = `\"${params}\"`\n }\n\n // Normalize params for comparison (remove quotes).\n const normalizeParams = (p: string) => {\n if (p.startsWith('\"') && p.endsWith('\"')) {\n return p.slice(1, -1)\n }\n if (p.startsWith('\\'') && p.endsWith('\\'')) {\n return p.slice(1, -1)\n }\n return p\n }\n\n // Find existing plugin with same normalized params.\n const existingPlugin = root.nodes?.find((node): node is AtRule => {\n if (node.type !== 'atrule' || node.name !== 'plugin') {\n return false\n }\n return normalizeParams(node.params) === normalizeParams(params)\n })\n\n if (!existingPlugin) {\n const pluginRule = postcss.atRule({\n name: 'plugin',\n params: quotedParams,\n raws: { semicolon: true, before: '\\n' },\n })\n\n // Find the last import or plugin node to insert after\n const importNodes = root.nodes?.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'import',\n )\n\n const pluginNodes = root.nodes?.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'plugin',\n )\n\n if (pluginNodes && pluginNodes.length > 0) {\n // Insert after the last existing plugin\n const lastPlugin = pluginNodes[pluginNodes.length - 1]\n root.insertAfter(lastPlugin, pluginRule)\n }\n else if (importNodes && importNodes.length > 0) {\n // Insert after the last import if no plugins exist\n const lastImport = importNodes[importNodes.length - 1]\n root.insertAfter(lastImport, pluginRule)\n // Add a break comment before the first plugin to create spacing\n root.insertBefore(\n pluginRule,\n postcss.comment({ text: '---break---' }),\n )\n // Add a break comment after the plugin for spacing from other content\n root.insertAfter(\n pluginRule,\n postcss.comment({ text: '---break---' }),\n )\n }\n else {\n // If no imports or plugins, insert at the beginning\n root.prepend(pluginRule)\n // Add a break comment before the first plugin for spacing\n root.insertBefore(\n pluginRule,\n postcss.comment({ text: '---break---' }),\n )\n // Add a break comment after the plugin for spacing from other content\n root.insertAfter(\n pluginRule,\n postcss.comment({ text: '---break---' }),\n )\n }\n }\n }\n // Check if this is any at-rule with no body (empty object).\n else if (\n typeof properties === 'object'\n && Object.keys(properties).length === 0\n ) {\n // Handle any at-rule with no body (e.g., @apply, @tailwind, etc.).\n const atRule = root.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === name\n && node.params === params,\n ) as AtRule | undefined\n\n if (!atRule) {\n const newAtRule = postcss.atRule({\n name,\n params,\n raws: { semicolon: true },\n })\n\n root.append(newAtRule)\n root.insertBefore(\n newAtRule,\n postcss.comment({ text: '---break---' }),\n )\n }\n }\n // Special handling for keyframes - place them under @theme inline.\n else if (name === 'keyframes') {\n let themeInline = root.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === 'theme'\n && node.params === 'inline',\n ) as AtRule | undefined\n\n if (!themeInline) {\n themeInline = postcss.atRule({\n name: 'theme',\n params: 'inline',\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n root.append(themeInline)\n root.insertBefore(\n themeInline,\n postcss.comment({ text: '---break---' }),\n )\n }\n\n // Check if a keyframe with the same name already exists\n const existingKeyframesRule = themeInline.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === 'keyframes'\n && node.params === params,\n )\n\n let keyframesRule: AtRule\n if (existingKeyframesRule) {\n // Replace existing keyframe\n keyframesRule = postcss.atRule({\n name: 'keyframes',\n params,\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n existingKeyframesRule.replaceWith(keyframesRule)\n }\n else {\n // Create new keyframe\n keyframesRule = postcss.atRule({\n name: 'keyframes',\n params,\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n themeInline.append(keyframesRule)\n }\n\n if (typeof properties === 'object') {\n for (const [step, stepProps] of Object.entries(properties)) {\n processRule(keyframesRule, step, stepProps)\n }\n }\n }\n // Special handling for utility classes to preserve property values\n else if (name === 'utility') {\n const utilityAtRule = root.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === name\n && node.params === params,\n ) as AtRule | undefined\n\n if (!utilityAtRule) {\n const atRule = postcss.atRule({\n name,\n params,\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n\n root.append(atRule)\n root.insertBefore(\n atRule,\n postcss.comment({ text: '---break---' }),\n )\n\n // Add declarations with their values preserved\n if (typeof properties === 'object') {\n for (const [prop, value] of Object.entries(properties)) {\n if (typeof value === 'string') {\n const decl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true, before: '\\n ' },\n })\n atRule.append(decl)\n }\n else if (typeof value === 'object') {\n processRule(atRule, prop, value)\n }\n }\n }\n }\n else {\n // Update existing utility class\n if (typeof properties === 'object') {\n for (const [prop, value] of Object.entries(properties)) {\n if (typeof value === 'string') {\n const existingDecl = utilityAtRule.nodes?.find(\n (node): node is Declaration =>\n node.type === 'decl' && node.prop === prop,\n )\n\n const decl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true, before: '\\n ' },\n })\n\n if (existingDecl) {\n existingDecl.replaceWith(decl)\n }\n else {\n utilityAtRule.append(decl)\n }\n }\n else if (typeof value === 'object') {\n processRule(utilityAtRule, prop, value)\n }\n }\n }\n }\n }\n // Handle at-property as regular CSS rules\n else if (name === 'property') {\n processRule(root, selector, properties)\n }\n else {\n // Handle other at-rules normally\n processAtRule(root, name, params, properties)\n }\n }\n else {\n // Handle regular CSS rules\n processRule(root, selector, properties)\n }\n }\n },\n }\n}\n\nfunction processAtRule(\n root: Root | AtRule,\n name: string,\n params: string,\n properties: any,\n) {\n // Find or create the at-rule\n let atRule = root.nodes?.find(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === name && node.params === params,\n ) as AtRule | undefined\n\n if (!atRule) {\n atRule = postcss.atRule({\n name,\n params,\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n root.append(atRule)\n root.insertBefore(atRule, postcss.comment({ text: '---break---' }))\n }\n\n // Process children of this at-rule\n if (typeof properties === 'object') {\n for (const [childSelector, childProps] of Object.entries(properties)) {\n if (childSelector.startsWith('@')) {\n // Nested at-rule\n const nestedMatch = childSelector.match(/@([a-z-]+)\\s*(.*)/i)\n if (nestedMatch) {\n const [, nestedName, nestedParams] = nestedMatch\n processAtRule(atRule, nestedName, nestedParams, childProps)\n }\n }\n else {\n // CSS rule within at-rule\n processRule(atRule, childSelector, childProps)\n }\n }\n }\n else if (typeof properties === 'string') {\n // Direct string content for the at-rule\n try {\n // Parse the CSS string with PostCSS\n const parsed = postcss.parse(`.temp{${properties}}`)\n const tempRule = parsed.first as Rule\n\n if (tempRule && tempRule.nodes) {\n // Create a rule for the at-rule if needed\n const rule = postcss.rule({\n selector: 'temp',\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n\n // Copy all declarations from the temp rule to our actual rule\n tempRule.nodes.forEach((node) => {\n if (node.type === 'decl') {\n const clone = node.clone()\n clone.raws.before = '\\n '\n rule.append(clone)\n }\n })\n\n // Only add the rule if it has declarations\n if (rule.nodes?.length) {\n atRule.append(rule)\n }\n }\n }\n catch (error) {\n console.error('Error parsing at-rule content:', properties, error)\n throw error\n }\n }\n}\n\nfunction processRule(parent: Root | AtRule, selector: string, properties: any) {\n let rule = parent.nodes?.find(\n (node): node is Rule => node.type === 'rule' && node.selector === selector,\n ) as Rule | undefined\n\n if (!rule) {\n rule = postcss.rule({\n selector,\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n parent.append(rule)\n }\n\n if (typeof properties === 'object') {\n for (const [prop, value] of Object.entries(properties)) {\n // Check if this is any at-rule with empty object (no body).\n if (\n prop.startsWith('@')\n && typeof value === 'object'\n && value !== null\n && Object.keys(value).length === 0\n ) {\n // Parse the at-rule.\n const atRuleMatch = prop.match(/@([a-z-]+)\\s*(.*)/i)\n if (atRuleMatch) {\n const [, atRuleName, atRuleParams] = atRuleMatch\n const atRule = postcss.atRule({\n name: atRuleName,\n params: atRuleParams,\n raws: { semicolon: true, before: '\\n ' },\n })\n rule.append(atRule)\n }\n }\n else if (typeof value === 'string') {\n const decl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true, before: '\\n ' },\n })\n\n // Replace existing property or add new one.\n const existingDecl = rule.nodes?.find(\n (node): node is Declaration =>\n node.type === 'decl' && node.prop === prop,\n )\n\n if (existingDecl) {\n existingDecl.replaceWith(decl)\n }\n else {\n rule.append(decl)\n }\n }\n else if (typeof value === 'object') {\n // Nested selector (including & selectors).\n const nestedSelector = prop.startsWith('&')\n ? selector.replace(/^([^:]+)/, `$1${prop.substring(1)}`)\n : prop // Use the original selector for other nested elements.\n processRule(parent, nestedSelector, value)\n }\n }\n }\n else if (typeof properties === 'string') {\n // Direct string content for the rule\n try {\n // Parse the CSS string with PostCSS\n const parsed = postcss.parse(`.temp{${properties}}`)\n const tempRule = parsed.first as Rule\n\n if (tempRule && tempRule.nodes) {\n // Copy all declarations from the temp rule to our actual rule\n tempRule.nodes.forEach((node) => {\n if (node.type === 'decl') {\n const clone = node.clone()\n clone.raws.before = '\\n '\n rule?.append(clone)\n }\n })\n }\n }\n catch (error) {\n console.error('Error parsing rule content:', selector, properties, error)\n throw error\n }\n }\n}\n","import type Root from 'postcss/lib/root'\nimport type Rule from 'postcss/lib/rule'\nimport type {\n registryItemCssVarsSchema,\n registryItemTailwindSchema,\n} from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport type { TailwindVersion } from '@/src/utils/get-project-info'\nimport { promises as fs } from 'node:fs'\nimport path from 'pathe'\nimport postcss from 'postcss'\nimport AtRule from 'postcss/lib/at-rule'\nimport { z } from 'zod'\nimport { getPackageInfo } from '@/src/utils/get-package-info'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function updateCssVars(\n cssVars: z.infer<typeof registryItemCssVarsSchema> | undefined,\n config: Config,\n options: {\n cleanupDefaultNextStyles?: boolean\n overwriteCssVars?: boolean\n initIndex?: boolean\n silent?: boolean\n tailwindVersion?: TailwindVersion\n tailwindConfig?: z.infer<typeof registryItemTailwindSchema>['config']\n },\n) {\n if (!config.resolvedPaths.tailwindCss || !Object.keys(cssVars ?? {}).length) {\n return\n }\n\n options = {\n cleanupDefaultNextStyles: false,\n silent: false,\n tailwindVersion: 'v3',\n overwriteCssVars: false,\n initIndex: true,\n ...options,\n }\n const cssFilepath = config.resolvedPaths.tailwindCss\n const cssFilepathRelative = path.relative(\n config.resolvedPaths.cwd,\n cssFilepath,\n )\n const cssVarsSpinner = spinner(\n `Updating CSS variables in ${highlighter.info(cssFilepathRelative)}`,\n {\n silent: options.silent,\n },\n ).start()\n const raw = await fs.readFile(cssFilepath, 'utf8')\n const output = await transformCssVars(raw, cssVars ?? {}, config, {\n cleanupDefaultNextStyles: options.cleanupDefaultNextStyles,\n tailwindVersion: options.tailwindVersion,\n tailwindConfig: options.tailwindConfig,\n overwriteCssVars: options.overwriteCssVars,\n initIndex: options.initIndex,\n })\n await fs.writeFile(cssFilepath, output, 'utf8')\n cssVarsSpinner.succeed()\n}\n\nexport async function transformCssVars(\n input: string,\n cssVars: z.infer<typeof registryItemCssVarsSchema>,\n config: Config,\n options: {\n cleanupDefaultNextStyles?: boolean\n tailwindVersion?: TailwindVersion\n tailwindConfig?: z.infer<typeof registryItemTailwindSchema>['config']\n overwriteCssVars?: boolean\n initIndex?: boolean\n } = {\n cleanupDefaultNextStyles: false,\n tailwindVersion: 'v3',\n tailwindConfig: undefined,\n overwriteCssVars: false,\n initIndex: true,\n },\n) {\n options = {\n cleanupDefaultNextStyles: false,\n tailwindVersion: 'v3',\n tailwindConfig: undefined,\n overwriteCssVars: false,\n initIndex: true,\n ...options,\n }\n\n let plugins = [updateCssVarsPlugin(cssVars)]\n\n if (options.cleanupDefaultNextStyles) {\n plugins.push(cleanupDefaultNextStylesPlugin())\n }\n\n if (options.tailwindVersion === 'v4') {\n plugins = []\n\n // Only add tw-animate-css if project does not have tailwindcss-animate\n if (config.resolvedPaths?.cwd) {\n const packageInfo = getPackageInfo(config.resolvedPaths.cwd)\n if (\n !packageInfo?.dependencies?.['tailwindcss-animate']\n && !packageInfo?.devDependencies?.['tailwindcss-animate']\n && options.initIndex\n ) {\n plugins.push(addCustomImport({ params: 'tw-animate-css' }))\n }\n }\n\n plugins.push(addCustomVariant({ params: 'dark (&:is(.dark *))' }))\n\n if (options.cleanupDefaultNextStyles) {\n plugins.push(cleanupDefaultNextStylesPlugin())\n }\n\n plugins.push(\n updateCssVarsPluginV4(cssVars, {\n overwriteCssVars: options.overwriteCssVars,\n }),\n )\n plugins.push(updateThemePlugin(cssVars))\n\n if (options.tailwindConfig) {\n plugins.push(updateTailwindConfigPlugin(options.tailwindConfig))\n plugins.push(updateTailwindConfigAnimationPlugin(options.tailwindConfig))\n plugins.push(updateTailwindConfigKeyframesPlugin(options.tailwindConfig))\n }\n }\n\n if (config.tailwind.cssVariables && options.initIndex) {\n plugins.push(\n updateBaseLayerPlugin({ tailwindVersion: options.tailwindVersion }),\n )\n }\n\n const result = await postcss(plugins).process(input, {\n from: undefined,\n })\n\n let output = result.css\n\n output = output.replace(/\\/\\* ---break--- \\*\\//g, '')\n\n if (options.tailwindVersion === 'v4') {\n output = output.replace(/(\\n\\s*\\n)+/g, '\\n\\n')\n }\n\n return output\n}\n\nfunction updateBaseLayerPlugin({\n tailwindVersion,\n}: {\n tailwindVersion?: TailwindVersion\n}) {\n return {\n postcssPlugin: 'update-base-layer',\n Once(root: Root) {\n const requiredRules = [\n {\n selector: '*',\n apply:\n tailwindVersion === 'v4'\n ? 'border-border outline-ring/50'\n : 'border-border',\n },\n { selector: 'body', apply: 'bg-background text-foreground' },\n ]\n\n let baseLayer = root.nodes.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === 'layer'\n && node.params === 'base'\n && requiredRules.every(({ selector, apply }) =>\n node.nodes?.some(\n (rule): rule is Rule =>\n rule.type === 'rule'\n && rule.selector === selector\n && rule.nodes.some(\n (applyRule): applyRule is AtRule =>\n applyRule.type === 'atrule'\n && applyRule.name === 'apply'\n && applyRule.params === apply,\n ),\n ),\n ),\n ) as AtRule | undefined\n\n if (!baseLayer) {\n baseLayer = postcss.atRule({\n name: 'layer',\n params: 'base',\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n root.append(baseLayer)\n root.insertBefore(baseLayer, postcss.comment({ text: '---break---' }))\n }\n\n requiredRules.forEach(({ selector, apply }) => {\n const existingRule = baseLayer?.nodes?.find(\n (node): node is Rule =>\n node.type === 'rule' && node.selector === selector,\n )\n\n if (!existingRule) {\n baseLayer?.append(\n postcss.rule({\n selector,\n nodes: [\n postcss.atRule({\n name: 'apply',\n params: apply,\n raws: { semicolon: true, before: '\\n ' },\n }),\n ],\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n }),\n )\n }\n })\n },\n }\n}\n\nfunction updateCssVarsPlugin(\n cssVars: z.infer<typeof registryItemCssVarsSchema>,\n) {\n return {\n postcssPlugin: 'update-css-vars',\n Once(root: Root) {\n let baseLayer = root.nodes.find(\n node =>\n node.type === 'atrule'\n && node.name === 'layer'\n && node.params === 'base',\n ) as AtRule | undefined\n\n if (!(baseLayer instanceof AtRule)) {\n baseLayer = postcss.atRule({\n name: 'layer',\n params: 'base',\n nodes: [],\n raws: {\n semicolon: true,\n before: '\\n',\n between: ' ',\n },\n })\n root.append(baseLayer)\n root.insertBefore(baseLayer, postcss.comment({ text: '---break---' }))\n }\n\n if (baseLayer !== undefined) {\n // Add variables for each key in cssVars\n Object.entries(cssVars).forEach(([key, vars]) => {\n const selector = key === 'light' ? ':root' : `.${key}`\n // TODO: Fix typecheck.\n addOrUpdateVars(baseLayer as AtRule, selector, vars)\n })\n }\n },\n }\n}\n\nfunction removeConflictVars(root: Rule | Root) {\n const rootRule = root.nodes.find(\n (node): node is Rule => node.type === 'rule' && node.selector === ':root',\n )\n\n if (rootRule) {\n const propsToRemove = ['--background', '--foreground']\n\n rootRule.nodes\n .filter(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && propsToRemove.includes(node.prop),\n )\n .forEach(node => node.remove())\n\n if (rootRule.nodes.length === 0) {\n rootRule.remove()\n }\n }\n}\n\nfunction cleanupDefaultNextStylesPlugin() {\n return {\n postcssPlugin: 'cleanup-default-next-styles',\n Once(root: Root) {\n const bodyRule = root.nodes.find(\n (node): node is Rule => node.type === 'rule' && node.selector === 'body',\n )\n if (bodyRule) {\n // Remove color from the body node.\n bodyRule.nodes\n .find(\n (node): node is postcss.Declaration =>\n node.type === 'decl'\n && node.prop === 'color'\n && ['rgb(var(--foreground-rgb))', 'var(--foreground)'].includes(\n node.value,\n ),\n )\n ?.remove()\n\n // Remove background: linear-gradient.\n bodyRule.nodes\n .find((node): node is postcss.Declaration => {\n return (\n node.type === 'decl'\n && node.prop === 'background'\n // This is only going to run on create project, so all good.\n && (node.value.startsWith('linear-gradient')\n || node.value === 'var(--background)')\n )\n })\n ?.remove()\n\n // Remove font-family: Arial, Helvetica, sans-serif;\n bodyRule.nodes\n .find(\n (node): node is postcss.Declaration =>\n node.type === 'decl'\n && node.prop === 'font-family'\n && node.value === 'Arial, Helvetica, sans-serif',\n )\n ?.remove()\n\n // If the body rule is empty, remove it.\n if (bodyRule.nodes.length === 0) {\n bodyRule.remove()\n }\n }\n\n removeConflictVars(root)\n\n const darkRootRule = root.nodes.find(\n (node): node is Rule =>\n node.type === 'atrule'\n && node.params === '(prefers-color-scheme: dark)',\n )\n\n if (darkRootRule) {\n removeConflictVars(darkRootRule)\n if (darkRootRule.nodes.length === 0) {\n darkRootRule.remove()\n }\n }\n },\n }\n}\n\nfunction addOrUpdateVars(\n baseLayer: AtRule,\n selector: string,\n vars: Record<string, string>,\n) {\n let ruleNode = baseLayer.nodes?.find(\n (node): node is Rule => node.type === 'rule' && node.selector === selector,\n )\n\n if (!ruleNode) {\n if (Object.keys(vars).length > 0) {\n ruleNode = postcss.rule({\n selector,\n raws: { between: ' ', before: '\\n ' },\n })\n baseLayer.append(ruleNode)\n }\n }\n\n Object.entries(vars).forEach(([key, value]) => {\n const prop = `--${key.replace(/^--/, '')}`\n const newDecl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true },\n })\n\n const existingDecl = ruleNode?.nodes.find(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop === prop,\n )\n\n if (existingDecl) {\n existingDecl.replaceWith(newDecl)\n }\n else {\n ruleNode?.append(newDecl)\n }\n })\n}\n\nfunction updateCssVarsPluginV4(\n cssVars: z.infer<typeof registryItemCssVarsSchema>,\n options: {\n overwriteCssVars?: boolean\n },\n) {\n return {\n postcssPlugin: 'update-css-vars-v4',\n Once(root: Root) {\n Object.entries(cssVars).forEach(([key, vars]) => {\n let selector = key === 'light' ? ':root' : `.${key}`\n\n if (key === 'theme') {\n selector = '@theme'\n const themeNode = upsertThemeNode(root)\n Object.entries(vars).forEach(([key, value]) => {\n const prop = `--${key.replace(/^--/, '')}`\n const newDecl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true },\n })\n\n const existingDecl = themeNode?.nodes?.find(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop === prop,\n )\n\n // Only overwrite if overwriteCssVars is true\n // i.e for registry:theme and registry:style\n // We do not want new components to overwrite existing vars.\n // Keep user defined vars.\n if (options.overwriteCssVars) {\n if (existingDecl) {\n existingDecl.replaceWith(newDecl)\n }\n else {\n themeNode?.append(newDecl)\n }\n }\n else {\n if (!existingDecl) {\n themeNode?.append(newDecl)\n }\n }\n })\n return\n }\n\n let ruleNode = root.nodes?.find(\n (node): node is Rule =>\n node.type === 'rule' && node.selector === selector,\n )\n\n if (!ruleNode && Object.keys(vars).length > 0) {\n ruleNode = postcss.rule({\n selector,\n nodes: [],\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n root.append(ruleNode)\n root.insertBefore(ruleNode, postcss.comment({ text: '---break---' }))\n }\n\n Object.entries(vars).forEach(([key, value]) => {\n let prop = `--${key.replace(/^--/, '')}`\n\n // Special case for sidebar-background.\n if (prop === '--sidebar-background') {\n prop = '--sidebar'\n }\n\n if (isLocalHSLValue(value)) {\n value = `hsl(${value})`\n }\n\n const newDecl = postcss.decl({\n prop,\n value,\n raws: { semicolon: true },\n })\n const existingDecl = ruleNode?.nodes.find(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop === prop,\n )\n\n // Only overwrite if overwriteCssVars is true\n // i.e for registry:theme and registry:style\n // We do not want new components to overwrite existing vars.\n // Keep user defined vars.\n if (options.overwriteCssVars) {\n if (existingDecl) {\n existingDecl.replaceWith(newDecl)\n }\n else {\n ruleNode?.append(newDecl)\n }\n }\n else {\n if (!existingDecl) {\n ruleNode?.append(newDecl)\n }\n }\n })\n })\n },\n }\n}\n\nfunction updateThemePlugin(cssVars: z.infer<typeof registryItemCssVarsSchema>) {\n return {\n postcssPlugin: 'update-theme',\n Once(root: Root) {\n // Find unique color names from light and dark.\n const variables = Array.from(\n new Set(\n Object.keys(cssVars).flatMap(key =>\n Object.keys(cssVars[key as keyof typeof cssVars] || {}),\n ),\n ),\n )\n\n if (!variables.length) {\n return\n }\n\n const themeNode = upsertThemeNode(root)\n\n const themeVarNodes = themeNode.nodes?.filter(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop.startsWith('--'),\n )\n\n for (const variable of variables) {\n const value = Object.values(cssVars).find(vars => vars[variable])?.[\n variable\n ]\n\n if (!value) {\n continue\n }\n\n if (variable === 'radius') {\n const radiusVariables = {\n sm: 'calc(var(--radius) - 4px)',\n md: 'calc(var(--radius) - 2px)',\n lg: 'var(--radius)',\n xl: 'calc(var(--radius) + 4px)',\n }\n for (const [key, value] of Object.entries(radiusVariables)) {\n const cssVarNode = postcss.decl({\n prop: `--radius-${key}`,\n value,\n raws: { semicolon: true },\n })\n if (\n themeNode?.nodes?.find(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop === cssVarNode.prop,\n )\n ) {\n continue\n }\n themeNode?.append(cssVarNode)\n }\n continue\n }\n\n let prop\n = isLocalHSLValue(value) || isColorValue(value)\n ? `--color-${variable.replace(/^--/, '')}`\n : `--${variable.replace(/^--/, '')}`\n if (prop === '--color-sidebar-background') {\n prop = '--color-sidebar'\n }\n\n let propValue = `var(--${variable})`\n if (prop === '--color-sidebar') {\n propValue = 'var(--sidebar)'\n }\n\n const cssVarNode = postcss.decl({\n prop,\n value: propValue,\n raws: { semicolon: true },\n })\n const existingDecl = themeNode?.nodes?.find(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop === cssVarNode.prop,\n )\n if (!existingDecl) {\n if (themeVarNodes?.length) {\n themeNode?.insertAfter(\n themeVarNodes[themeVarNodes.length - 1],\n cssVarNode,\n )\n }\n else {\n themeNode?.append(cssVarNode)\n }\n }\n }\n },\n }\n}\n\nfunction upsertThemeNode(root: Root): AtRule {\n let themeNode = root.nodes.find(\n (node): node is AtRule =>\n node.type === 'atrule'\n && node.name === 'theme'\n && node.params === 'inline',\n )\n\n if (!themeNode) {\n themeNode = postcss.atRule({\n name: 'theme',\n params: 'inline',\n nodes: [],\n raws: { semicolon: true, between: ' ', before: '\\n' },\n })\n root.append(themeNode)\n root.insertBefore(themeNode, postcss.comment({ text: '---break---' }))\n }\n\n return themeNode\n}\n\nfunction addCustomVariant({ params }: { params: string }) {\n return {\n postcssPlugin: 'add-custom-variant',\n Once(root: Root) {\n const customVariant = root.nodes.find(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'custom-variant',\n )\n\n if (!customVariant) {\n // Find all import nodes\n const importNodes = root.nodes.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'import',\n )\n\n const variantNode = postcss.atRule({\n name: 'custom-variant',\n params,\n raws: { semicolon: true, before: '\\n' },\n })\n\n if (importNodes.length > 0) {\n // Insert after the last import\n const lastImport = importNodes[importNodes.length - 1]\n root.insertAfter(lastImport, variantNode)\n }\n else {\n // If no imports, insert after the first node\n root.insertAfter(root.nodes[0], variantNode)\n }\n\n root.insertBefore(variantNode, postcss.comment({ text: '---break---' }))\n }\n },\n }\n}\n\nfunction addCustomImport({ params }: { params: string }) {\n return {\n postcssPlugin: 'add-custom-import',\n Once(root: Root) {\n const importNodes = root.nodes.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'import',\n )\n\n // Find custom variant node (to ensure we insert before it)\n const customVariantNode = root.nodes.find(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'custom-variant',\n )\n\n // Check if our specific import already exists\n const hasImport = importNodes.some(\n node => node.params.replace(/[\"']/g, '') === params,\n )\n\n if (!hasImport) {\n const importNode = postcss.atRule({\n name: 'import',\n params: `\"${params}\"`,\n raws: { semicolon: true, before: '\\n' },\n })\n\n if (importNodes.length > 0) {\n // If there are existing imports, add after the last import\n const lastImport = importNodes[importNodes.length - 1]\n root.insertAfter(lastImport, importNode)\n }\n else if (customVariantNode) {\n // If no imports but has custom-variant, insert before it\n root.insertBefore(customVariantNode, importNode)\n root.insertBefore(\n customVariantNode,\n postcss.comment({ text: '---break---' }),\n )\n }\n else {\n // If no imports and no custom-variant, insert at the start\n root.prepend(importNode)\n root.insertAfter(importNode, postcss.comment({ text: '---break---' }))\n }\n }\n },\n }\n}\n\nfunction updateTailwindConfigPlugin(\n tailwindConfig: z.infer<typeof registryItemTailwindSchema>['config'],\n) {\n return {\n postcssPlugin: 'update-tailwind-config',\n Once(root: Root) {\n if (!tailwindConfig?.plugins) {\n return\n }\n\n const quoteType = getQuoteType(root)\n const quote = quoteType === 'single' ? '\\'' : '\"'\n\n const pluginNodes = root.nodes.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'plugin',\n )\n\n const lastPluginNode\n = pluginNodes[pluginNodes.length - 1] || root.nodes[0]\n\n for (const plugin of tailwindConfig.plugins) {\n const pluginName = plugin.replace(/^require\\([\"']|[\"']\\)$/g, '')\n\n // Check if the plugin is already present.\n if (\n pluginNodes.some((node) => {\n return node.params.replace(/[\"']/g, '') === pluginName\n })\n ) {\n continue\n }\n\n const pluginNode = postcss.atRule({\n name: 'plugin',\n params: `${quote}${pluginName}${quote}`,\n raws: { semicolon: true, before: '\\n' },\n })\n root.insertAfter(lastPluginNode, pluginNode)\n root.insertBefore(pluginNode, postcss.comment({ text: '---break---' }))\n }\n },\n }\n}\n\nfunction updateTailwindConfigKeyframesPlugin(\n tailwindConfig: z.infer<typeof registryItemTailwindSchema>['config'],\n) {\n return {\n postcssPlugin: 'update-tailwind-config-keyframes',\n Once(root: Root) {\n if (!tailwindConfig?.theme?.extend?.keyframes) {\n return\n }\n\n const themeNode = upsertThemeNode(root)\n const existingKeyFrameNodes = themeNode.nodes?.filter(\n (node): node is AtRule =>\n node.type === 'atrule' && node.name === 'keyframes',\n )\n\n const keyframeValueSchema = z.record(\n z.string(),\n z.record(z.string(), z.string()),\n )\n\n for (const [keyframeName, keyframeValue] of Object.entries(\n tailwindConfig.theme.extend.keyframes,\n )) {\n if (typeof keyframeName !== 'string') {\n continue\n }\n\n const parsedKeyframeValue = keyframeValueSchema.safeParse(keyframeValue)\n\n if (!parsedKeyframeValue.success) {\n continue\n }\n\n if (\n existingKeyFrameNodes?.find(\n (node): node is postcss.AtRule =>\n node.type === 'atrule'\n && node.name === 'keyframes'\n && node.params === keyframeName,\n )\n ) {\n continue\n }\n\n const keyframeNode = postcss.atRule({\n name: 'keyframes',\n params: keyframeName,\n nodes: [],\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n\n for (const [key, values] of Object.entries(parsedKeyframeValue.data)) {\n const rule = postcss.rule({\n selector: key,\n nodes: Object.entries(values).map(([key, value]) =>\n postcss.decl({\n prop: key,\n value,\n raws: { semicolon: true, before: '\\n ', between: ': ' },\n }),\n ),\n raws: { semicolon: true, between: ' ', before: '\\n ' },\n })\n keyframeNode.append(rule)\n }\n\n themeNode.append(keyframeNode)\n themeNode.insertBefore(\n keyframeNode,\n postcss.comment({ text: '---break---' }),\n )\n }\n },\n }\n}\n\nfunction updateTailwindConfigAnimationPlugin(\n tailwindConfig: z.infer<typeof registryItemTailwindSchema>['config'],\n) {\n return {\n postcssPlugin: 'update-tailwind-config-animation',\n Once(root: Root) {\n if (!tailwindConfig?.theme?.extend?.animation) {\n return\n }\n\n const themeNode = upsertThemeNode(root)\n const existingAnimationNodes = themeNode.nodes?.filter(\n (node): node is postcss.Declaration =>\n node.type === 'decl' && node.prop.startsWith('--animate-'),\n )\n\n const parsedAnimationValue = z\n .record(z.string(), z.string())\n .safeParse(tailwindConfig.theme.extend.animation)\n if (!parsedAnimationValue.success) {\n return\n }\n\n for (const [key, value] of Object.entries(parsedAnimationValue.data)) {\n const prop = `--animate-${key}`\n if (\n existingAnimationNodes?.find(\n (node): node is postcss.Declaration => node.prop === prop,\n )\n ) {\n continue\n }\n\n const animationNode = postcss.decl({\n prop,\n value,\n raws: { semicolon: true, between: ': ', before: '\\n ' },\n })\n themeNode.append(animationNode)\n }\n },\n }\n}\n\nfunction getQuoteType(root: Root): 'single' | 'double' {\n const firstNode = root.nodes[0]\n const raw = firstNode.toString()\n\n if (raw.includes('\\'')) {\n return 'single'\n }\n return 'double'\n}\n\nexport function isLocalHSLValue(value: string) {\n if (\n value.startsWith('hsl')\n || value.startsWith('rgb')\n || value.startsWith('#')\n || value.startsWith('oklch')\n ) {\n return false\n }\n\n const chunks = value.split(' ')\n\n return (\n chunks.length === 3\n && chunks.slice(1, 3).every(chunk => chunk.includes('%'))\n )\n}\n\nexport function isColorValue(value: string) {\n return (\n value.startsWith('hsl')\n || value.startsWith('rgb')\n || value.startsWith('#')\n || value.startsWith('oklch')\n || value.includes('var(--color-')\n )\n}\n","import type { RegistryItem } from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport { addDependency } from 'nypm'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function updateDependencies(\n dependencies: RegistryItem['dependencies'],\n devDependencies: RegistryItem['devDependencies'],\n config: Config,\n options: {\n silent?: boolean\n },\n) {\n dependencies = Array.from(new Set(dependencies))\n devDependencies = Array.from(new Set(devDependencies))\n\n if (!dependencies?.length && !devDependencies?.length) {\n return\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const dependenciesSpinner = spinner(`Installing dependencies.`, { silent: options.silent })?.start()\n dependenciesSpinner?.start()\n\n if (dependencies?.length) {\n await addDependency(dependencies, {\n cwd: config.resolvedPaths.cwd,\n silent: true,\n dev: false,\n })\n }\n\n // Install dev dependencies\n if (devDependencies?.length) {\n await addDependency(devDependencies, {\n cwd: config.resolvedPaths.cwd,\n silent: true,\n dev: true,\n })\n }\n\n dependenciesSpinner?.succeed()\n}\n","import type { z } from 'zod'\nimport type { registryItemEnvVarsSchema } from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport { existsSync, promises as fs } from 'node:fs'\nimport path from 'pathe'\nimport {\n findExistingEnvFile,\n getNewEnvKeys,\n mergeEnvContent,\n} from '@/src/utils/env-helpers'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function updateEnvVars(\n envVars: z.infer<typeof registryItemEnvVarsSchema> | undefined,\n config: Config,\n options: {\n silent?: boolean\n },\n) {\n if (!envVars || Object.keys(envVars).length === 0) {\n return {\n envVarsAdded: [],\n envFileUpdated: null,\n envFileCreated: null,\n }\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const envSpinner = spinner(`Adding environment variables.`, {\n silent: options.silent,\n })?.start()\n\n const projectRoot = config.resolvedPaths.cwd\n\n // Find existing env file or use .env.local as default.\n let envFilePath = path.join(projectRoot, '.env.local')\n const existingEnvFile = findExistingEnvFile(projectRoot)\n\n if (existingEnvFile) {\n envFilePath = existingEnvFile\n }\n\n const envFileExists = existsSync(envFilePath)\n const envFileName = path.basename(envFilePath)\n\n // Convert envVars object to env file format\n const newEnvContent = Object.entries(envVars)\n .map(([key, value]) => `${key}=${value}`)\n .join('\\n')\n\n let envVarsAdded: string[] = []\n let envFileUpdated: string | null = null\n let envFileCreated: string | null = null\n\n if (envFileExists) {\n const existingContent = await fs.readFile(envFilePath, 'utf-8')\n const mergedContent = mergeEnvContent(existingContent, newEnvContent)\n envVarsAdded = getNewEnvKeys(existingContent, newEnvContent)\n\n if (envVarsAdded.length > 0) {\n await fs.writeFile(envFilePath, mergedContent, 'utf-8')\n envFileUpdated = path.relative(projectRoot, envFilePath)\n\n envSpinner?.succeed(\n `Added the following variables to ${highlighter.info(envFileName)}:`,\n )\n\n if (!options.silent) {\n for (const key of envVarsAdded) {\n logger.log(` ${highlighter.success('+')} ${key}`)\n }\n }\n }\n else {\n envSpinner?.stop()\n }\n }\n else {\n // Create new env file\n await fs.writeFile(envFilePath, `${newEnvContent}\\n`, 'utf-8')\n envFileCreated = path.relative(projectRoot, envFilePath)\n envVarsAdded = Object.keys(envVars)\n\n envSpinner?.succeed(\n `Added the following variables to ${highlighter.info(envFileName)}:`,\n )\n\n if (!options.silent) {\n for (const key of envVarsAdded) {\n logger.log(` ${highlighter.success('+')} ${key}`)\n }\n }\n }\n\n if (!options.silent && envVarsAdded.length > 0) {\n logger.break()\n }\n\n return {\n envVarsAdded,\n envFileUpdated,\n envFileCreated,\n }\n}\n","import type {\n configSchema,\n registryItemFileSchema,\n workspaceConfigSchema,\n} from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport path from 'pathe'\nimport { z } from 'zod'\nimport { getRegistryItems } from '@/src/registry/api'\nimport { configWithDefaults } from '@/src/registry/config'\nimport { resolveRegistryTree } from '@/src/registry/resolver'\nimport {\n registryItemSchema,\n} from '@/src/schema'\nimport {\n findCommonRoot,\n findPackageRoot,\n getWorkspaceConfig,\n} from '@/src/utils/get-config'\nimport { getProjectTailwindVersionFromConfig } from '@/src/utils/get-project-info'\nimport { handleError } from '@/src/utils/handle-error'\nimport { isSafeTarget } from '@/src/utils/is-safe-target'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\nimport { updateCss } from '@/src/utils/updaters/update-css'\nimport { updateCssVars } from '@/src/utils/updaters/update-css-vars'\nimport { updateDependencies } from '@/src/utils/updaters/update-dependencies'\nimport { updateEnvVars } from '@/src/utils/updaters/update-env-vars'\nimport { updateFiles } from '@/src/utils/updaters/update-files'\nimport { updateTailwindConfig } from '@/src/utils/updaters/update-tailwind-config'\n\nexport async function addComponents(\n components: string[],\n config: Config,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n baseStyle?: boolean\n registryHeaders?: Record<string, Record<string, string>>\n path?: string\n },\n) {\n options = {\n overwrite: false,\n silent: false,\n isNewProject: false,\n baseStyle: true,\n ...options,\n }\n\n const workspaceConfig = await getWorkspaceConfig(config)\n if (\n workspaceConfig\n && workspaceConfig.ui\n && workspaceConfig.ui.resolvedPaths.cwd !== config.resolvedPaths.cwd\n ) {\n return await addWorkspaceComponents(components, config, workspaceConfig, {\n ...options,\n isRemote:\n components?.length === 1 && !!components[0].match(/\\/chat\\/b\\//),\n })\n }\n\n return await addProjectComponents(components, config, options)\n}\n\nasync function addProjectComponents(\n components: string[],\n config: z.infer<typeof configSchema>,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n baseStyle?: boolean\n path?: string\n },\n) {\n if (!options.baseStyle && !components.length) {\n return\n }\n\n const registrySpinner = spinner(`Checking registry.`, {\n silent: options.silent,\n })?.start()\n const tree = await resolveRegistryTree(components, configWithDefaults(config))\n\n if (!tree) {\n registrySpinner?.fail()\n return handleError(new Error('Failed to fetch components from registry.'))\n }\n\n try {\n validateFilesTarget(tree.files ?? [], config.resolvedPaths.cwd)\n }\n catch (error) {\n registrySpinner?.fail()\n return handleError(error)\n }\n\n registrySpinner?.succeed()\n\n const tailwindVersion = await getProjectTailwindVersionFromConfig(config)\n\n await updateTailwindConfig(tree.tailwind?.config, config, {\n silent: options.silent,\n tailwindVersion,\n })\n\n const overwriteCssVars = await shouldOverwriteCssVars(components, config)\n await updateCssVars(tree.cssVars, config, {\n cleanupDefaultNextStyles: options.isNewProject,\n silent: options.silent,\n tailwindVersion,\n tailwindConfig: tree.tailwind?.config,\n overwriteCssVars,\n initIndex: options.baseStyle,\n })\n\n // Add CSS updater\n await updateCss(tree.css, config, {\n silent: options.silent,\n })\n\n await updateEnvVars(tree.envVars, config, {\n silent: options.silent,\n })\n\n await updateDependencies(tree.dependencies, tree.devDependencies, config, {\n silent: options.silent,\n })\n await updateFiles(tree.files, config, {\n overwrite: options.overwrite,\n silent: options.silent,\n path: options.path,\n })\n\n if (tree.docs) {\n logger.info(tree.docs)\n }\n}\n\nasync function addWorkspaceComponents(\n components: string[],\n config: z.infer<typeof configSchema>,\n workspaceConfig: z.infer<typeof workspaceConfigSchema>,\n options: {\n overwrite?: boolean\n silent?: boolean\n isNewProject?: boolean\n isRemote?: boolean\n baseStyle?: boolean\n path?: string\n },\n) {\n if (!options.baseStyle && !components.length) {\n return\n }\n\n const registrySpinner = spinner(`Checking registry.`, {\n silent: options.silent,\n })?.start()\n const tree = await resolveRegistryTree(components, configWithDefaults(config))\n\n if (!tree) {\n registrySpinner?.fail()\n return handleError(new Error('Failed to fetch components from registry.'))\n }\n\n try {\n validateFilesTarget(tree.files ?? [], config.resolvedPaths.cwd)\n }\n catch (error) {\n registrySpinner?.fail()\n return handleError(error)\n }\n\n registrySpinner?.succeed()\n\n const filesCreated: string[] = []\n const filesUpdated: string[] = []\n const filesSkipped: string[] = []\n\n const rootSpinner = spinner(`Installing components.`)?.start()\n\n // Process global updates (tailwind, css vars, dependencies) first for the main target.\n // These should typically go to the UI package in a workspace.\n const mainTargetConfig = workspaceConfig.ui\n const tailwindVersion = await getProjectTailwindVersionFromConfig(\n mainTargetConfig,\n )\n const workspaceRoot = findCommonRoot(\n config.resolvedPaths.cwd,\n mainTargetConfig.resolvedPaths.ui,\n )\n\n // 1. Update tailwind config.\n if (tree.tailwind?.config) {\n await updateTailwindConfig(tree.tailwind?.config, mainTargetConfig, {\n silent: true,\n tailwindVersion,\n })\n filesUpdated.push(\n path.relative(\n workspaceRoot,\n mainTargetConfig.resolvedPaths.tailwindConfig,\n ),\n )\n }\n\n // 2. Update css vars.\n if (tree.cssVars) {\n const overwriteCssVars = await shouldOverwriteCssVars(components, config)\n await updateCssVars(tree.cssVars, mainTargetConfig, {\n silent: true,\n tailwindVersion,\n tailwindConfig: tree.tailwind?.config,\n overwriteCssVars,\n })\n filesUpdated.push(\n path.relative(workspaceRoot, mainTargetConfig.resolvedPaths.tailwindCss),\n )\n }\n\n // 3. Update CSS\n if (tree.css) {\n await updateCss(tree.css, mainTargetConfig, {\n silent: true,\n })\n filesUpdated.push(\n path.relative(workspaceRoot, mainTargetConfig.resolvedPaths.tailwindCss),\n )\n }\n\n // 4. Update environment variables\n if (tree.envVars) {\n await updateEnvVars(tree.envVars, mainTargetConfig, {\n silent: true,\n })\n }\n\n // 5. Update dependencies.\n await updateDependencies(\n tree.dependencies,\n tree.devDependencies,\n mainTargetConfig,\n {\n silent: true,\n\n },\n )\n\n // 6. Group files by their type to determine target config and update files.\n const filesByType = new Map<string, typeof tree.files>()\n\n for (const file of tree.files ?? []) {\n const type = file.type || 'registry:ui'\n if (!filesByType.has(type)) {\n filesByType.set(type, [])\n }\n filesByType.get(type)!.push(file)\n }\n\n // Process each type of component with its appropriate target config.\n for (const type of Array.from(filesByType.keys())) {\n const typeFiles = filesByType.get(type)!\n\n // eslint-disable-next-line prefer-const\n let targetConfig = type === 'registry:ui' ? workspaceConfig.ui : config\n\n const typeWorkspaceRoot = findCommonRoot(\n config.resolvedPaths.cwd,\n targetConfig.resolvedPaths.ui || targetConfig.resolvedPaths.cwd,\n )\n const packageRoot\n = (await findPackageRoot(\n typeWorkspaceRoot,\n targetConfig.resolvedPaths.cwd,\n )) ?? targetConfig.resolvedPaths.cwd\n\n // Update files for this type.\n const files = await updateFiles(typeFiles, targetConfig, {\n overwrite: options.overwrite,\n silent: true,\n rootSpinner,\n isRemote: options.isRemote,\n isWorkspace: true,\n path: options.path,\n })\n\n filesCreated.push(\n ...files.filesCreated.map(file =>\n path.relative(typeWorkspaceRoot, path.join(packageRoot, file)),\n ),\n )\n filesUpdated.push(\n ...files.filesUpdated.map(file =>\n path.relative(typeWorkspaceRoot, path.join(packageRoot, file)),\n ),\n )\n filesSkipped.push(\n ...files.filesSkipped.map(file =>\n path.relative(typeWorkspaceRoot, path.join(packageRoot, file)),\n ),\n )\n }\n\n rootSpinner?.succeed()\n\n // Sort files.\n filesCreated.sort()\n filesUpdated.sort()\n filesSkipped.sort()\n\n const hasUpdatedFiles = filesCreated.length || filesUpdated.length\n if (!hasUpdatedFiles && !filesSkipped.length) {\n spinner(`No files updated.`, {\n silent: options.silent,\n })?.info()\n }\n\n if (filesCreated.length) {\n spinner(\n `Created ${filesCreated.length} ${\n filesCreated.length === 1 ? 'file' : 'files'\n }:`,\n {\n silent: options.silent,\n },\n )?.succeed()\n for (const file of filesCreated) {\n logger.log(` - ${file}`)\n }\n }\n\n if (filesUpdated.length) {\n spinner(\n `Updated ${filesUpdated.length} ${\n filesUpdated.length === 1 ? 'file' : 'files'\n }:`,\n {\n silent: options.silent,\n },\n )?.info()\n for (const file of filesUpdated) {\n logger.log(` - ${file}`)\n }\n }\n\n if (filesSkipped.length) {\n spinner(\n `Skipped ${filesSkipped.length} ${\n filesUpdated.length === 1 ? 'file' : 'files'\n }: (use --overwrite to overwrite)`,\n {\n silent: options.silent,\n },\n )?.info()\n for (const file of filesSkipped) {\n logger.log(` - ${file}`)\n }\n }\n\n if (tree.docs) {\n logger.info(tree.docs)\n }\n}\n\nasync function shouldOverwriteCssVars(\n components: z.infer<typeof registryItemSchema>['name'][],\n config: z.infer<typeof configSchema>,\n) {\n const result = await getRegistryItems(components, { config })\n const payload = z.array(registryItemSchema).parse(result)\n\n return payload.some(\n component =>\n component.type === 'registry:theme' || component.type === 'registry:style',\n )\n}\n\nfunction validateFilesTarget(\n files: z.infer<typeof registryItemFileSchema>[],\n cwd: string,\n) {\n for (const file of files) {\n if (!file?.target) {\n continue\n }\n\n if (!isSafeTarget(file.target, cwd)) {\n throw new Error(\n `We found an unsafe file path \"${file.target} in the registry item. Installation aborted.`,\n )\n }\n }\n}\n","import { existsSync } from 'node:fs'\nimport { join } from 'pathe'\nimport { logger } from '@/src/utils/logger'\n\nexport async function loadEnvFiles(cwd: string = process.cwd()): Promise<void> {\n try {\n const { config } = await import('@dotenvx/dotenvx')\n const envFiles = [\n '.env.local',\n '.env.development.local',\n '.env.development',\n '.env',\n ]\n\n for (const envFile of envFiles) {\n const envPath = join(cwd, envFile)\n if (existsSync(envPath)) {\n config({\n path: envPath,\n overload: false,\n quiet: true,\n })\n }\n }\n }\n catch (error) {\n logger.warn('Failed to load env files:', error)\n }\n}\n","import fsExtra from 'fs-extra'\n\nexport const FILE_BACKUP_SUFFIX = '.bak'\n\nexport function createFileBackup(filePath: string): string | null {\n if (!fsExtra.existsSync(filePath)) {\n return null\n }\n\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n try {\n fsExtra.renameSync(filePath, backupPath)\n return backupPath\n }\n catch (error) {\n console.error(`Failed to create backup of ${filePath}: ${error}`)\n return null\n }\n}\n\nexport function restoreFileBackup(filePath: string): boolean {\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n\n if (!fsExtra.existsSync(backupPath)) {\n return false\n }\n\n try {\n fsExtra.renameSync(backupPath, filePath)\n return true\n }\n catch (error) {\n console.error(\n `Warning: Could not restore backup file ${backupPath}: ${error}`,\n )\n return false\n }\n}\n\nexport function deleteFileBackup(filePath: string): boolean {\n const backupPath = `${filePath}${FILE_BACKUP_SUFFIX}`\n\n if (!fsExtra.existsSync(backupPath)) {\n return false\n }\n\n try {\n fsExtra.unlinkSync(backupPath)\n return true\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n catch (_error) {\n // Best effort - don't log as this is just cleanup\n return false\n }\n}\n","import type { Config } from \"@/src/utils/get-config\"\nimport { BUILTIN_REGISTRIES } from \"@/src/registry/constants\"\nimport { RegistryNotConfiguredError } from \"@/src/registry/errors\"\nimport { parseRegistryAndItemFromString } from \"@/src/registry/parser\"\nimport { fetchRegistryItems } from \"@/src/registry/resolver\"\n\n// Recursively discovers all registry namespaces including nested ones.\nexport async function resolveRegistryNamespaces(\n components: string[],\n config: Config,\n) {\n const discoveredNamespaces = new Set<string>()\n const visitedItems = new Set<string>()\n const itemsToProcess = [...components]\n\n while (itemsToProcess.length > 0) {\n const currentItem = itemsToProcess.shift()!\n\n if (visitedItems.has(currentItem)) {\n continue\n }\n visitedItems.add(currentItem)\n\n const { registry } = parseRegistryAndItemFromString(currentItem)\n if (registry && !BUILTIN_REGISTRIES[registry]) {\n discoveredNamespaces.add(registry)\n }\n\n try {\n const [item] = await fetchRegistryItems([currentItem], config, {\n useCache: true,\n })\n\n if (item?.registryDependencies) {\n for (const dep of item.registryDependencies) {\n const { registry: depRegistry } = parseRegistryAndItemFromString(dep)\n if (depRegistry && !BUILTIN_REGISTRIES[depRegistry]) {\n discoveredNamespaces.add(depRegistry)\n }\n\n if (!visitedItems.has(dep)) {\n itemsToProcess.push(dep)\n }\n }\n }\n }\n catch (error) {\n // If a registry is not configured, we still track it.\n if (error instanceof RegistryNotConfiguredError) {\n const { registry } = parseRegistryAndItemFromString(currentItem)\n if (registry && !BUILTIN_REGISTRIES[registry]) {\n discoveredNamespaces.add(registry)\n }\n continue\n }\n\n // For other errors (network, parsing, etc.), we skip this item\n // but continue processing others to discover as many namespaces as possible.\n continue\n }\n }\n\n return Array.from(discoveredNamespaces)\n}\n","import type { Config } from '@/src/utils/get-config'\nimport fs from 'fs-extra'\nimport path from 'pathe'\nimport { getRegistriesIndex } from '@/src/registry/api'\nimport { BUILTIN_REGISTRIES } from '@/src/registry/constants'\nimport { resolveRegistryNamespaces } from '@/src/registry/namespaces'\nimport { rawConfigSchema } from '@/src/registry/schema'\nimport { spinner } from '@/src/utils/spinner'\n\nexport async function ensureRegistriesInConfig(\n components: string[],\n config: Config,\n options: {\n silent?: boolean\n writeFile?: boolean\n } = {},\n) {\n options = {\n silent: false,\n writeFile: true,\n ...options,\n }\n\n // Use resolveRegistryNamespaces to discover all namespaces including dependencies.\n const registryNames = await resolveRegistryNamespaces(components, config)\n\n const missingRegistries = registryNames.filter(\n registry =>\n !config.registries?.[registry]\n && !Object.keys(BUILTIN_REGISTRIES).includes(registry),\n )\n\n if (missingRegistries.length === 0) {\n return {\n config,\n newRegistries: [],\n }\n }\n\n // We'll fail silently if we can't fetch the registry index.\n // The error handling by caller will guide user to add the missing registries.\n const registryIndex = await getRegistriesIndex({\n useCache: process.env.NODE_ENV !== 'development',\n })\n if (!registryIndex) {\n return {\n config,\n newRegistries: [],\n }\n }\n\n const foundRegistries: Record<string, string> = {}\n for (const registry of missingRegistries) {\n if (registryIndex[registry]) {\n foundRegistries[registry] = registryIndex[registry]\n }\n }\n\n if (Object.keys(foundRegistries).length === 0) {\n return {\n config,\n newRegistries: [],\n }\n }\n\n // Filter out built-in registries from existing config before merging\n const existingRegistries = Object.fromEntries(\n Object.entries(config.registries || {}).filter(\n ([key]) => !Object.keys(BUILTIN_REGISTRIES).includes(key),\n ),\n )\n\n const newConfigWithRegistries = {\n ...config,\n registries: {\n ...existingRegistries,\n ...foundRegistries,\n },\n }\n\n if (options.writeFile) {\n const { resolvedPaths: _resolvedPaths, ...configWithoutResolvedPaths }\n = newConfigWithRegistries\n const configSpinner = spinner('Updating components.json.', {\n silent: options.silent,\n }).start()\n const updatedConfig = rawConfigSchema.parse(configWithoutResolvedPaths)\n await fs.writeFile(\n path.resolve(config.resolvedPaths.cwd, 'components.json'),\n `${JSON.stringify(updatedConfig, null, 2)}\\n`,\n 'utf-8',\n )\n configSpinner.succeed()\n }\n\n return {\n config: newConfigWithRegistries,\n newRegistries: Object.keys(foundRegistries),\n }\n}\n","import type { ObjectLiteralExpression } from 'ts-morph'\nimport type { Config } from '@/src/utils/get-config'\nimport { promises as fs } from 'node:fs'\nimport path from 'pathe'\nimport { SyntaxKind } from 'ts-morph'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { spinner } from '@/src/utils/spinner'\nimport {\n _createSourceFile,\n _getQuoteChar,\n} from '@/src/utils/updaters/update-tailwind-config'\n\nexport async function updateTailwindContent(\n content: string[],\n config: Config,\n options: {\n silent?: boolean\n },\n) {\n if (!content) {\n return\n }\n\n options = {\n silent: false,\n ...options,\n }\n\n const tailwindFileRelativePath = path.relative(\n config.resolvedPaths.cwd,\n config.resolvedPaths.tailwindConfig,\n )\n const tailwindSpinner = spinner(\n `Updating ${highlighter.info(tailwindFileRelativePath)}`,\n {\n silent: options.silent,\n },\n ).start()\n const raw = await fs.readFile(config.resolvedPaths.tailwindConfig, 'utf8')\n const output = await transformTailwindContent(raw, content, config)\n await fs.writeFile(config.resolvedPaths.tailwindConfig, output, 'utf8')\n tailwindSpinner?.succeed()\n}\n\nexport async function transformTailwindContent(\n input: string,\n content: string[],\n config: Config,\n) {\n const sourceFile = await _createSourceFile(input, config)\n // Find the object with content property.\n // This is faster than traversing the default export.\n // TODO: maybe we do need to traverse the default export?\n const configObject = sourceFile\n .getDescendantsOfKind(SyntaxKind.ObjectLiteralExpression)\n .find(node =>\n node\n .getProperties()\n .some(\n property =>\n property.isKind(SyntaxKind.PropertyAssignment)\n && property.getName() === 'content',\n ),\n )\n\n // We couldn't find the config object, so we return the input as is.\n if (!configObject) {\n return input\n }\n\n addTailwindConfigContent(configObject, content)\n\n return sourceFile.getFullText()\n}\n\nasync function addTailwindConfigContent(\n configObject: ObjectLiteralExpression,\n content: string[],\n) {\n const quoteChar = _getQuoteChar(configObject)\n\n const existingProperty = configObject.getProperty('content')\n\n if (!existingProperty) {\n const newProperty = {\n name: 'content',\n initializer: `[${quoteChar}${content.join(\n `${quoteChar}, ${quoteChar}`,\n )}${quoteChar}]`,\n }\n configObject.addPropertyAssignment(newProperty)\n\n return configObject\n }\n\n if (existingProperty.isKind(SyntaxKind.PropertyAssignment)) {\n const initializer = existingProperty.getInitializer()\n\n // If property is an array, append.\n if (initializer?.isKind(SyntaxKind.ArrayLiteralExpression)) {\n for (const contentItem of content) {\n const newValue = `${quoteChar}${contentItem}${quoteChar}`\n\n // Check if the array already contains the value.\n if (\n initializer\n .getElements()\n .map(element => element.getText())\n .includes(newValue)\n ) {\n continue\n }\n\n initializer.addElement(newValue)\n }\n }\n\n return configObject\n }\n\n return configObject\n}\n","import type { Config } from '@/src/utils/get-config'\nimport { promises as fs } from 'node:fs'\nimport { Command } from 'commander'\nimport deepmerge from 'deepmerge'\nimport fsExtra from 'fs-extra'\nimport path from 'pathe'\nimport prompts from 'prompts'\nimport { z } from 'zod'\nimport { preFlightInit } from '@/src/preflights/preflight-init'\nimport {\n getRegistryBaseColors,\n getRegistryItems,\n getRegistryStyles,\n} from '@/src/registry/api'\nimport { buildUrlAndHeadersForRegistryItem } from '@/src/registry/builder'\nimport { configWithDefaults } from '@/src/registry/config'\nimport {\n BASE_COLORS,\n BUILTIN_REGISTRIES,\n REGISTRY_URL,\n} from '@/src/registry/constants'\nimport { hexToOklch, isValidHex, getForegroundColor } from '@/src/utils/frontic-colors'\nimport { clearRegistryContext } from '@/src/registry/context'\nimport { rawConfigSchema } from '@/src/schema'\nimport { addComponents } from '@/src/utils/add-components'\n// import { createProject, TEMPLATES } from '@/src/utils/create-project'\nimport { loadEnvFiles } from '@/src/utils/env-loader'\nimport * as ERRORS from '@/src/utils/errors'\nimport {\n createFileBackup,\n deleteFileBackup,\n FILE_BACKUP_SUFFIX,\n restoreFileBackup,\n} from '@/src/utils/file-helper'\nimport {\n createConfig,\n DEFAULT_COMPONENTS,\n DEFAULT_TAILWIND_CONFIG,\n DEFAULT_TAILWIND_CSS,\n DEFAULT_UTILS,\n getConfig,\n resolveConfigPaths,\n} from '@/src/utils/get-config'\nimport {\n getProjectConfig,\n getProjectInfo,\n getProjectTailwindVersionFromConfig,\n} from '@/src/utils/get-project-info'\nimport { handleError } from '@/src/utils/handle-error'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { ensureRegistriesInConfig } from '@/src/utils/registries'\nimport { spinner } from '@/src/utils/spinner'\nimport { updateTailwindContent } from '@/src/utils/updaters/update-tailwind-content'\n\nprocess.on('exit', (code) => {\n const filePath = path.resolve(process.cwd(), 'components.json')\n\n // Delete backup if successful.\n if (code === 0) {\n return deleteFileBackup(filePath)\n }\n\n // Restore backup if error.\n return restoreFileBackup(filePath)\n})\n\nexport const initOptionsSchema = z.object({\n cwd: z.string(),\n components: z.array(z.string()).optional(),\n yes: z.boolean(),\n defaults: z.boolean(),\n force: z.boolean(),\n silent: z.boolean(),\n isNewProject: z.boolean(),\n srcDir: z.boolean().optional(),\n cssVariables: z.boolean(),\n // Frontic-specific options\n brand: z.string().optional(),\n baseColor: z\n .string()\n .optional()\n .refine(\n (val) => {\n if (val) {\n return BASE_COLORS.find(color => color.name === val)\n }\n\n return true\n },\n {\n message: `Invalid base color. Please use '${BASE_COLORS.map(\n color => color.name,\n ).join('\\', \\'')}'`,\n },\n ),\n baseStyle: z.boolean(),\n})\n\nexport const init = new Command()\n .name('init')\n .description('Initialize Frontic UI in your Vue/Nuxt project')\n .argument('[components...]', 'names, url or local path to component')\n .option(\n '-b, --base-color <base-color>',\n 'the base color to use. (neutral, gray, zinc, stone, slate)',\n undefined,\n )\n .option(\n '--brand <color>',\n 'brand color in hex format (e.g., #6366f1)',\n undefined,\n )\n .option('-y, --yes', 'skip confirmation prompt.', true)\n .option('-d, --defaults,', 'use default configuration.', false)\n .option('-f, --force', 'force overwrite of existing configuration.', false)\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-s, --silent', 'mute output.', false)\n .option('--css-variables', 'use css variables for theming.', true)\n .option('--no-css-variables', 'do not use css variables for theming.')\n .option('--no-base-style', 'do not install the base shadcn style.')\n .action(async (components, opts) => {\n try {\n // Apply defaults when --defaults flag is set.\n if (opts.defaults) {\n opts.template = opts.template || 'next'\n opts.baseColor = opts.baseColor || 'neutral'\n }\n\n const options = initOptionsSchema.parse({\n cwd: path.resolve(opts.cwd),\n isNewProject: false,\n components,\n ...opts,\n })\n\n await loadEnvFiles(options.cwd)\n\n // We need to check if we're initializing with a new style.\n // This will allow us to determine if we need to install the base style.\n // And if we should prompt the user for a base color.\n if (components.length > 0) {\n // We don't know the full config at this point.\n // So we'll use a shadow config to fetch the first item.\n let shadowConfig = configWithDefaults(\n createConfig({\n resolvedPaths: {\n cwd: options.cwd,\n },\n }),\n )\n\n // Check if there's a components.json file.\n // If so, we'll merge with our shadow config.\n const componentsJsonPath = path.resolve(options.cwd, 'components.json')\n if (fsExtra.existsSync(componentsJsonPath)) {\n const existingConfig = await fsExtra.readJson(componentsJsonPath)\n const config = rawConfigSchema.partial().parse(existingConfig)\n const baseConfig = createConfig({\n resolvedPaths: {\n cwd: options.cwd,\n },\n })\n shadowConfig = configWithDefaults({\n ...config,\n resolvedPaths: {\n ...baseConfig.resolvedPaths,\n cwd: options.cwd,\n },\n })\n\n // Since components.json might not be valid at this point.\n // Temporarily rename components.json to allow preflight to run.\n // We'll rename it back after preflight.\n createFileBackup(componentsJsonPath)\n }\n\n // Ensure all registries used in components are configured.\n const { config: updatedConfig } = await ensureRegistriesInConfig(\n components,\n shadowConfig,\n {\n silent: true,\n writeFile: false,\n },\n )\n shadowConfig = updatedConfig\n\n // This forces a shadowConfig validation early in the process.\n buildUrlAndHeadersForRegistryItem(components[0], shadowConfig)\n\n const [item] = await getRegistryItems([components[0]], {\n config: shadowConfig,\n })\n if (item?.type === 'registry:style') {\n // Set a default base color so we're not prompted.\n // The style will extend or override it.\n options.baseColor = 'neutral'\n\n // If the style extends none, we don't want to install the base style.\n options.baseStyle\n = item.extends === 'none' ? false : options.baseStyle\n }\n }\n\n // If --no-base-style, we don't want to prompt for a base color either.\n // The style will extend or override it.\n if (!options.baseStyle) {\n options.baseColor = 'neutral'\n }\n\n await runInit(options)\n\n logger.log(\n `${highlighter.success(\n 'Success!',\n )} Frontic UI initialized.\\nYou may now add components with: ${highlighter.info('npx @frontic/ui add button')}`,\n )\n\n // We need when running with custom cwd.\n deleteFileBackup(path.resolve(options.cwd, 'components.json'))\n logger.break()\n }\n catch (error) {\n logger.break()\n handleError(error)\n }\n finally {\n clearRegistryContext()\n }\n })\n\nexport async function runInit(\n options: z.infer<typeof initOptionsSchema> & {\n skipPreflight?: boolean\n },\n) {\n let projectInfo\n let _newProjectTemplate\n if (!options.skipPreflight) {\n const preflight = await preFlightInit(options)\n if (preflight.errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]) {\n // const { projectPath, template } = await createProject(options)\n // if (!projectPath) {\n process.exit(1)\n // }\n // options.cwd = projectPath\n // options.isNewProject = true\n // newProjectTemplate = template\n }\n projectInfo = preflight.projectInfo\n }\n else {\n projectInfo = await getProjectInfo(options.cwd)\n }\n\n // if (newProjectTemplate === 'next-monorepo') {\n // options.cwd = path.resolve(options.cwd, 'apps/web')\n // return await getConfig(options.cwd)\n // }\n\n const projectConfig = await getProjectConfig(options.cwd, projectInfo)\n\n let config = projectConfig\n ? await promptForMinimalConfig(projectConfig, options)\n : await promptForConfig(await getConfig(options.cwd))\n\n if (!options.yes) {\n const { proceed } = await prompts({\n type: 'confirm',\n name: 'proceed',\n message: `Write configuration to ${highlighter.info(\n 'components.json',\n )}. Proceed?`,\n initial: true,\n })\n\n if (!proceed) {\n process.exit(0)\n }\n }\n\n // Prepare the list of components to be added.\n const components = [\n // \"index\" is the default shadcn style.\n // Why index? Because when style is true, we read style from components.json and fetch that.\n // i.e new-york from components.json then fetch /styles/new-york/index.\n // TODO: Fix this so that we can extend any style i.e --style=new-york.\n ...(options.baseStyle ? ['index'] : []),\n ...(options.components ?? []),\n ]\n\n // Ensure registries are configured for the components we're about to add.\n const fullConfigForRegistry = await resolveConfigPaths(options.cwd, config)\n const { config: configWithRegistries } = await ensureRegistriesInConfig(\n components,\n fullConfigForRegistry,\n {\n silent: true,\n },\n )\n\n // Update config with any new registries found.\n if (configWithRegistries.registries) {\n config.registries = configWithRegistries.registries\n }\n\n const componentSpinner = spinner(`Writing components.json.`).start()\n const targetPath = path.resolve(options.cwd, 'components.json')\n const backupPath = `${targetPath}${FILE_BACKUP_SUFFIX}`\n\n // Merge with backup config if it exists and not using --force\n if (!options.force && fsExtra.existsSync(backupPath)) {\n const existingConfig = await fsExtra.readJson(backupPath)\n\n // Move registries at the end of the config.\n const { registries, ...merged } = deepmerge(existingConfig, config)\n config = { ...merged, registries }\n }\n\n // Make sure to filter out built-in registries.\n // TODO: fix this in ensureRegistriesInConfig.\n config.registries = Object.fromEntries(\n Object.entries(config.registries || {}).filter(\n ([key]) => !Object.keys(BUILTIN_REGISTRIES).includes(key),\n ),\n )\n\n // Write components.json.\n await fs.writeFile(targetPath, `${JSON.stringify(config, null, 2)}\\n`, 'utf8')\n componentSpinner.succeed()\n\n // Add components.\n const fullConfig = await resolveConfigPaths(options.cwd, config)\n\n await addComponents(components, fullConfig, {\n // Init will always overwrite files.\n overwrite: true,\n silent: options.silent,\n baseStyle: options.baseStyle,\n isNewProject:\n options.isNewProject || projectInfo?.framework.name === 'nuxt4',\n })\n\n // If a new project is using src dir, let's update the tailwind content config.\n // TODO: Handle this per framework.\n if (options.isNewProject && options.srcDir) {\n await updateTailwindContent(\n ['./src/**/*.{js,ts,jsx,tsx,mdx}'],\n fullConfig,\n {\n silent: options.silent,\n },\n )\n }\n\n // === Frontic customizations ===\n // Brand/radius are now collected in the unified prompt flow and stored in config.frontic\n // The theme CSS variables are injected via registryGetTheme() in the resolver\n\n // Add Frontic registry to components.json\n const configPath = path.resolve(options.cwd, 'components.json')\n try {\n const existingConfig = await fsExtra.readJson(configPath)\n existingConfig.registries = existingConfig.registries || {}\n existingConfig.registries['@frontic'] = {\n url: `${REGISTRY_URL}/styles/{style}/{name}.json`,\n }\n await fs.writeFile(configPath, `${JSON.stringify(existingConfig, null, 2)}\\n`, 'utf8')\n if (!options.silent) {\n logger.success('Frontic registry configured')\n }\n } catch {\n logger.warn('Could not add Frontic registry to components.json')\n }\n\n // Show summary if brand color is configured\n const { brand, brandForeground } = fullConfig.tailwind\n if (!options.silent && brand) {\n logger.break()\n logger.info('Your Frontic theme settings:')\n logger.info(` --brand: ${highlighter.info(brand)}`)\n if (brandForeground) {\n logger.info(` --brand-foreground: ${highlighter.info(brandForeground)}`)\n }\n }\n\n return fullConfig\n}\n\nasync function promptForConfig(defaultConfig: Config | null = null) {\n const [styles, baseColors] = await Promise.all([\n getRegistryStyles(),\n getRegistryBaseColors(),\n ])\n\n logger.info('')\n const options = await prompts([\n {\n type: 'toggle',\n name: 'typescript',\n message: `Would you like to use ${highlighter.info(\n 'TypeScript',\n )} (recommended)?`,\n initial: defaultConfig?.typescript ?? true,\n active: 'yes',\n inactive: 'no',\n },\n {\n type: 'select',\n name: 'style',\n message: `Which ${highlighter.info('style')} would you like to use?`,\n choices: styles.map(style => ({\n title: style.label,\n value: style.name,\n })),\n },\n {\n type: 'select',\n name: 'tailwindBaseColor',\n message: `Which color would you like to use as the ${highlighter.info(\n 'base color',\n )}?`,\n choices: baseColors.map(color => ({\n title: color.label,\n value: color.name,\n })),\n },\n {\n type: 'text',\n name: 'brandColor',\n message: `What ${highlighter.info('brand color')} would you like to use? (hex)`,\n initial: '#6366f1',\n validate: (value: string) => {\n if (!value) return true\n return isValidHex(value) || 'Please enter a valid hex color (e.g., #6366f1)'\n },\n },\n {\n type: 'text',\n name: 'tailwindCss',\n message: `Where is your ${highlighter.info('global CSS')} file?`,\n initial: defaultConfig?.tailwind.css ?? DEFAULT_TAILWIND_CSS,\n },\n {\n type: 'toggle',\n name: 'tailwindCssVariables',\n message: `Would you like to use ${highlighter.info(\n 'CSS variables',\n )} for theming?`,\n initial: defaultConfig?.tailwind.cssVariables ?? true,\n active: 'yes',\n inactive: 'no',\n },\n {\n type: 'text',\n name: 'tailwindPrefix',\n message: `Are you using a custom ${highlighter.info(\n 'tailwind prefix eg. tw-',\n )}? (Leave blank if not)`,\n initial: '',\n },\n {\n type: 'text',\n name: 'tailwindConfig',\n message: `Where is your ${highlighter.info(\n 'tailwind.config.js',\n )} located?`,\n initial: defaultConfig?.tailwind.config ?? DEFAULT_TAILWIND_CONFIG,\n },\n {\n type: 'text',\n name: 'components',\n message: `Configure the import alias for ${highlighter.info(\n 'components',\n )}:`,\n initial: defaultConfig?.aliases.components ?? DEFAULT_COMPONENTS,\n },\n {\n type: 'text',\n name: 'utils',\n message: `Configure the import alias for ${highlighter.info('utils')}:`,\n initial: defaultConfig?.aliases.utils ?? DEFAULT_UTILS,\n },\n ])\n\n // Convert brand color to OKLCH and calculate foreground (only if provided)\n const brandOklch = options.brandColor && isValidHex(options.brandColor)\n ? hexToOklch(options.brandColor)\n : undefined\n const brandForeground = brandOklch ? getForegroundColor(brandOklch) : undefined\n\n return rawConfigSchema.parse({\n $schema: 'https://shadcn-vue.com/schema.json',\n style: options.style,\n tailwind: {\n config: options.tailwindConfig,\n css: options.tailwindCss,\n baseColor: options.tailwindBaseColor,\n cssVariables: options.tailwindCssVariables,\n prefix: options.tailwindPrefix,\n // Frontic additions (only if user provided a brand color)\n ...(brandOklch && { brand: brandOklch }),\n ...(brandForeground && { brandForeground }),\n },\n typescript: options.typescript,\n aliases: {\n utils: options.utils,\n components: options.components,\n // TODO: fix this.\n lib: options.components.replace(/\\/components$/, '/lib'),\n composables: options.components.replace(/\\/components$/, '/composables'),\n },\n })\n}\n\nasync function promptForMinimalConfig(\n defaultConfig: Config,\n opts: z.infer<typeof initOptionsSchema>,\n) {\n let style = defaultConfig.style\n let baseColor = opts.baseColor\n let cssVariables = defaultConfig.tailwind.cssVariables\n let brandOklch: string | undefined\n let brandForeground: string | undefined\n\n // Handle CLI flag for brand\n if (opts.brand && isValidHex(opts.brand)) {\n brandOklch = hexToOklch(opts.brand)\n brandForeground = getForegroundColor(brandOklch)\n }\n\n if (!opts.defaults) {\n const [styles, baseColors, tailwindVersion] = await Promise.all([\n getRegistryStyles(),\n getRegistryBaseColors(),\n getProjectTailwindVersionFromConfig(defaultConfig),\n ])\n\n const options = await prompts([\n {\n type: tailwindVersion === 'v4' ? null : 'select',\n name: 'style',\n message: `Which ${highlighter.info('style')} would you like to use?`,\n choices: styles.map(style => ({\n title:\n style.name === 'new-york' ? 'New York (Recommended)' : style.label,\n value: style.name,\n })),\n initial: 0,\n },\n {\n type: opts.baseColor ? null : 'select',\n name: 'tailwindBaseColor',\n message: `Which color would you like to use as the ${highlighter.info(\n 'base color',\n )}?`,\n choices: baseColors.map(color => ({\n title: color.label,\n value: color.name,\n })),\n },\n {\n // Skip if already provided via CLI flag\n type: opts.brand ? null : 'text',\n name: 'brandColor',\n message: `What ${highlighter.info('brand color')} would you like to use? (hex)`,\n initial: '#6366f1',\n validate: (value: string) => {\n if (!value) return true\n return isValidHex(value) || 'Please enter a valid hex color (e.g., #6366f1)'\n },\n },\n ])\n\n style = options.style ?? 'new-york'\n baseColor = options.tailwindBaseColor ?? baseColor\n cssVariables = opts.cssVariables\n\n // Process brand color from prompt (if not from CLI)\n if (!opts.brand && options.brandColor && isValidHex(options.brandColor)) {\n brandOklch = hexToOklch(options.brandColor)\n brandForeground = getForegroundColor(brandOklch)\n }\n }\n\n return rawConfigSchema.parse({\n $schema: defaultConfig?.$schema,\n style,\n tailwind: {\n ...defaultConfig?.tailwind,\n baseColor,\n cssVariables,\n // Frontic additions (only if user provided a brand color)\n ...(brandOklch && { brand: brandOklch }),\n ...(brandForeground && { brandForeground }),\n },\n typescript: defaultConfig.typescript,\n aliases: defaultConfig?.aliases,\n iconLibrary: defaultConfig?.iconLibrary,\n })\n}\n","import type { z } from 'zod'\nimport type { addOptionsSchema } from '@/src/commands/add'\nimport fs from 'fs-extra'\nimport path from 'pathe'\nimport * as ERRORS from '@/src/utils/errors'\nimport { getConfig } from '@/src/utils/get-config'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\n\nexport async function preFlightAdd(options: z.infer<typeof addOptionsSchema>) {\n const errors: Record<string, boolean> = {}\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd)\n || !fs.existsSync(path.resolve(options.cwd, 'package.json'))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true\n return {\n errors,\n config: null,\n }\n }\n\n // Check for existing components.json file.\n if (!fs.existsSync(path.resolve(options.cwd, 'components.json'))) {\n errors[ERRORS.MISSING_CONFIG] = true\n return {\n errors,\n config: null,\n }\n }\n\n try {\n const config = await getConfig(options.cwd)\n\n return {\n errors,\n config: config!,\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n catch (_error) {\n logger.break()\n logger.error(\n `An invalid ${highlighter.info(\n 'components.json',\n )} file was found at ${highlighter.info(\n options.cwd,\n )}.\\nBefore you can add components, you must create a valid ${highlighter.info(\n 'components.json',\n )} file by running the ${highlighter.info('init')} command.`,\n )\n logger.error(\n `Learn more at ${highlighter.info(\n 'https://frontic.io/docs/components-json',\n )}.`,\n )\n logger.break()\n process.exit(1)\n }\n}\n","/* eslint-disable prefer-const */\nimport type { registryItemTypeSchema } from '@/src/registry/schema'\nimport { Command } from 'commander'\nimport path from 'pathe'\nimport prompts from 'prompts'\nimport { z } from 'zod'\nimport { runInit } from '@/src/commands/init'\nimport { preFlightAdd } from '@/src/preflights/preflight-add'\nimport { getRegistryItems, getShadcnRegistryIndex } from '@/src/registry/api'\nimport { DEPRECATED_COMPONENTS } from '@/src/registry/constants'\nimport { clearRegistryContext } from '@/src/registry/context'\nimport { isUniversalRegistryItem } from '@/src/registry/utils'\nimport { addComponents } from '@/src/utils/add-components'\n// import { createProject } from '@/src/utils/create-project'\nimport { loadEnvFiles } from '@/src/utils/env-loader'\nimport * as ERRORS from '@/src/utils/errors'\nimport { createConfig, getConfig } from '@/src/utils/get-config'\nimport { getProjectInfo } from '@/src/utils/get-project-info'\nimport { handleError } from '@/src/utils/handle-error'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { ensureRegistriesInConfig } from '@/src/utils/registries'\n// import { updateAppIndex } from '@/src/utils/update-app-index'\n\nexport const addOptionsSchema = z.object({\n components: z.array(z.string()).optional(),\n yes: z.boolean(),\n overwrite: z.boolean(),\n cwd: z.string(),\n all: z.boolean(),\n path: z.string().optional(),\n silent: z.boolean(),\n srcDir: z.boolean().optional(),\n cssVariables: z.boolean(),\n})\n\nexport const add = new Command()\n .name('add')\n .description('add a component to your project')\n .argument('[components...]', 'names, url or local path to component')\n .option('-y, --yes', 'skip confirmation prompt.', false)\n .option('-o, --overwrite', 'overwrite existing files.', false)\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-a, --all', 'add all available components', false)\n .option('-p, --path <path>', 'the path to add the component to.')\n .option('-s, --silent', 'mute output.', false)\n // .option(\n // '--src-dir',\n // 'use the src directory when creating a new project.',\n // false,\n // )\n // .option(\n // '--no-src-dir',\n // 'do not use the src directory when creating a new project.',\n // )\n .option('--css-variables', 'use css variables for theming.', true)\n .option('--no-css-variables', 'do not use css variables for theming.')\n .action(async (components, opts) => {\n try {\n const options = addOptionsSchema.parse({\n components,\n cwd: path.resolve(opts.cwd),\n ...opts,\n })\n\n await loadEnvFiles(options.cwd)\n\n let initialConfig = await getConfig(options.cwd)\n if (!initialConfig) {\n initialConfig = createConfig({\n style: 'new-york',\n resolvedPaths: {\n cwd: options.cwd,\n },\n })\n }\n\n let hasNewRegistries = false\n if (components.length > 0) {\n const { config: updatedConfig, newRegistries }\n = await ensureRegistriesInConfig(components, initialConfig, {\n silent: options.silent,\n writeFile: false,\n })\n initialConfig = updatedConfig\n hasNewRegistries = newRegistries.length > 0\n }\n\n let itemType: z.infer<typeof registryItemTypeSchema> | undefined\n let shouldInstallBaseStyle = true\n if (components.length > 0) {\n const [registryItem] = await getRegistryItems([components[0]], {\n config: initialConfig,\n })\n itemType = registryItem?.type\n shouldInstallBaseStyle\n = itemType !== 'registry:theme' && itemType !== 'registry:style'\n\n if (isUniversalRegistryItem(registryItem)) {\n await addComponents(components, initialConfig, {\n ...options,\n baseStyle: shouldInstallBaseStyle,\n })\n return\n }\n\n if (\n !options.yes\n && (itemType === 'registry:style' || itemType === 'registry:theme')\n ) {\n logger.break()\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n message: highlighter.warn(\n `You are about to install a new ${itemType.replace(\n 'registry:',\n '',\n )}. \\nExisting CSS variables and components will be overwritten. Continue?`,\n ),\n })\n if (!confirm) {\n logger.break()\n logger.log(`Installation cancelled.`)\n logger.break()\n process.exit(1)\n }\n }\n }\n\n if (!options.components?.length) {\n options.components = await promptForRegistryComponents(options)\n }\n\n const projectInfo = await getProjectInfo(options.cwd)\n if (projectInfo?.tailwindVersion === 'v4') {\n const deprecatedComponents = DEPRECATED_COMPONENTS.filter(component =>\n options.components?.includes(component.name),\n )\n\n if (deprecatedComponents?.length) {\n logger.break()\n deprecatedComponents.forEach((component) => {\n logger.warn(highlighter.warn(component.message))\n })\n logger.break()\n process.exit(1)\n }\n }\n\n let { errors, config } = await preFlightAdd(options)\n\n // No components.json file. Prompt the user to run init.\n let initHasRun = false\n if (errors[ERRORS.MISSING_CONFIG]) {\n const { proceed } = await prompts({\n type: 'confirm',\n name: 'proceed',\n message: `You need to create a ${highlighter.info(\n 'components.json',\n )} file to add components. Proceed?`,\n initial: true,\n })\n\n if (!proceed) {\n logger.break()\n process.exit(1)\n }\n\n config = await runInit({\n cwd: options.cwd,\n yes: true,\n force: true,\n defaults: false,\n skipPreflight: false,\n silent: options.silent && !hasNewRegistries,\n isNewProject: false,\n srcDir: options.srcDir,\n cssVariables: options.cssVariables,\n baseStyle: shouldInstallBaseStyle,\n baseColor: shouldInstallBaseStyle ? undefined : 'neutral',\n components: options.components,\n })\n }\n\n const _shouldUpdateAppIndex = false\n // if (errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]) {\n // const { projectPath, template } = await createProject({\n // cwd: options.cwd,\n // force: options.overwrite,\n // srcDir: options.srcDir,\n // components: options.components,\n // })\n // if (!projectPath) {\n // logger.break()\n // process.exit(1)\n // }\n // options.cwd = projectPath\n\n // if (template === 'next-monorepo') {\n // options.cwd = path.resolve(options.cwd, 'apps/web')\n // config = await getConfig(options.cwd)\n // }\n // else {\n // config = await runInit({\n // cwd: options.cwd,\n // yes: true,\n // force: true,\n // defaults: false,\n // skipPreflight: true,\n // silent: !hasNewRegistries && options.silent,\n // isNewProject: true,\n // srcDir: options.srcDir,\n // cssVariables: options.cssVariables,\n // baseStyle: true,\n // components: options.components,\n // })\n // initHasRun = true\n\n // shouldUpdateAppIndex\n // = options.components?.length === 1\n // && !!options.components[0].match(/\\/chat\\/b\\//)\n // }\n // }\n\n if (!config) {\n throw new Error(\n `Failed to read config at ${highlighter.info(options.cwd)}.`,\n )\n }\n\n const { config: updatedConfig } = await ensureRegistriesInConfig(\n options.components,\n config,\n {\n silent: options.silent || hasNewRegistries,\n },\n )\n config = updatedConfig\n\n if (!initHasRun) {\n await addComponents(options.components, config, {\n ...options,\n baseStyle: shouldInstallBaseStyle,\n })\n }\n\n // If we're adding a single component and it's from the v0 registry,\n // let's update the app/page.tsx file to import the component.\n // if (shouldUpdateAppIndex) {\n // await updateAppIndex(options.components[0], config)\n // }\n }\n catch (error) {\n logger.break()\n handleError(error)\n }\n finally {\n clearRegistryContext()\n }\n })\n\nasync function promptForRegistryComponents(\n options: z.infer<typeof addOptionsSchema>,\n) {\n const registryIndex = await getShadcnRegistryIndex()\n if (!registryIndex) {\n logger.break()\n handleError(new Error('Failed to fetch registry index.'))\n return []\n }\n\n if (options.all) {\n return registryIndex\n .map(entry => entry.name)\n .filter(\n component => !DEPRECATED_COMPONENTS.some(c => c.name === component),\n )\n }\n\n if (options.components?.length) {\n return options.components\n }\n\n const { components } = await prompts({\n type: 'multiselect',\n name: 'components',\n message: 'Which components would you like to add?',\n hint: 'Space to select. A to toggle all. Enter to submit.',\n instructions: false,\n choices: registryIndex\n .filter(\n entry =>\n entry.type === 'registry:ui'\n && !DEPRECATED_COMPONENTS.some(\n component => component.name === entry.name,\n ),\n )\n .map(entry => ({\n title: entry.name,\n value: entry.name,\n selected: options.all ? true : options.components?.includes(entry.name),\n })),\n })\n\n if (!components?.length) {\n logger.warn('No components selected. Exiting.')\n logger.info('')\n process.exit(1)\n }\n\n const result = z.array(z.string()).safeParse(components)\n if (!result.success) {\n logger.error('')\n handleError(new Error('Something went wrong. Please try again.'))\n return []\n }\n return result.data\n}\n","import type { z } from 'zod'\nimport type { buildOptionsSchema } from '@/src/commands/build'\nimport fs from 'fs-extra'\nimport path from 'pathe'\nimport * as ERRORS from '@/src/utils/errors'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\n\nexport async function preFlightBuild(\n options: z.infer<typeof buildOptionsSchema>,\n) {\n const errors: Record<string, boolean> = {}\n\n const resolvePaths = {\n cwd: options.cwd,\n registryFile: path.resolve(options.cwd, options.registryFile),\n outputDir: path.resolve(options.cwd, options.outputDir),\n }\n\n // Ensure registry file exists.\n if (!fs.existsSync(resolvePaths.registryFile)) {\n errors[ERRORS.BUILD_MISSING_REGISTRY_FILE] = true\n }\n\n // Create output directory if it doesn't exist.\n await fs.mkdir(resolvePaths.outputDir, { recursive: true })\n\n if (Object.keys(errors).length > 0) {\n if (errors[ERRORS.BUILD_MISSING_REGISTRY_FILE]) {\n logger.break()\n logger.error(\n `The path ${highlighter.info(\n resolvePaths.registryFile,\n )} does not exist.`,\n )\n }\n\n logger.break()\n process.exit(1)\n }\n\n return {\n errors,\n resolvePaths,\n }\n}\n","import * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\nimport { Command } from 'commander'\nimport { z } from 'zod'\nimport { preFlightBuild } from '@/src/preflights/preflight-build'\nimport { registryItemSchema, registrySchema } from '@/src/schema'\nimport { handleError } from '@/src/utils/handle-error'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\n\nexport const buildOptionsSchema = z.object({\n cwd: z.string(),\n registryFile: z.string(),\n outputDir: z.string(),\n})\n\nexport const build = new Command()\n .name('build')\n .description('Build components for a Frontic UI registry')\n .argument('[registry]', 'path to registry.json file', './registry.json')\n .option(\n '-o, --output <path>',\n 'destination directory for json files',\n './public/r',\n )\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .action(async (registry: string, opts) => {\n try {\n const options = buildOptionsSchema.parse({\n cwd: path.resolve(opts.cwd),\n registryFile: registry,\n outputDir: opts.output,\n })\n\n const { resolvePaths } = await preFlightBuild(options)\n const content = await fs.readFile(resolvePaths.registryFile, 'utf-8')\n\n const result = registrySchema.safeParse(JSON.parse(content))\n\n if (!result.success) {\n logger.error(\n `Invalid registry file found at ${highlighter.info(\n resolvePaths.registryFile,\n )}.`,\n )\n process.exit(1)\n }\n\n const buildSpinner = spinner('Building registry...')\n for (const registryItem of result.data.items) {\n buildSpinner.start(`Building ${registryItem.name}...`)\n\n // Add the schema to the registry item.\n registryItem.$schema\n = 'https://shadcn-vue.com/schema/registry-item.json'\n\n // Loop through each file in the files array.\n for (const file of registryItem.files ?? []) {\n const content = await fs.readFile(\n path.resolve(resolvePaths.cwd, file.path),\n 'utf-8',\n )\n file.content = content.replace(/\\r\\n/g, '\\n')\n }\n\n // Validate the registry item.\n const result = registryItemSchema.safeParse(registryItem)\n if (!result.success) {\n logger.error(\n `Invalid registry item found for ${highlighter.info(\n registryItem.name,\n )}.`,\n )\n continue\n }\n\n // Write the registry item to the output directory.\n await fs.writeFile(\n path.resolve(resolvePaths.outputDir, `${result.data.name}.json`),\n JSON.stringify(result.data, null, 2),\n )\n }\n\n // Copy registry.json to the output directory.\n await fs.copyFile(\n resolvePaths.registryFile,\n path.resolve(resolvePaths.outputDir, 'registry.json'),\n )\n\n buildSpinner.succeed('Building registry.')\n }\n catch (error) {\n logger.break()\n handleError(error)\n }\n })\n","import type { Change } from 'diff'\nimport type { registryIndexSchema } from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport { existsSync, promises as fs } from 'node:fs'\nimport { Command } from 'commander'\nimport { diffLines } from 'diff'\nimport path from 'pathe'\nimport { z } from 'zod'\nimport {\n fetchTree,\n getItemTargetPath,\n getRegistryBaseColor,\n getShadcnRegistryIndex,\n} from '@/src/registry/api'\nimport { getConfig } from '@/src/utils/get-config'\nimport { handleError } from '@/src/utils/handle-error'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { transform } from '@/src/utils/transformers'\n\nconst updateOptionsSchema = z.object({\n component: z.string().optional(),\n yes: z.boolean(),\n cwd: z.string(),\n path: z.string().optional(),\n})\n\nexport const diff = new Command()\n .name('diff')\n .description('check for updates against the registry')\n .argument('[component]', 'the component name')\n .option('-y, --yes', 'skip confirmation prompt.', false)\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .action(async (name, opts) => {\n try {\n const options = updateOptionsSchema.parse({\n component: name,\n ...opts,\n })\n\n const cwd = path.resolve(options.cwd)\n\n if (!existsSync(cwd)) {\n logger.error(`The path ${cwd} does not exist. Please try again.`)\n process.exit(1)\n }\n\n const config = await getConfig(cwd)\n if (!config) {\n logger.warn(\n `Configuration is missing. Please run ${highlighter.success(\n `init`,\n )} to create a components.json file.`,\n )\n process.exit(1)\n }\n\n const registryIndex = await getShadcnRegistryIndex()\n\n if (!registryIndex) {\n handleError(new Error('Failed to fetch registry index.'))\n process.exit(1)\n }\n\n if (!options.component) {\n const targetDir = config.resolvedPaths.components\n\n // Find all components that exist in the project.\n const projectComponents = registryIndex.filter((item) => {\n for (const file of item.files ?? []) {\n const filePath = path.resolve(\n targetDir,\n typeof file === 'string' ? file : file.path,\n )\n if (existsSync(filePath)) {\n return true\n }\n }\n\n return false\n })\n\n // Check for updates.\n const componentsWithUpdates = []\n for (const component of projectComponents) {\n const changes = await diffComponent(component, config)\n if (changes.length) {\n componentsWithUpdates.push({\n name: component.name,\n changes,\n })\n }\n }\n\n if (!componentsWithUpdates.length) {\n logger.info('No updates found.')\n process.exit(0)\n }\n\n logger.info('The following components have updates available:')\n for (const component of componentsWithUpdates) {\n logger.info(`- ${component.name}`)\n for (const change of component.changes) {\n logger.info(` - ${change.filePath}`)\n }\n }\n logger.break()\n logger.info(\n `Run ${highlighter.success(`diff <component>`)} to see the changes.`,\n )\n process.exit(0)\n }\n\n // Show diff for a single component.\n const component = registryIndex.find(\n item => item.name === options.component,\n )\n\n if (!component) {\n logger.error(\n `The component ${highlighter.success(\n options.component,\n )} does not exist.`,\n )\n process.exit(1)\n }\n\n const changes = await diffComponent(component, config)\n\n if (!changes.length) {\n logger.info(`No updates found for ${options.component}.`)\n process.exit(0)\n }\n\n for (const change of changes) {\n logger.info(`- ${change.filePath}`)\n await printDiff(change.patch)\n logger.info('')\n }\n }\n catch (error) {\n handleError(error)\n }\n })\n\nasync function diffComponent(\n component: z.infer<typeof registryIndexSchema>[number],\n config: Config,\n) {\n const payload = await fetchTree(config.style, [component])\n const baseColor = await getRegistryBaseColor(config.tailwind.baseColor)\n\n if (!payload) {\n return []\n }\n\n const changes = []\n\n for (const item of payload) {\n const targetDir = await getItemTargetPath(config, item)\n\n if (!targetDir) {\n continue\n }\n\n for (const file of item.files ?? []) {\n const filePath = path.resolve(\n targetDir,\n typeof file === 'string' ? file : file.path,\n )\n\n if (!existsSync(filePath)) {\n continue\n }\n\n const fileContent = await fs.readFile(filePath, 'utf8')\n\n if (typeof file === 'string' || !file.content) {\n continue\n }\n\n const registryContent = await transform({\n filename: file.path,\n raw: file.content,\n config,\n baseColor,\n })\n\n const patch = diffLines(registryContent as string, fileContent)\n if (patch.length > 1) {\n changes.push({\n filePath,\n patch,\n })\n }\n }\n }\n\n return changes\n}\n\nasync function printDiff(diff: Change[]) {\n diff.forEach((part) => {\n if (part) {\n if (part.added) {\n return process.stdout.write(highlighter.success(part.value))\n }\n if (part.removed) {\n return process.stdout.write(highlighter.error(part.value))\n }\n\n return process.stdout.write(part.value)\n }\n })\n}\n","import { Command } from 'commander'\nimport consola from 'consola'\nimport { getConfig } from '@/src/utils/get-config'\nimport { getProjectInfo } from '@/src/utils/get-project-info'\nimport { handleError } from '@/src/utils/handle-error'\nimport { logger } from '@/src/utils/logger'\n\nexport const info = new Command()\n .name('info')\n .description('get information about your project')\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .action(async (opts) => {\n try {\n logger.info('> project info')\n consola.log(await getProjectInfo(opts.cwd))\n logger.break()\n logger.info('> components.json')\n consola.log(await getConfig(opts.cwd))\n }\n catch (error) {\n handleError(error)\n }\n })\n","import { promises as fs } from 'node:fs'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { Command } from 'commander'\nimport deepmerge from 'deepmerge'\nimport fsExtra from 'fs-extra'\nimport { detectPackageManager } from 'nypm'\nimport path from 'pathe'\nimport prompts from 'prompts'\nimport { x } from 'tinyexec'\nimport z from 'zod'\nimport { server } from '@/src/mcp'\nimport { REGISTRY_URL } from '@/src/registry/constants'\nimport { loadEnvFiles } from '@/src/utils/env-loader'\nimport { getConfig } from '@/src/utils/get-config'\nimport { handleError } from '@/src/utils/handle-error'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\nimport { updateDependencies } from '@/src/utils/updaters/update-dependencies'\n\nconst FRONTIC_MCP_VERSION = 'latest'\n\nconst CLIENTS = [\n {\n name: 'claude',\n label: 'Claude Code',\n configPath: '.mcp.json',\n config: {\n mcpServers: {\n 'frontic-ui': {\n command: 'npx',\n args: [`@frontic/ui@${FRONTIC_MCP_VERSION}`, 'mcp'],\n env: {\n REGISTRY_URL,\n },\n },\n },\n },\n },\n {\n name: 'cursor',\n label: 'Cursor',\n configPath: '.cursor/mcp.json',\n config: {\n mcpServers: {\n 'frontic-ui': {\n command: 'npx',\n args: [`@frontic/ui@${FRONTIC_MCP_VERSION}`, 'mcp'],\n env: {\n REGISTRY_URL,\n },\n },\n },\n },\n },\n {\n name: 'vscode',\n label: 'VS Code',\n configPath: '.vscode/mcp.json',\n config: {\n servers: {\n 'frontic-ui': {\n command: 'npx',\n args: [`@frontic/ui@${FRONTIC_MCP_VERSION}`, 'mcp'],\n env: {\n REGISTRY_URL,\n },\n },\n },\n },\n },\n {\n name: 'codex',\n label: 'Codex',\n configPath: '.codex/config.toml',\n config: `[mcp_servers.frontic_ui]\ncommand = \"npx\"\nargs = [\"@frontic/ui@${FRONTIC_MCP_VERSION}\", \"mcp\"]\n`,\n },\n {\n name: 'opencode',\n label: 'Opencode',\n configPath: 'opencode.json',\n config: {\n $schema: 'https://opencode.ai/config.json',\n mcp: {\n 'frontic-ui': {\n type: 'local',\n enabled: true,\n command: ['npx', `@frontic/ui@${FRONTIC_MCP_VERSION}`, 'mcp'],\n },\n },\n },\n },\n] as const\n\nconst DEPENDENCIES = [`@frontic/ui@${FRONTIC_MCP_VERSION}`]\n\nexport const mcp = new Command()\n .name('mcp')\n .description('MCP server and configuration commands')\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .action(async (options) => {\n try {\n await loadEnvFiles(options.cwd)\n const transport = new StdioServerTransport()\n await server.connect(transport)\n }\n catch (error) {\n logger.break()\n handleError(error)\n }\n })\n\nconst mcpInitOptionsSchema = z.object({\n client: z.enum(['claude', 'cursor', 'vscode', 'codex', 'opencode']),\n cwd: z.string(),\n})\n\nmcp\n .command('init')\n .description('Initialize MCP configuration for your client')\n .option(\n '--client <client>',\n `MCP client (${CLIENTS.map(c => c.name).join(', ')})`,\n )\n .action(async (opts, command) => {\n try {\n // Get the cwd from parent command.\n const parentOpts = command.parent?.opts() || {}\n const cwd = parentOpts.cwd || process.cwd()\n\n let client = opts.client\n\n if (!client) {\n const response = await prompts({\n type: 'select',\n name: 'client',\n message: 'Which MCP client are you using?',\n choices: CLIENTS.map(c => ({\n title: c.label,\n value: c.name,\n })),\n })\n\n if (!response.client) {\n logger.break()\n process.exit(1)\n }\n\n client = response.client\n }\n\n const options = mcpInitOptionsSchema.parse({\n client,\n cwd,\n })\n\n const config = await getConfig(options.cwd)\n\n if (options.client === 'codex') {\n if (config) {\n await updateDependencies([], DEPENDENCIES, config, {\n silent: false,\n })\n }\n else {\n const packageManager = await detectPackageManager(options.cwd)\n const installCommand = packageManager?.name === 'npm' ? 'install' : 'add'\n const devFlag = packageManager?.name === 'npm' ? '--save-dev' : '-D'\n\n const installSpinner = spinner('Installing dependencies...').start()\n await x(\n packageManager?.name || 'npm',\n [installCommand, devFlag, ...DEPENDENCIES],\n {\n nodeOptions: {\n cwd: options.cwd,\n },\n },\n )\n installSpinner.succeed('Installing dependencies.')\n }\n\n logger.break()\n logger.log('To configure the Frontic UI MCP server in Codex:')\n logger.break()\n logger.log(\n `1. Open or create the file ${highlighter.info(\n '~/.codex/config.toml',\n )}`,\n )\n logger.log('2. Add the following configuration:')\n logger.log()\n logger.info(`[mcp_servers.frontic_ui]\ncommand = \"npx\"\nargs = [\"@frontic/ui@${FRONTIC_MCP_VERSION}\", \"mcp\"]`)\n logger.break()\n logger.info('3. Restart Codex to load the MCP server')\n logger.break()\n process.exit(0)\n }\n\n const configSpinner = spinner('Configuring MCP server...').start()\n const configPath = await runMcpInit(options)\n configSpinner.succeed('Configuring MCP server.')\n\n if (config) {\n await updateDependencies([], DEPENDENCIES, config, {\n silent: false,\n })\n }\n else {\n const packageManager = await detectPackageManager(options.cwd)\n const installCommand = packageManager?.name === 'npm' ? 'install' : 'add'\n const devFlag = packageManager?.name === 'npm' ? '--save-dev' : '-D'\n\n const installSpinner = spinner('Installing dependencies...').start()\n await x(\n packageManager?.name || 'npm',\n [installCommand, devFlag, ...DEPENDENCIES],\n {\n nodeOptions: {\n cwd: options.cwd,\n },\n },\n )\n installSpinner.succeed('Installing dependencies.')\n }\n\n logger.break()\n logger.success(`Configuration saved to ${configPath}.`)\n logger.break()\n }\n catch (error) {\n handleError(error)\n }\n })\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst overwriteMerge = (_destArray: any[], sourceArray: any[]) => sourceArray\n\nasync function runMcpInit(options: z.infer<typeof mcpInitOptionsSchema>) {\n const { client, cwd } = options\n\n const clientInfo = CLIENTS.find(c => c.name === client)\n if (!clientInfo) {\n throw new Error(\n `Unknown client: ${client}. Available clients: ${CLIENTS.map(\n c => c.name,\n ).join(', ')}`,\n )\n }\n\n const configPath = path.join(cwd, clientInfo.configPath)\n const dir = path.dirname(configPath)\n await fsExtra.ensureDir(dir)\n\n let existingConfig = {}\n try {\n const content = await fs.readFile(configPath, 'utf-8')\n existingConfig = JSON.parse(content)\n }\n catch {\n // Config file doesn't exist yet, use empty object\n }\n\n const mergedConfig = deepmerge(\n existingConfig,\n clientInfo.config as Record<string, unknown>,\n { arrayMerge: overwriteMerge },\n )\n\n await fs.writeFile(\n configPath,\n `${JSON.stringify(mergedConfig, null, 2)}\\n`,\n 'utf-8',\n )\n\n return clientInfo.configPath\n}\n","import type { z } from 'zod'\nimport type { iconsSchema } from '@/src/schema'\nimport type { Config } from '@/src/utils/get-config'\nimport { randomBytes } from 'node:crypto'\nimport { promises as fs } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport path from 'pathe'\nimport prompts from 'prompts'\nimport { glob } from 'tinyglobby'\nimport { Project, ScriptKind, SyntaxKind } from 'ts-morph'\nimport { getRegistryIcons } from '@/src/registry/api'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { ICON_LIBRARIES } from '@/src/utils/icon-libraries'\nimport { logger } from '@/src/utils/logger'\nimport { spinner } from '@/src/utils/spinner'\nimport { updateDependencies } from '@/src/utils/updaters/update-dependencies'\n\nexport async function migrateIcons(config: Config) {\n if (!config.resolvedPaths.ui) {\n throw new Error(\n 'We could not find a valid `ui` path in your `components.json` file. Please ensure you have a valid `ui` path in your `components.json` file.',\n )\n }\n\n const uiPath = config.resolvedPaths.ui\n const [files, registryIcons] = await Promise.all([\n glob('**/*.{js,ts,jsx,tsx}', {\n cwd: uiPath,\n }),\n getRegistryIcons(),\n ])\n\n if (Object.keys(registryIcons).length === 0) {\n throw new Error('Something went wrong fetching the registry icons.')\n }\n\n const libraryChoices = Object.entries(ICON_LIBRARIES).map(\n ([name, iconLibrary]) => ({\n title: iconLibrary.name,\n value: name,\n }),\n )\n\n const migrateOptions = await prompts([\n {\n type: 'select',\n name: 'sourceLibrary',\n message: `Which icon library would you like to ${highlighter.info(\n 'migrate from',\n )}?`,\n choices: libraryChoices,\n },\n {\n type: 'select',\n name: 'targetLibrary',\n message: `Which icon library would you like to ${highlighter.info(\n 'migrate to',\n )}?`,\n choices: libraryChoices,\n },\n ])\n\n if (migrateOptions.sourceLibrary === migrateOptions.targetLibrary) {\n throw new Error(\n 'You cannot migrate to the same icon library. Please choose a different icon library.',\n )\n }\n\n if (\n !(\n migrateOptions.sourceLibrary in ICON_LIBRARIES\n && migrateOptions.targetLibrary in ICON_LIBRARIES\n )\n ) {\n throw new Error('Invalid icon library. Please choose a valid icon library.')\n }\n\n const sourceLibrary\n = ICON_LIBRARIES[migrateOptions.sourceLibrary as keyof typeof ICON_LIBRARIES]\n const targetLibrary\n = ICON_LIBRARIES[migrateOptions.targetLibrary as keyof typeof ICON_LIBRARIES]\n const { confirm } = await prompts({\n type: 'confirm',\n name: 'confirm',\n initial: true,\n message: `We will migrate ${highlighter.info(\n files.length,\n )} files in ${highlighter.info(\n `./${path.relative(config.resolvedPaths.cwd, uiPath)}`,\n )} from ${highlighter.info(sourceLibrary.name)} to ${highlighter.info(\n targetLibrary.name,\n )}. Continue?`,\n })\n\n if (!confirm) {\n logger.info('Migration cancelled.')\n process.exit(0)\n }\n\n if (targetLibrary.package) {\n await updateDependencies([targetLibrary.package], [], config, {\n silent: false,\n })\n }\n\n const migrationSpinner = spinner(`Migrating icons...`)?.start()\n\n await Promise.all(\n files.map(async (file) => {\n migrationSpinner.text = `Migrating ${file}...`\n\n const filePath = path.join(uiPath, file)\n const fileContent = await fs.readFile(filePath, 'utf-8')\n\n const content = await migrateIconsFile(\n fileContent,\n migrateOptions.sourceLibrary,\n migrateOptions.targetLibrary,\n registryIcons,\n )\n\n await fs.writeFile(filePath, content)\n }),\n )\n\n migrationSpinner.succeed('Migration complete.')\n}\n\nexport async function migrateIconsFile(\n content: string,\n sourceLibrary: keyof typeof ICON_LIBRARIES,\n targetLibrary: keyof typeof ICON_LIBRARIES,\n iconsMapping: z.infer<typeof iconsSchema>,\n) {\n const sourceLibraryImport = ICON_LIBRARIES[sourceLibrary]?.import\n const targetLibraryImport = ICON_LIBRARIES[targetLibrary]?.import\n\n const dir = await fs.mkdtemp(path.join(tmpdir(), 'shadcn-'))\n const project = new Project({\n compilerOptions: {},\n })\n\n const tempFile = path.join(\n dir,\n `shadcn-icons-${randomBytes(4).toString('hex')}.tsx`,\n )\n const sourceFile = project.createSourceFile(tempFile, content, {\n scriptKind: ScriptKind.TSX,\n })\n\n // Find all sourceLibrary imports.\n const targetedIcons: string[] = []\n for (const importDeclaration of sourceFile.getImportDeclarations() ?? []) {\n if (\n importDeclaration.getModuleSpecifier()?.getText()\n !== `\"${sourceLibraryImport}\"`\n ) {\n continue\n }\n\n for (const specifier of importDeclaration.getNamedImports() ?? []) {\n const iconName = specifier.getName()\n\n // TODO: this is O(n^2) but okay for now.\n const targetedIcon = Object.values(iconsMapping).find(\n icon => icon[sourceLibrary] === iconName,\n )?.[targetLibrary]\n\n if (!targetedIcon || targetedIcons.includes(targetedIcon)) {\n continue\n }\n\n targetedIcons.push(targetedIcon)\n\n // Remove the named import.\n specifier.remove()\n\n // Replace with the targeted icon.\n sourceFile\n .getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement)\n .filter(node => node.getTagNameNode()?.getText() === iconName)\n .forEach(node => node.getTagNameNode()?.replaceWithText(targetedIcon))\n }\n\n // If the named import is empty, remove the import declaration.\n if (importDeclaration.getNamedImports()?.length === 0) {\n importDeclaration.remove()\n }\n }\n\n if (targetedIcons.length > 0) {\n sourceFile.addImportDeclaration({\n moduleSpecifier: targetLibraryImport,\n namedImports: targetedIcons.map(icon => ({\n name: icon,\n })),\n })\n }\n\n return await sourceFile.getText()\n}\n","import type { z } from 'zod'\nimport type { migrateOptionsSchema } from '@/src/commands/migrate'\nimport fs from 'fs-extra'\nimport path from 'pathe'\n// import { addOptionsSchema } from '@/src/commands/add'\nimport * as ERRORS from '@/src/utils/errors'\nimport { getConfig } from '@/src/utils/get-config'\nimport { highlighter } from '@/src/utils/highlighter'\nimport { logger } from '@/src/utils/logger'\n\nexport async function preFlightMigrate(\n options: z.infer<typeof migrateOptionsSchema>,\n) {\n const errors: Record<string, boolean> = {}\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd)\n || !fs.existsSync(path.resolve(options.cwd, 'package.json'))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true\n return {\n errors,\n config: null,\n }\n }\n\n // Check for existing components.json file.\n if (!fs.existsSync(path.resolve(options.cwd, 'components.json'))) {\n errors[ERRORS.MISSING_CONFIG] = true\n return {\n errors,\n config: null,\n }\n }\n\n try {\n const config = await getConfig(options.cwd)\n\n return {\n errors,\n config: config!,\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n catch (_error) {\n logger.break()\n logger.error(\n `An invalid ${highlighter.info(\n 'components.json',\n )} file was found at ${highlighter.info(\n options.cwd,\n )}.\\nBefore you can run a migration, you must create a valid ${highlighter.info(\n 'components.json',\n )} file by running the ${highlighter.info('init')} command.`,\n )\n logger.error(\n `Learn more at ${highlighter.info(\n 'https://frontic.io/docs/components-json',\n )}.`,\n )\n logger.break()\n process.exit(1)\n }\n}\n","import { Command } from 'commander'\nimport path from 'pathe'\nimport { z } from 'zod'\nimport { migrateIcons } from '@/src/migrations/migrate-icons'\n// import { migrateRadix } from '@/src/migrations/migrate-radix'\nimport { preFlightMigrate } from '@/src/preflights/preflight-migrate'\nimport * as ERRORS from '@/src/utils/errors'\nimport { handleError } from '@/src/utils/handle-error'\nimport { logger } from '@/src/utils/logger'\n\nexport const migrations = [\n {\n name: 'icons',\n description: 'migrate your ui components to a different icon library.',\n },\n // {\n // name: 'radix',\n // description: 'migrate to radix-ui.',\n // },\n] as const\n\nexport const migrateOptionsSchema = z.object({\n cwd: z.string(),\n list: z.boolean(),\n yes: z.boolean(),\n migration: z\n .string()\n .refine(\n value =>\n value && migrations.some(migration => migration.name === value),\n {\n message:\n 'You must specify a valid migration. Run `frontic-ui migrate --list` to see available migrations.',\n },\n )\n .optional(),\n})\n\nexport const migrate = new Command()\n .name('migrate')\n .description('run a migration.')\n .argument('[migration]', 'the migration to run.')\n .option(\n '-c, --cwd <cwd>',\n 'the working directory. defaults to the current directory.',\n process.cwd(),\n )\n .option('-l, --list', 'list all migrations.', false)\n .option('-y, --yes', 'skip confirmation prompt.', false)\n .action(async (migration, opts) => {\n try {\n const options = migrateOptionsSchema.parse({\n cwd: path.resolve(opts.cwd),\n migration,\n list: opts.list,\n yes: opts.yes,\n })\n\n if (options.list || !options.migration) {\n logger.info('Available migrations:')\n for (const migration of migrations) {\n logger.info(`- ${migration.name}: ${migration.description}`)\n }\n return\n }\n\n if (!options.migration) {\n throw new Error(\n 'You must specify a migration. Run `frontic-ui migrate --list` to see available migrations.',\n )\n }\n\n const { errors, config } = await preFlightMigrate(options)\n\n if (\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]\n || errors[ERRORS.MISSING_CONFIG]\n ) {\n throw new Error(\n 'No `components.json` file found. Ensure you are at the root of your project.',\n )\n }\n\n if (!config) {\n throw new Error(\n 'Something went wrong reading your `components.json` file. Please ensure you have a valid `components.json` file.',\n )\n }\n\n if (options.migration === 'icons') {\n await migrateIcons(config)\n }\n\n // if (options.migration === 'radix') {\n // await migrateRadix(config, { yes: options.yes })\n // }\n }\n catch (error) {\n logger.break()\n handleError(error)\n }\n })\n","{\n \"name\": \"@frontic/ui\",\n \"version\": \"0.5.1\",\n \"description\": \"CLI for adding Frontic UI components to your Vue project\",\n \"type\": \"module\",\n \"bin\": \"./dist/index.js\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./registry\": {\n \"types\": \"./dist/registry/index.d.ts\",\n \"default\": \"./dist/registry/index.js\"\n },\n \"./schema\": {\n \"types\": \"./dist/schema/index.d.ts\",\n \"default\": \"./dist/schema/index.js\"\n },\n \"./mcp\": {\n \"types\": \"./dist/mcp/index.d.ts\",\n \"default\": \"./dist/mcp/index.js\"\n }\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"dev\": \"tsdown --watch\",\n \"build\": \"tsdown\",\n \"typecheck\": \"echo 'Skipping typecheck for vendored CLI code - build validates types'\",\n \"test\": \"vitest run\",\n \"test:unit\": \"vitest run tests/unit\",\n \"test:e2e\": \"vitest run tests/e2e\",\n \"test:watch\": \"vitest\",\n \"clean\": \"rm -rf dist\",\n \"start\": \"node dist/index.js\"\n },\n \"dependencies\": {\n \"@dotenvx/dotenvx\": \"^1.51.1\",\n \"@modelcontextprotocol/sdk\": \"^1.24.3\",\n \"@unovue/detypes\": \"^0.8.5\",\n \"@vue/compiler-sfc\": \"^3.5.0\",\n \"c12\": \"^3.3.2\",\n \"commander\": \"^14.0.2\",\n \"consola\": \"^3.4.2\",\n \"dedent\": \"^1.7.0\",\n \"deepmerge\": \"^4.3.1\",\n \"diff\": \"^8.0.2\",\n \"fs-extra\": \"^11.3.2\",\n \"fuzzysort\": \"^3.1.0\",\n \"get-tsconfig\": \"^4.13.0\",\n \"magic-string\": \"^0.30.21\",\n \"nypm\": \"^0.6.2\",\n \"ofetch\": \"^1.5.1\",\n \"ora\": \"^9.0.0\",\n \"pathe\": \"^2.0.3\",\n \"postcss\": \"^8.5.6\",\n \"prompts\": \"^2.4.2\",\n \"reka-ui\": \"^2.2.1\",\n \"semver\": \"^7.7.3\",\n \"stringify-object\": \"^6.0.0\",\n \"tailwindcss\": \"^4.1.17\",\n \"tinyexec\": \"^1.0.2\",\n \"tinyglobby\": \"^0.2.13\",\n \"ts-morph\": \"^27.0.2\",\n \"undici\": \"^7.16.0\",\n \"vue-metamorph\": \"^3.3.3\",\n \"zod\": \"^3.25.0\",\n \"zod-to-json-schema\": \"^3.25.0\"\n },\n \"devDependencies\": {\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/node\": \"^22.19.2\",\n \"@types/prompts\": \"^2.4.9\",\n \"@types/semver\": \"^7.7.1\",\n \"@types/stringify-object\": \"^4.0.5\",\n \"msw\": \"^2.12.4\",\n \"tsdown\": \"^0.17.2\",\n \"type-fest\": \"^5.3.1\",\n \"typescript\": \"^5.7.2\",\n \"vitest\": \"^2.1.8\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/frontic/frontic-ui.git\",\n \"directory\": \"packages/cli\"\n },\n \"keywords\": [\n \"vue\",\n \"nuxt\",\n \"components\",\n \"ui\",\n \"shadcn\",\n \"shadcn-vue\",\n \"frontic\",\n \"frontic-ui\",\n \"tailwind\",\n \"radix-ui\",\n \"radix-vue\",\n \"reka-ui\",\n \"cli\"\n ],\n \"author\": \"Frontic\",\n \"license\": \"MIT\"\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander'\nimport { add } from '@/src/commands/add'\nimport { build } from '@/src/commands/build'\nimport { diff } from '@/src/commands/diff'\nimport { info } from '@/src/commands/info'\nimport { init } from '@/src/commands/init'\nimport { mcp } from '@/src/commands/mcp'\nimport { migrate } from '@/src/commands/migrate'\n\nimport packageJson from '../package.json'\n\nprocess.on('SIGINT', () => process.exit(0))\nprocess.on('SIGTERM', () => process.exit(0))\n\nasync function main() {\n const program = new Command()\n .name('frontic-ui')\n .description('Add Frontic UI components to your Vue/Nuxt project')\n .version(\n packageJson.version || '1.0.0',\n '-v, --version',\n 'display the version number',\n )\n\n program\n .addCommand(init)\n .addCommand(add)\n .addCommand(diff)\n .addCommand(migrate)\n .addCommand(info)\n .addCommand(build)\n .addCommand(mcp)\n\n program.parse()\n}\n\nmain()\n\nexport * from './registry/api'\n"],"mappings":"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"}