@frontic/ui 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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","configSpinner","configPath","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} 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 // 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://schema.frontic.io/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://schema.frontic.io/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'\nconst REMOTE_MCP_URL = 'https://ui.frontic.io/mcp'\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\n// Remote MCP client configs (connect to hosted Cloudflare Worker via Streamable HTTP)\nconst REMOTE_CLIENTS = [\n {\n name: 'claude',\n label: 'Claude Code',\n configPath: '.mcp.json',\n config: {\n mcpServers: {\n 'frontic-ui': {\n type: 'streamable-http',\n url: REMOTE_MCP_URL,\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: ['mcp-remote', REMOTE_MCP_URL],\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 type: 'http',\n url: REMOTE_MCP_URL,\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 = [\"mcp-remote\", \"${REMOTE_MCP_URL}\"]\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: 'remote',\n enabled: true,\n url: REMOTE_MCP_URL,\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 local: z.boolean().default(false),\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 .option(\n '--local',\n 'Use local MCP server via npx instead of the hosted remote server',\n false,\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 let local = opts.local\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 if (!local) {\n const modeResponse = await prompts({\n type: 'select',\n name: 'mode',\n message: 'How do you want to run the MCP server?',\n choices: [\n {\n title: 'Remote (hosted)',\n value: 'remote',\n description: 'Connects to hosted server — no install needed',\n },\n {\n title: 'Local (npx)',\n value: 'local',\n description: 'Runs locally via npx — requires Node.js',\n },\n ],\n })\n\n if (!modeResponse.mode) {\n logger.break()\n process.exit(1)\n }\n\n local = modeResponse.mode === 'local'\n }\n\n const options = mcpInitOptionsSchema.parse({\n client,\n cwd,\n local,\n })\n\n // Remote mode (default): just write the config, no deps needed\n if (!options.local) {\n const clientList = REMOTE_CLIENTS\n const clientInfo = clientList.find(c => c.name === options.client)\n\n if (!clientInfo) {\n throw new Error(`Unknown client: ${options.client}`)\n }\n\n if (options.client === 'codex') {\n logger.break()\n logger.log('To configure the Frontic UI MCP server (remote) 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(clientInfo.config as string)\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 remote MCP server...').start()\n const configPath = await runMcpInit(options, clientList)\n configSpinner.succeed('Configuring remote MCP server.')\n\n logger.break()\n logger.success(`Configuration saved to ${configPath}.`)\n logger.info('Using hosted remote server — no local dependencies needed.')\n logger.break()\n return\n }\n\n // Local mode: original behavior\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(\n options: z.infer<typeof mcpInitOptionsSchema>,\n clientList: ReadonlyArray<{ name: string, label: string, configPath: string, config: unknown }> = CLIENTS,\n) {\n const { client, cwd } = options\n\n const clientInfo = clientList.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.8.0\",\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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"}
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","configSpinner","configPath","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} 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 // 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://ui.frontic.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://ui.frontic.com/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://ui.frontic.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'\nconst REMOTE_MCP_URL = 'https://mcp.ui.frontic.com/mcp'\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\n// Remote MCP client configs (connect to hosted Cloudflare Worker via Streamable HTTP)\nconst REMOTE_CLIENTS = [\n {\n name: 'claude',\n label: 'Claude Code',\n configPath: '.mcp.json',\n config: {\n mcpServers: {\n 'frontic-ui': {\n type: 'http',\n url: REMOTE_MCP_URL,\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: ['mcp-remote', REMOTE_MCP_URL],\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 type: 'http',\n url: REMOTE_MCP_URL,\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 = [\"mcp-remote\", \"${REMOTE_MCP_URL}\"]\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: 'remote',\n enabled: true,\n url: REMOTE_MCP_URL,\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 local: z.boolean().default(false),\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 .option(\n '--local',\n 'Use local MCP server via npx instead of the hosted remote server',\n false,\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 let local = opts.local\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 if (!local) {\n const modeResponse = await prompts({\n type: 'select',\n name: 'mode',\n message: 'How do you want to run the MCP server?',\n choices: [\n {\n title: 'Remote (hosted)',\n value: 'remote',\n description: 'Connects to hosted server — no install needed',\n },\n {\n title: 'Local (npx)',\n value: 'local',\n description: 'Runs locally via npx — requires Node.js',\n },\n ],\n })\n\n if (!modeResponse.mode) {\n logger.break()\n process.exit(1)\n }\n\n local = modeResponse.mode === 'local'\n }\n\n const options = mcpInitOptionsSchema.parse({\n client,\n cwd,\n local,\n })\n\n // Remote mode (default): just write the config, no deps needed\n if (!options.local) {\n const clientList = REMOTE_CLIENTS\n const clientInfo = clientList.find(c => c.name === options.client)\n\n if (!clientInfo) {\n throw new Error(`Unknown client: ${options.client}`)\n }\n\n if (options.client === 'codex') {\n logger.break()\n logger.log('To configure the Frontic UI MCP server (remote) 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(clientInfo.config as string)\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 remote MCP server...').start()\n const configPath = await runMcpInit(options, clientList)\n configSpinner.succeed('Configuring remote MCP server.')\n\n logger.break()\n logger.success(`Configuration saved to ${configPath}.`)\n logger.info('Using hosted remote server — no local dependencies needed.')\n logger.break()\n return\n }\n\n // Local mode: original behavior\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(\n options: z.infer<typeof mcpInitOptionsSchema>,\n clientList: ReadonlyArray<{ name: string, label: string, configPath: string, config: unknown }> = CLIENTS,\n) {\n const { client, cwd } = options\n\n const clientInfo = clientList.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://ui.frontic.com/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.8.2\",\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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"}