@frontic/ui 0.0.3 → 0.0.5
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/bin/frontic-ui.js +113 -55
- package/dist/bin/frontic-ui.js.map +1 -1
- package/dist/index.js +113 -55
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/bin/frontic-ui.js
CHANGED
|
@@ -31,6 +31,7 @@ import { join } from "path";
|
|
|
31
31
|
// src/utils/constants.ts
|
|
32
32
|
var FRONTIC_REGISTRY_URL = "https://registry.frontic.io/r/{name}.json";
|
|
33
33
|
var CONFIG_FILE = "components.json";
|
|
34
|
+
var DEFAULT_BRAND_COLOR = "oklch(58% 0.25 265)";
|
|
34
35
|
|
|
35
36
|
// src/utils/config.ts
|
|
36
37
|
async function configExists() {
|
|
@@ -99,9 +100,85 @@ function deepMerge(target, source) {
|
|
|
99
100
|
return result;
|
|
100
101
|
}
|
|
101
102
|
|
|
103
|
+
// src/utils/colors.ts
|
|
104
|
+
function isValidHex(hex) {
|
|
105
|
+
const cleanHex = hex.replace(/^#/, "");
|
|
106
|
+
return /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/.test(cleanHex);
|
|
107
|
+
}
|
|
108
|
+
function normalizeHex(hex) {
|
|
109
|
+
const cleanHex = hex.replace(/^#/, "");
|
|
110
|
+
if (cleanHex.length === 3) {
|
|
111
|
+
return cleanHex.split("").map((c) => c + c).join("");
|
|
112
|
+
}
|
|
113
|
+
return cleanHex;
|
|
114
|
+
}
|
|
115
|
+
function hexToRgb(hex) {
|
|
116
|
+
const normalizedHex = normalizeHex(hex);
|
|
117
|
+
return {
|
|
118
|
+
r: parseInt(normalizedHex.slice(0, 2), 16),
|
|
119
|
+
g: parseInt(normalizedHex.slice(2, 4), 16),
|
|
120
|
+
b: parseInt(normalizedHex.slice(4, 6), 16)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function srgbToLinear(value) {
|
|
124
|
+
const normalized = value / 255;
|
|
125
|
+
return normalized <= 0.04045 ? normalized / 12.92 : Math.pow((normalized + 0.055) / 1.055, 2.4);
|
|
126
|
+
}
|
|
127
|
+
function linearRgbToXyz(r, g, b) {
|
|
128
|
+
return {
|
|
129
|
+
x: 0.4124564 * r + 0.3575761 * g + 0.1804375 * b,
|
|
130
|
+
y: 0.2126729 * r + 0.7151522 * g + 0.072175 * b,
|
|
131
|
+
z: 0.0193339 * r + 0.119192 * g + 0.9503041 * b
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function xyzToOklab(x, y, z) {
|
|
135
|
+
const l_ = Math.cbrt(0.8189330101 * x + 0.3618667424 * y - 0.1288597137 * z);
|
|
136
|
+
const m_ = Math.cbrt(0.0329845436 * x + 0.9293118715 * y + 0.0361456387 * z);
|
|
137
|
+
const s_ = Math.cbrt(-0.0482003018 * x + 0.2643662691 * y + 0.633851707 * z);
|
|
138
|
+
return {
|
|
139
|
+
l: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,
|
|
140
|
+
a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,
|
|
141
|
+
b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function oklabToOklch(l, a, b) {
|
|
145
|
+
const c = Math.sqrt(a * a + b * b);
|
|
146
|
+
let h = Math.atan2(b, a) * (180 / Math.PI);
|
|
147
|
+
if (h < 0) h += 360;
|
|
148
|
+
return { l, c, h };
|
|
149
|
+
}
|
|
150
|
+
function hexToOklch(hex) {
|
|
151
|
+
if (!isValidHex(hex)) {
|
|
152
|
+
throw new Error(`Invalid hex color: ${hex}`);
|
|
153
|
+
}
|
|
154
|
+
const { r, g, b } = hexToRgb(hex);
|
|
155
|
+
const linearR = srgbToLinear(r);
|
|
156
|
+
const linearG = srgbToLinear(g);
|
|
157
|
+
const linearB = srgbToLinear(b);
|
|
158
|
+
const { x, y, z } = linearRgbToXyz(linearR, linearG, linearB);
|
|
159
|
+
const oklab = xyzToOklab(x, y, z);
|
|
160
|
+
const { l, c, h } = oklabToOklch(oklab.l, oklab.a, oklab.b);
|
|
161
|
+
const lightness = Math.round(l * 100);
|
|
162
|
+
const chroma = Math.round(c * 100) / 100;
|
|
163
|
+
const hue = Math.round(h);
|
|
164
|
+
return `oklch(${lightness}% ${chroma} ${hue})`;
|
|
165
|
+
}
|
|
166
|
+
function getForegroundColor(oklchOrHex) {
|
|
167
|
+
let lightness;
|
|
168
|
+
if (oklchOrHex.startsWith("oklch")) {
|
|
169
|
+
const match = oklchOrHex.match(/oklch\((\d+)%/);
|
|
170
|
+
lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;
|
|
171
|
+
} else {
|
|
172
|
+
const oklch = hexToOklch(oklchOrHex);
|
|
173
|
+
const match = oklch.match(/oklch\((\d+)%/);
|
|
174
|
+
lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;
|
|
175
|
+
}
|
|
176
|
+
return lightness > 0.6 ? "oklch(20% 0 0)" : "oklch(100% 0 0)";
|
|
177
|
+
}
|
|
178
|
+
|
|
102
179
|
// src/commands/init.ts
|
|
103
180
|
function registerInitCommand(program2) {
|
|
104
|
-
program2.command("init").description("Initialize Frontic UI in your Vue project").option("-y, --yes", "Skip confirmation prompts").option("-d, --defaults", "Use default configuration").option("-f, --force", "Force overwrite of existing configuration").action(async (options) => {
|
|
181
|
+
program2.command("init").description("Initialize Frontic UI in your Vue project").option("-y, --yes", "Skip confirmation prompts").option("-d, --defaults", "Use default configuration").option("-f, --force", "Force overwrite of existing configuration").option("-b, --brand <color>", "Brand color in hex format (e.g., #6366f1)").action(async (options) => {
|
|
105
182
|
await init(options);
|
|
106
183
|
});
|
|
107
184
|
}
|
|
@@ -120,7 +197,7 @@ async function init(options) {
|
|
|
120
197
|
if (options.force) args.push("--force");
|
|
121
198
|
try {
|
|
122
199
|
await spawnShadcn(args);
|
|
123
|
-
} catch
|
|
200
|
+
} catch {
|
|
124
201
|
console.log();
|
|
125
202
|
console.log(chalk.red("Failed to initialize shadcn-vue."));
|
|
126
203
|
console.log();
|
|
@@ -133,51 +210,33 @@ async function init(options) {
|
|
|
133
210
|
}
|
|
134
211
|
console.log();
|
|
135
212
|
}
|
|
136
|
-
let
|
|
137
|
-
if (
|
|
213
|
+
let brandColor = DEFAULT_BRAND_COLOR;
|
|
214
|
+
if (options.brand) {
|
|
215
|
+
if (isValidHex(options.brand)) {
|
|
216
|
+
brandColor = hexToOklch(options.brand);
|
|
217
|
+
console.log(chalk.dim(`Using brand color: ${options.brand} \u2192 ${brandColor}`));
|
|
218
|
+
} else {
|
|
219
|
+
console.log(chalk.yellow(`Invalid hex color: ${options.brand}, using default`));
|
|
220
|
+
}
|
|
221
|
+
} else if (!options.yes && !options.defaults) {
|
|
138
222
|
const response = await prompts([
|
|
139
223
|
{
|
|
140
|
-
type: "
|
|
141
|
-
name: "
|
|
142
|
-
message: "
|
|
143
|
-
initial:
|
|
224
|
+
type: "text",
|
|
225
|
+
name: "brand",
|
|
226
|
+
message: "Brand color (hex, e.g., #6366f1)",
|
|
227
|
+
initial: "#6366f1",
|
|
228
|
+
validate: (value) => {
|
|
229
|
+
if (!value) return true;
|
|
230
|
+
return isValidHex(value) || "Please enter a valid hex color (e.g., #6366f1)";
|
|
231
|
+
}
|
|
144
232
|
}
|
|
145
233
|
]);
|
|
146
|
-
if (response.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
type: "text",
|
|
150
|
-
name: "brand",
|
|
151
|
-
message: "Brand color (OKLCH)",
|
|
152
|
-
initial: themeColors.brand
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
type: "text",
|
|
156
|
-
name: "success",
|
|
157
|
-
message: "Success color (OKLCH)",
|
|
158
|
-
initial: themeColors.success
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
type: "text",
|
|
162
|
-
name: "warning",
|
|
163
|
-
message: "Warning color (OKLCH)",
|
|
164
|
-
initial: themeColors.warning
|
|
165
|
-
},
|
|
166
|
-
{
|
|
167
|
-
type: "text",
|
|
168
|
-
name: "info",
|
|
169
|
-
message: "Info color (OKLCH)",
|
|
170
|
-
initial: themeColors.info
|
|
171
|
-
}
|
|
172
|
-
]);
|
|
173
|
-
themeColors = {
|
|
174
|
-
brand: colorResponse.brand || themeColors.brand,
|
|
175
|
-
success: colorResponse.success || themeColors.success,
|
|
176
|
-
warning: colorResponse.warning || themeColors.warning,
|
|
177
|
-
info: colorResponse.info || themeColors.info
|
|
178
|
-
};
|
|
234
|
+
if (response.brand && isValidHex(response.brand)) {
|
|
235
|
+
brandColor = hexToOklch(response.brand);
|
|
236
|
+
console.log(chalk.dim(`Converted: ${response.brand} \u2192 ${brandColor}`));
|
|
179
237
|
}
|
|
180
238
|
}
|
|
239
|
+
const brandForeground = getForegroundColor(brandColor);
|
|
181
240
|
const spinner = ora("Configuring Frontic registry...").start();
|
|
182
241
|
try {
|
|
183
242
|
await updateConfig({
|
|
@@ -192,32 +251,31 @@ async function init(options) {
|
|
|
192
251
|
spinner.fail("Failed to configure registry");
|
|
193
252
|
throw error;
|
|
194
253
|
}
|
|
195
|
-
const themeSpinner = ora("Installing theme...").start();
|
|
254
|
+
const themeSpinner = ora("Installing Frontic theme...").start();
|
|
196
255
|
try {
|
|
197
|
-
await spawnShadcn(["add", "theme", "--yes"], { silent: true });
|
|
198
|
-
themeSpinner.succeed("
|
|
256
|
+
await spawnShadcn(["add", "@frontic/theme", "--yes"], { silent: true });
|
|
257
|
+
themeSpinner.succeed("Frontic theme installed");
|
|
199
258
|
} catch {
|
|
200
|
-
themeSpinner.warn("Theme installation skipped (may already exist)");
|
|
259
|
+
themeSpinner.warn("Theme installation skipped (may already exist or registry not available)");
|
|
201
260
|
}
|
|
202
261
|
console.log();
|
|
203
262
|
console.log(chalk.green("\u2713 Frontic UI initialized successfully!"));
|
|
204
263
|
console.log();
|
|
264
|
+
console.log(chalk.dim("Your brand color:"));
|
|
265
|
+
console.log(` --brand: ${chalk.cyan(brandColor)}`);
|
|
266
|
+
console.log(` --brand-foreground: ${chalk.cyan(brandForeground)}`);
|
|
267
|
+
console.log();
|
|
205
268
|
console.log("Next steps:");
|
|
206
269
|
console.log(chalk.dim(" 1. Add components:"));
|
|
207
270
|
console.log(` ${chalk.cyan("npx @frontic/ui add button")}`);
|
|
208
271
|
console.log();
|
|
209
|
-
console.log(chalk.dim(" 2.
|
|
272
|
+
console.log(chalk.dim(" 2. Customize your brand color in your CSS:"));
|
|
273
|
+
console.log(` ${chalk.cyan("--brand: " + brandColor + ";")}`);
|
|
274
|
+
console.log();
|
|
275
|
+
console.log(chalk.dim(" 3. Set up MCP for AI assistants (optional):"));
|
|
210
276
|
console.log(` ${chalk.cyan("npx @frontic/ui mcp init")}`);
|
|
211
277
|
console.log();
|
|
212
278
|
}
|
|
213
|
-
function getDefaultThemeColors() {
|
|
214
|
-
return {
|
|
215
|
-
brand: "oklch(58% 0.25 265)",
|
|
216
|
-
success: "oklch(55% 0.2 145)",
|
|
217
|
-
warning: "oklch(75% 0.18 85)",
|
|
218
|
-
info: "oklch(60% 0.2 230)"
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
279
|
|
|
222
280
|
// src/commands/add.ts
|
|
223
281
|
import chalk2 from "chalk";
|
|
@@ -373,7 +431,7 @@ function getMcpConfig() {
|
|
|
373
431
|
|
|
374
432
|
// src/index.ts
|
|
375
433
|
var program = new Command();
|
|
376
|
-
program.name("frontic-ui").description("CLI for adding Frontic UI components to your Vue project").version("0.0.
|
|
434
|
+
program.name("frontic-ui").description("CLI for adding Frontic UI components to your Vue project").version("0.0.5");
|
|
377
435
|
registerInitCommand(program);
|
|
378
436
|
registerAddCommand(program);
|
|
379
437
|
registerMcpCommand(program);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/commands/init.ts","../../src/utils/spawn-shadcn.ts","../../src/utils/config.ts","../../src/utils/constants.ts","../../src/commands/add.ts","../../src/commands/mcp.ts","../../bin/frontic-ui.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerMcpCommand } from \"./commands/mcp.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"frontic-ui\")\n .description(\"CLI for adding Frontic UI components to your Vue project\")\n .version(\"0.0.3\");\n\nregisterInitCommand(program);\nregisterAddCommand(program);\nregisterMcpCommand(program);\n\nexport function run() {\n program.parse();\n}\n\nexport { program };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { updateConfig, configExists } from \"../utils/config.js\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ninterface InitOptions {\n yes?: boolean;\n defaults?: boolean;\n force?: boolean;\n}\n\nexport function registerInitCommand(program: Command) {\n program\n .command(\"init\")\n .description(\"Initialize Frontic UI in your Vue project\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-d, --defaults\", \"Use default configuration\")\n .option(\"-f, --force\", \"Force overwrite of existing configuration\")\n .action(async (options: InitOptions) => {\n await init(options);\n });\n}\n\nasync function init(options: InitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI\"));\n console.log(chalk.dim(\"Initializing your project...\"));\n console.log();\n\n const hasConfig = await configExists();\n\n // Run shadcn-vue init if no config exists\n if (!hasConfig) {\n console.log(chalk.blue(\"Running shadcn-vue init...\"));\n console.log();\n\n const args = [\"init\"];\n if (options.yes) args.push(\"--yes\");\n if (options.defaults) args.push(\"--defaults\");\n if (options.force) args.push(\"--force\");\n\n try {\n await spawnShadcn(args);\n } catch (error) {\n console.log();\n console.log(chalk.red(\"Failed to initialize shadcn-vue.\"));\n console.log();\n console.log(chalk.yellow(\"Common issues:\"));\n console.log(chalk.dim(\" • Tailwind CSS not installed - run: npx nuxi module add @nuxtjs/tailwindcss\"));\n console.log(chalk.dim(\" • Not in a Vue/Nuxt project root directory\"));\n console.log(chalk.dim(\" • Existing components.json with invalid config - try: npx @frontic/ui init --force\"));\n console.log();\n process.exit(1);\n }\n console.log();\n }\n\n // Prompt for theme colors (unless skipped)\n let themeColors = getDefaultThemeColors();\n\n if (!options.yes && !options.defaults) {\n const response = await prompts([\n {\n type: \"confirm\",\n name: \"customizeColors\",\n message: \"Would you like to customize theme colors?\",\n initial: false,\n },\n ]);\n\n if (response.customizeColors) {\n const colorResponse = await prompts([\n {\n type: \"text\",\n name: \"brand\",\n message: \"Brand color (OKLCH)\",\n initial: themeColors.brand,\n },\n {\n type: \"text\",\n name: \"success\",\n message: \"Success color (OKLCH)\",\n initial: themeColors.success,\n },\n {\n type: \"text\",\n name: \"warning\",\n message: \"Warning color (OKLCH)\",\n initial: themeColors.warning,\n },\n {\n type: \"text\",\n name: \"info\",\n message: \"Info color (OKLCH)\",\n initial: themeColors.info,\n },\n ]);\n\n themeColors = {\n brand: colorResponse.brand || themeColors.brand,\n success: colorResponse.success || themeColors.success,\n warning: colorResponse.warning || themeColors.warning,\n info: colorResponse.info || themeColors.info,\n };\n }\n }\n\n // Update components.json with Frontic registry\n const spinner = ora(\"Configuring Frontic registry...\").start();\n\n try {\n await updateConfig({\n registries: {\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n spinner.succeed(\"Frontic registry configured\");\n } catch (error) {\n spinner.fail(\"Failed to configure registry\");\n throw error;\n }\n\n // Install theme\n const themeSpinner = ora(\"Installing theme...\").start();\n try {\n await spawnShadcn([\"add\", \"theme\", \"--yes\"], { silent: true });\n themeSpinner.succeed(\"Theme installed\");\n } catch {\n themeSpinner.warn(\"Theme installation skipped (may already exist)\");\n }\n\n console.log();\n console.log(chalk.green(\"✓ Frontic UI initialized successfully!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.dim(\" 1. Add components:\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log();\n console.log(chalk.dim(\" 2. Set up MCP for AI assistants (optional):\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui mcp init\")}`);\n console.log();\n}\n\nfunction getDefaultThemeColors() {\n return {\n brand: \"oklch(58% 0.25 265)\",\n success: \"oklch(55% 0.2 145)\",\n warning: \"oklch(75% 0.18 85)\",\n info: \"oklch(60% 0.2 230)\",\n };\n}\n","import { execa } from \"execa\";\n\ninterface SpawnOptions {\n silent?: boolean;\n}\n\nexport async function spawnShadcn(\n args: string[],\n options: SpawnOptions = {}\n): Promise<void> {\n const { silent = false } = options;\n\n try {\n await execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: silent ? \"pipe\" : \"inherit\",\n shell: true,\n });\n } catch (error) {\n if (!silent) {\n throw error;\n }\n // Silently ignore errors when silent mode is enabled\n }\n}\n","import { readFile, writeFile, access } from \"fs/promises\";\nimport { join } from \"path\";\nimport { CONFIG_FILE, FRONTIC_REGISTRY_URL } from \"./constants.js\";\n\nexport interface ComponentsConfig {\n $schema?: string;\n style?: string;\n typescript?: boolean;\n tailwind?: {\n css?: string;\n baseColor?: string;\n cssVariables?: boolean;\n };\n aliases?: {\n components?: string;\n utils?: string;\n ui?: string;\n lib?: string;\n composables?: string;\n };\n registries?: {\n [key: string]: {\n url: string;\n };\n };\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await access(join(process.cwd(), CONFIG_FILE));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readConfig(): Promise<ComponentsConfig | null> {\n try {\n const content = await readFile(join(process.cwd(), CONFIG_FILE), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function writeConfig(config: ComponentsConfig): Promise<void> {\n await writeFile(\n join(process.cwd(), CONFIG_FILE),\n JSON.stringify(config, null, 2)\n );\n}\n\nexport async function updateConfig(\n updates: Partial<ComponentsConfig>\n): Promise<void> {\n const existing = await readConfig();\n\n if (!existing) {\n throw new Error(\n \"components.json not found. Run `npx @frontic/ui init` first.\"\n );\n }\n\n const merged = deepMerge(existing, updates);\n await writeConfig(merged);\n}\n\nexport async function ensureFronticRegistry(): Promise<void> {\n const config = await readConfig();\n\n if (!config) {\n throw new Error(\"components.json not found\");\n }\n\n // Check if Frontic registry is already configured\n if (config.registries?.[\"@frontic\"]?.url === FRONTIC_REGISTRY_URL) {\n return;\n }\n\n // Add Frontic registry\n await updateConfig({\n registries: {\n ...config.registries,\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n}\n\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === \"object\" &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return result;\n}\n","export const FRONTIC_REGISTRY_URL = \"https://registry.frontic.io/r/{name}.json\";\n\nexport const CONFIG_FILE = \"components.json\";\n\nexport const DEFAULT_THEME_COLORS = {\n brand: \"oklch(58% 0.25 265)\",\n \"brand-foreground\": \"oklch(100% 0 0)\",\n success: \"oklch(55% 0.2 145)\",\n \"success-foreground\": \"oklch(100% 0 0)\",\n warning: \"oklch(75% 0.18 85)\",\n \"warning-foreground\": \"oklch(20% 0 0)\",\n info: \"oklch(60% 0.2 230)\",\n \"info-foreground\": \"oklch(100% 0 0)\",\n};\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { ensureFronticRegistry } from \"../utils/config.js\";\n\ninterface AddOptions {\n overwrite?: boolean;\n all?: boolean;\n path?: string;\n yes?: boolean;\n}\n\nexport function registerAddCommand(program: Command) {\n program\n .command(\"add\")\n .description(\"Add components to your project\")\n .argument(\"[components...]\", \"Components to add\")\n .option(\"-o, --overwrite\", \"Overwrite existing files\")\n .option(\"-a, --all\", \"Add all available components\")\n .option(\"-p, --path <path>\", \"Custom installation path\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .action(async (components: string[], options: AddOptions) => {\n await add(components, options);\n });\n}\n\nasync function add(components: string[], options: AddOptions) {\n // Validate input\n if (!options.all && components.length === 0) {\n console.log(chalk.red(\"Error: Please specify components to add or use --all\"));\n console.log();\n console.log(\"Usage:\");\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button dialog card\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add --all\")}`);\n process.exit(1);\n }\n\n // Ensure Frontic registry is configured\n const spinner = ora(\"Checking configuration...\").start();\n try {\n await ensureFronticRegistry();\n spinner.succeed(\"Configuration verified\");\n } catch {\n spinner.fail(\"Configuration error\");\n console.log();\n console.log(chalk.yellow(\"Run `npx @frontic/ui init` first to set up your project.\"));\n process.exit(1);\n }\n\n // Build shadcn-vue arguments\n const args = [\"add\"];\n\n if (options.all) {\n args.push(\"--all\");\n } else {\n args.push(...components);\n }\n\n if (options.overwrite) {\n args.push(\"--overwrite\");\n }\n\n if (options.path) {\n args.push(\"--path\", options.path);\n }\n\n if (options.yes) {\n args.push(\"--yes\");\n }\n\n console.log();\n console.log(chalk.blue(\"Adding components...\"));\n console.log();\n\n // Run shadcn-vue add\n await spawnShadcn(args);\n\n console.log();\n console.log(chalk.green(\"✓ Components added successfully!\"));\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { writeFile, readFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport prompts from \"prompts\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ntype McpClient = \"claude\" | \"cursor\" | \"vscode\";\n\ninterface McpInitOptions {\n client?: McpClient;\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program\n .command(\"mcp\")\n .description(\"MCP (Model Context Protocol) commands\");\n\n mcp\n .command(\"init\")\n .description(\"Set up MCP for AI assistants\")\n .option(\"-c, --client <client>\", \"Target client (claude, cursor, vscode)\")\n .action(async (options: McpInitOptions) => {\n await initMcp(options);\n });\n}\n\nasync function initMcp(options: McpInitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI - MCP Setup\"));\n console.log(chalk.dim(\"Configure AI assistant integration\"));\n console.log();\n\n let client = options.client as McpClient | undefined;\n\n // Prompt for client if not specified\n if (!client) {\n const response = await prompts({\n type: \"select\",\n name: \"client\",\n message: \"Select your AI client:\",\n choices: [\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Cursor\", value: \"cursor\" },\n { title: \"VS Code\", value: \"vscode\" },\n ],\n });\n\n client = response.client;\n\n if (!client) {\n console.log(chalk.yellow(\"Setup cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Creating MCP configuration...\").start();\n\n try {\n await createMcpConfig(client);\n spinner.succeed(\"MCP configuration created\");\n } catch (error) {\n spinner.fail(\"Failed to create MCP configuration\");\n throw error;\n }\n\n console.log();\n console.log(chalk.green(\"✓ MCP configured successfully!\"));\n console.log();\n console.log(\"Your AI assistant can now:\");\n console.log(chalk.dim(\" • Browse available Frontic UI components\"));\n console.log(chalk.dim(\" • Add components using natural language\"));\n console.log(chalk.dim(' • Example: \"Add a button component\"'));\n console.log();\n}\n\nasync function createMcpConfig(client: McpClient) {\n const config = getMcpConfig();\n const configPath = getMcpConfigPath(client);\n const configDir = join(process.cwd(), configPath.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create directory if needed\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n const fullPath = join(process.cwd(), configPath);\n\n // Read existing config or create new\n let existingConfig: Record<string, unknown> = {};\n try {\n const content = await readFile(fullPath, \"utf-8\");\n existingConfig = JSON.parse(content);\n } catch {\n // File doesn't exist, use empty config\n }\n\n // Merge with existing config\n const mergedConfig = {\n ...existingConfig,\n mcpServers: {\n ...(existingConfig.mcpServers as Record<string, unknown> || {}),\n ...config.mcpServers,\n },\n };\n\n await writeFile(fullPath, JSON.stringify(mergedConfig, null, 2));\n\n console.log(chalk.dim(` Config written to: ${configPath}`));\n}\n\nfunction getMcpConfigPath(client: McpClient): string {\n switch (client) {\n case \"claude\":\n return \".mcp.json\";\n case \"cursor\":\n return \".cursor/mcp.json\";\n case \"vscode\":\n return \".vscode/mcp.json\";\n }\n}\n\nfunction getMcpConfig() {\n return {\n mcpServers: {\n \"frontic-ui\": {\n command: \"npx\",\n args: [\"shadcn-vue@latest\", \"mcp\"],\n env: {\n SHADCN_REGISTRY_URL: FRONTIC_REGISTRY_URL,\n },\n },\n },\n };\n}\n","#!/usr/bin/env node\nimport { run } from '../src/index.js'\n\nrun()\n"],"mappings":"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","names":["program","chalk","ora","program","chalk","ora","chalk","ora","writeFile","readFile","join","prompts","program","chalk","prompts","ora","join","readFile","writeFile"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/commands/init.ts","../../src/utils/spawn-shadcn.ts","../../src/utils/config.ts","../../src/utils/constants.ts","../../src/utils/colors.ts","../../src/commands/add.ts","../../src/commands/mcp.ts","../../bin/frontic-ui.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerMcpCommand } from \"./commands/mcp.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"frontic-ui\")\n .description(\"CLI for adding Frontic UI components to your Vue project\")\n .version(\"0.0.5\");\n\nregisterInitCommand(program);\nregisterAddCommand(program);\nregisterMcpCommand(program);\n\nexport function run() {\n program.parse();\n}\n\nexport { program };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { updateConfig, configExists } from \"../utils/config.js\";\nimport { FRONTIC_REGISTRY_URL, DEFAULT_BRAND_COLOR } from \"../utils/constants.js\";\nimport { hexToOklch, isValidHex, getForegroundColor } from \"../utils/colors.js\";\n\ninterface InitOptions {\n yes?: boolean;\n defaults?: boolean;\n force?: boolean;\n brand?: string;\n}\n\nexport function registerInitCommand(program: Command) {\n program\n .command(\"init\")\n .description(\"Initialize Frontic UI in your Vue project\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-d, --defaults\", \"Use default configuration\")\n .option(\"-f, --force\", \"Force overwrite of existing configuration\")\n .option(\"-b, --brand <color>\", \"Brand color in hex format (e.g., #6366f1)\")\n .action(async (options: InitOptions) => {\n await init(options);\n });\n}\n\nasync function init(options: InitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI\"));\n console.log(chalk.dim(\"Initializing your project...\"));\n console.log();\n\n const hasConfig = await configExists();\n\n // Run shadcn-vue init if no config exists\n if (!hasConfig) {\n console.log(chalk.blue(\"Running shadcn-vue init...\"));\n console.log();\n\n const args = [\"init\"];\n if (options.yes) args.push(\"--yes\");\n if (options.defaults) args.push(\"--defaults\");\n if (options.force) args.push(\"--force\");\n\n try {\n await spawnShadcn(args);\n } catch {\n console.log();\n console.log(chalk.red(\"Failed to initialize shadcn-vue.\"));\n console.log();\n console.log(chalk.yellow(\"Common issues:\"));\n console.log(chalk.dim(\" • Tailwind CSS not installed - run: npx nuxi module add @nuxtjs/tailwindcss\"));\n console.log(chalk.dim(\" • Not in a Vue/Nuxt project root directory\"));\n console.log(chalk.dim(\" • Existing components.json with invalid config - try: npx @frontic/ui init --force\"));\n console.log();\n process.exit(1);\n }\n console.log();\n }\n\n // Get brand color\n let brandColor = DEFAULT_BRAND_COLOR;\n\n // Check if brand was provided via CLI flag\n if (options.brand) {\n if (isValidHex(options.brand)) {\n brandColor = hexToOklch(options.brand);\n console.log(chalk.dim(`Using brand color: ${options.brand} → ${brandColor}`));\n } else {\n console.log(chalk.yellow(`Invalid hex color: ${options.brand}, using default`));\n }\n } else if (!options.yes && !options.defaults) {\n // Prompt for brand color\n const response = await prompts([\n {\n type: \"text\",\n name: \"brand\",\n message: \"Brand color (hex, e.g., #6366f1)\",\n initial: \"#6366f1\",\n validate: (value: string) => {\n if (!value) return true; // Allow empty to use default\n return isValidHex(value) || \"Please enter a valid hex color (e.g., #6366f1)\";\n },\n },\n ]);\n\n if (response.brand && isValidHex(response.brand)) {\n brandColor = hexToOklch(response.brand);\n console.log(chalk.dim(`Converted: ${response.brand} → ${brandColor}`));\n }\n }\n\n // Calculate foreground color based on brand\n const brandForeground = getForegroundColor(brandColor);\n\n // Update components.json with Frontic registry\n const spinner = ora(\"Configuring Frontic registry...\").start();\n\n try {\n await updateConfig({\n registries: {\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n spinner.succeed(\"Frontic registry configured\");\n } catch (error) {\n spinner.fail(\"Failed to configure registry\");\n throw error;\n }\n\n // Install Frontic theme from registry\n const themeSpinner = ora(\"Installing Frontic theme...\").start();\n try {\n await spawnShadcn([\"add\", \"@frontic/theme\", \"--yes\"], { silent: true });\n themeSpinner.succeed(\"Frontic theme installed\");\n } catch {\n themeSpinner.warn(\"Theme installation skipped (may already exist or registry not available)\");\n }\n\n // TODO: In future, inject brand color into user's CSS\n // For now, we log it so users know what to set\n console.log();\n console.log(chalk.green(\"✓ Frontic UI initialized successfully!\"));\n console.log();\n console.log(chalk.dim(\"Your brand color:\"));\n console.log(` --brand: ${chalk.cyan(brandColor)}`);\n console.log(` --brand-foreground: ${chalk.cyan(brandForeground)}`);\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.dim(\" 1. Add components:\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log();\n console.log(chalk.dim(\" 2. Customize your brand color in your CSS:\"));\n console.log(` ${chalk.cyan(\"--brand: \" + brandColor + \";\")}`);\n console.log();\n console.log(chalk.dim(\" 3. Set up MCP for AI assistants (optional):\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui mcp init\")}`);\n console.log();\n}\n","import { execa } from \"execa\";\n\ninterface SpawnOptions {\n silent?: boolean;\n}\n\nexport async function spawnShadcn(\n args: string[],\n options: SpawnOptions = {}\n): Promise<void> {\n const { silent = false } = options;\n\n try {\n await execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: silent ? \"pipe\" : \"inherit\",\n shell: true,\n });\n } catch (error) {\n if (!silent) {\n throw error;\n }\n // Silently ignore errors when silent mode is enabled\n }\n}\n","import { readFile, writeFile, access } from \"fs/promises\";\nimport { join } from \"path\";\nimport { CONFIG_FILE, FRONTIC_REGISTRY_URL } from \"./constants.js\";\n\nexport interface ComponentsConfig {\n $schema?: string;\n style?: string;\n typescript?: boolean;\n tailwind?: {\n css?: string;\n baseColor?: string;\n cssVariables?: boolean;\n };\n aliases?: {\n components?: string;\n utils?: string;\n ui?: string;\n lib?: string;\n composables?: string;\n };\n registries?: {\n [key: string]: {\n url: string;\n };\n };\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await access(join(process.cwd(), CONFIG_FILE));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readConfig(): Promise<ComponentsConfig | null> {\n try {\n const content = await readFile(join(process.cwd(), CONFIG_FILE), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function writeConfig(config: ComponentsConfig): Promise<void> {\n await writeFile(\n join(process.cwd(), CONFIG_FILE),\n JSON.stringify(config, null, 2)\n );\n}\n\nexport async function updateConfig(\n updates: Partial<ComponentsConfig>\n): Promise<void> {\n const existing = await readConfig();\n\n if (!existing) {\n throw new Error(\n \"components.json not found. Run `npx @frontic/ui init` first.\"\n );\n }\n\n const merged = deepMerge(existing, updates);\n await writeConfig(merged);\n}\n\nexport async function ensureFronticRegistry(): Promise<void> {\n const config = await readConfig();\n\n if (!config) {\n throw new Error(\"components.json not found\");\n }\n\n // Check if Frontic registry is already configured\n if (config.registries?.[\"@frontic\"]?.url === FRONTIC_REGISTRY_URL) {\n return;\n }\n\n // Add Frontic registry\n await updateConfig({\n registries: {\n ...config.registries,\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n}\n\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === \"object\" &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return result;\n}\n","export const FRONTIC_REGISTRY_URL = \"https://registry.frontic.io/r/{name}.json\";\n\nexport const CONFIG_FILE = \"components.json\";\n\n// Default brand color (purple - similar to Indigo 500)\nexport const DEFAULT_BRAND_COLOR = \"oklch(58% 0.25 265)\";\n","/**\n * 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 { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { ensureFronticRegistry } from \"../utils/config.js\";\n\ninterface AddOptions {\n overwrite?: boolean;\n all?: boolean;\n path?: string;\n yes?: boolean;\n}\n\nexport function registerAddCommand(program: Command) {\n program\n .command(\"add\")\n .description(\"Add components to your project\")\n .argument(\"[components...]\", \"Components to add\")\n .option(\"-o, --overwrite\", \"Overwrite existing files\")\n .option(\"-a, --all\", \"Add all available components\")\n .option(\"-p, --path <path>\", \"Custom installation path\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .action(async (components: string[], options: AddOptions) => {\n await add(components, options);\n });\n}\n\nasync function add(components: string[], options: AddOptions) {\n // Validate input\n if (!options.all && components.length === 0) {\n console.log(chalk.red(\"Error: Please specify components to add or use --all\"));\n console.log();\n console.log(\"Usage:\");\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button dialog card\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add --all\")}`);\n process.exit(1);\n }\n\n // Ensure Frontic registry is configured\n const spinner = ora(\"Checking configuration...\").start();\n try {\n await ensureFronticRegistry();\n spinner.succeed(\"Configuration verified\");\n } catch {\n spinner.fail(\"Configuration error\");\n console.log();\n console.log(chalk.yellow(\"Run `npx @frontic/ui init` first to set up your project.\"));\n process.exit(1);\n }\n\n // Build shadcn-vue arguments\n const args = [\"add\"];\n\n if (options.all) {\n args.push(\"--all\");\n } else {\n args.push(...components);\n }\n\n if (options.overwrite) {\n args.push(\"--overwrite\");\n }\n\n if (options.path) {\n args.push(\"--path\", options.path);\n }\n\n if (options.yes) {\n args.push(\"--yes\");\n }\n\n console.log();\n console.log(chalk.blue(\"Adding components...\"));\n console.log();\n\n // Run shadcn-vue add\n await spawnShadcn(args);\n\n console.log();\n console.log(chalk.green(\"✓ Components added successfully!\"));\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { writeFile, readFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport prompts from \"prompts\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ntype McpClient = \"claude\" | \"cursor\" | \"vscode\";\n\ninterface McpInitOptions {\n client?: McpClient;\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program\n .command(\"mcp\")\n .description(\"MCP (Model Context Protocol) commands\");\n\n mcp\n .command(\"init\")\n .description(\"Set up MCP for AI assistants\")\n .option(\"-c, --client <client>\", \"Target client (claude, cursor, vscode)\")\n .action(async (options: McpInitOptions) => {\n await initMcp(options);\n });\n}\n\nasync function initMcp(options: McpInitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI - MCP Setup\"));\n console.log(chalk.dim(\"Configure AI assistant integration\"));\n console.log();\n\n let client = options.client as McpClient | undefined;\n\n // Prompt for client if not specified\n if (!client) {\n const response = await prompts({\n type: \"select\",\n name: \"client\",\n message: \"Select your AI client:\",\n choices: [\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Cursor\", value: \"cursor\" },\n { title: \"VS Code\", value: \"vscode\" },\n ],\n });\n\n client = response.client;\n\n if (!client) {\n console.log(chalk.yellow(\"Setup cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Creating MCP configuration...\").start();\n\n try {\n await createMcpConfig(client);\n spinner.succeed(\"MCP configuration created\");\n } catch (error) {\n spinner.fail(\"Failed to create MCP configuration\");\n throw error;\n }\n\n console.log();\n console.log(chalk.green(\"✓ MCP configured successfully!\"));\n console.log();\n console.log(\"Your AI assistant can now:\");\n console.log(chalk.dim(\" • Browse available Frontic UI components\"));\n console.log(chalk.dim(\" • Add components using natural language\"));\n console.log(chalk.dim(' • Example: \"Add a button component\"'));\n console.log();\n}\n\nasync function createMcpConfig(client: McpClient) {\n const config = getMcpConfig();\n const configPath = getMcpConfigPath(client);\n const configDir = join(process.cwd(), configPath.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create directory if needed\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n const fullPath = join(process.cwd(), configPath);\n\n // Read existing config or create new\n let existingConfig: Record<string, unknown> = {};\n try {\n const content = await readFile(fullPath, \"utf-8\");\n existingConfig = JSON.parse(content);\n } catch {\n // File doesn't exist, use empty config\n }\n\n // Merge with existing config\n const mergedConfig = {\n ...existingConfig,\n mcpServers: {\n ...(existingConfig.mcpServers as Record<string, unknown> || {}),\n ...config.mcpServers,\n },\n };\n\n await writeFile(fullPath, JSON.stringify(mergedConfig, null, 2));\n\n console.log(chalk.dim(` Config written to: ${configPath}`));\n}\n\nfunction getMcpConfigPath(client: McpClient): string {\n switch (client) {\n case \"claude\":\n return \".mcp.json\";\n case \"cursor\":\n return \".cursor/mcp.json\";\n case \"vscode\":\n return \".vscode/mcp.json\";\n }\n}\n\nfunction getMcpConfig() {\n return {\n mcpServers: {\n \"frontic-ui\": {\n command: \"npx\",\n args: [\"shadcn-vue@latest\", \"mcp\"],\n env: {\n SHADCN_REGISTRY_URL: FRONTIC_REGISTRY_URL,\n },\n },\n },\n };\n}\n","#!/usr/bin/env node\nimport { run } from '../src/index.js'\n\nrun()\n"],"mappings":"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","names":["program","chalk","ora","program","chalk","ora","chalk","ora","writeFile","readFile","join","prompts","program","chalk","prompts","ora","join","readFile","writeFile"]}
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import { join } from "path";
|
|
|
29
29
|
// src/utils/constants.ts
|
|
30
30
|
var FRONTIC_REGISTRY_URL = "https://registry.frontic.io/r/{name}.json";
|
|
31
31
|
var CONFIG_FILE = "components.json";
|
|
32
|
+
var DEFAULT_BRAND_COLOR = "oklch(58% 0.25 265)";
|
|
32
33
|
|
|
33
34
|
// src/utils/config.ts
|
|
34
35
|
async function configExists() {
|
|
@@ -97,9 +98,85 @@ function deepMerge(target, source) {
|
|
|
97
98
|
return result;
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
// src/utils/colors.ts
|
|
102
|
+
function isValidHex(hex) {
|
|
103
|
+
const cleanHex = hex.replace(/^#/, "");
|
|
104
|
+
return /^([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/.test(cleanHex);
|
|
105
|
+
}
|
|
106
|
+
function normalizeHex(hex) {
|
|
107
|
+
const cleanHex = hex.replace(/^#/, "");
|
|
108
|
+
if (cleanHex.length === 3) {
|
|
109
|
+
return cleanHex.split("").map((c) => c + c).join("");
|
|
110
|
+
}
|
|
111
|
+
return cleanHex;
|
|
112
|
+
}
|
|
113
|
+
function hexToRgb(hex) {
|
|
114
|
+
const normalizedHex = normalizeHex(hex);
|
|
115
|
+
return {
|
|
116
|
+
r: parseInt(normalizedHex.slice(0, 2), 16),
|
|
117
|
+
g: parseInt(normalizedHex.slice(2, 4), 16),
|
|
118
|
+
b: parseInt(normalizedHex.slice(4, 6), 16)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function srgbToLinear(value) {
|
|
122
|
+
const normalized = value / 255;
|
|
123
|
+
return normalized <= 0.04045 ? normalized / 12.92 : Math.pow((normalized + 0.055) / 1.055, 2.4);
|
|
124
|
+
}
|
|
125
|
+
function linearRgbToXyz(r, g, b) {
|
|
126
|
+
return {
|
|
127
|
+
x: 0.4124564 * r + 0.3575761 * g + 0.1804375 * b,
|
|
128
|
+
y: 0.2126729 * r + 0.7151522 * g + 0.072175 * b,
|
|
129
|
+
z: 0.0193339 * r + 0.119192 * g + 0.9503041 * b
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function xyzToOklab(x, y, z) {
|
|
133
|
+
const l_ = Math.cbrt(0.8189330101 * x + 0.3618667424 * y - 0.1288597137 * z);
|
|
134
|
+
const m_ = Math.cbrt(0.0329845436 * x + 0.9293118715 * y + 0.0361456387 * z);
|
|
135
|
+
const s_ = Math.cbrt(-0.0482003018 * x + 0.2643662691 * y + 0.633851707 * z);
|
|
136
|
+
return {
|
|
137
|
+
l: 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_,
|
|
138
|
+
a: 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_,
|
|
139
|
+
b: 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function oklabToOklch(l, a, b) {
|
|
143
|
+
const c = Math.sqrt(a * a + b * b);
|
|
144
|
+
let h = Math.atan2(b, a) * (180 / Math.PI);
|
|
145
|
+
if (h < 0) h += 360;
|
|
146
|
+
return { l, c, h };
|
|
147
|
+
}
|
|
148
|
+
function hexToOklch(hex) {
|
|
149
|
+
if (!isValidHex(hex)) {
|
|
150
|
+
throw new Error(`Invalid hex color: ${hex}`);
|
|
151
|
+
}
|
|
152
|
+
const { r, g, b } = hexToRgb(hex);
|
|
153
|
+
const linearR = srgbToLinear(r);
|
|
154
|
+
const linearG = srgbToLinear(g);
|
|
155
|
+
const linearB = srgbToLinear(b);
|
|
156
|
+
const { x, y, z } = linearRgbToXyz(linearR, linearG, linearB);
|
|
157
|
+
const oklab = xyzToOklab(x, y, z);
|
|
158
|
+
const { l, c, h } = oklabToOklch(oklab.l, oklab.a, oklab.b);
|
|
159
|
+
const lightness = Math.round(l * 100);
|
|
160
|
+
const chroma = Math.round(c * 100) / 100;
|
|
161
|
+
const hue = Math.round(h);
|
|
162
|
+
return `oklch(${lightness}% ${chroma} ${hue})`;
|
|
163
|
+
}
|
|
164
|
+
function getForegroundColor(oklchOrHex) {
|
|
165
|
+
let lightness;
|
|
166
|
+
if (oklchOrHex.startsWith("oklch")) {
|
|
167
|
+
const match = oklchOrHex.match(/oklch\((\d+)%/);
|
|
168
|
+
lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;
|
|
169
|
+
} else {
|
|
170
|
+
const oklch = hexToOklch(oklchOrHex);
|
|
171
|
+
const match = oklch.match(/oklch\((\d+)%/);
|
|
172
|
+
lightness = match?.[1] ? parseInt(match[1], 10) / 100 : 0.5;
|
|
173
|
+
}
|
|
174
|
+
return lightness > 0.6 ? "oklch(20% 0 0)" : "oklch(100% 0 0)";
|
|
175
|
+
}
|
|
176
|
+
|
|
100
177
|
// src/commands/init.ts
|
|
101
178
|
function registerInitCommand(program2) {
|
|
102
|
-
program2.command("init").description("Initialize Frontic UI in your Vue project").option("-y, --yes", "Skip confirmation prompts").option("-d, --defaults", "Use default configuration").option("-f, --force", "Force overwrite of existing configuration").action(async (options) => {
|
|
179
|
+
program2.command("init").description("Initialize Frontic UI in your Vue project").option("-y, --yes", "Skip confirmation prompts").option("-d, --defaults", "Use default configuration").option("-f, --force", "Force overwrite of existing configuration").option("-b, --brand <color>", "Brand color in hex format (e.g., #6366f1)").action(async (options) => {
|
|
103
180
|
await init(options);
|
|
104
181
|
});
|
|
105
182
|
}
|
|
@@ -118,7 +195,7 @@ async function init(options) {
|
|
|
118
195
|
if (options.force) args.push("--force");
|
|
119
196
|
try {
|
|
120
197
|
await spawnShadcn(args);
|
|
121
|
-
} catch
|
|
198
|
+
} catch {
|
|
122
199
|
console.log();
|
|
123
200
|
console.log(chalk.red("Failed to initialize shadcn-vue."));
|
|
124
201
|
console.log();
|
|
@@ -131,51 +208,33 @@ async function init(options) {
|
|
|
131
208
|
}
|
|
132
209
|
console.log();
|
|
133
210
|
}
|
|
134
|
-
let
|
|
135
|
-
if (
|
|
211
|
+
let brandColor = DEFAULT_BRAND_COLOR;
|
|
212
|
+
if (options.brand) {
|
|
213
|
+
if (isValidHex(options.brand)) {
|
|
214
|
+
brandColor = hexToOklch(options.brand);
|
|
215
|
+
console.log(chalk.dim(`Using brand color: ${options.brand} \u2192 ${brandColor}`));
|
|
216
|
+
} else {
|
|
217
|
+
console.log(chalk.yellow(`Invalid hex color: ${options.brand}, using default`));
|
|
218
|
+
}
|
|
219
|
+
} else if (!options.yes && !options.defaults) {
|
|
136
220
|
const response = await prompts([
|
|
137
221
|
{
|
|
138
|
-
type: "
|
|
139
|
-
name: "
|
|
140
|
-
message: "
|
|
141
|
-
initial:
|
|
222
|
+
type: "text",
|
|
223
|
+
name: "brand",
|
|
224
|
+
message: "Brand color (hex, e.g., #6366f1)",
|
|
225
|
+
initial: "#6366f1",
|
|
226
|
+
validate: (value) => {
|
|
227
|
+
if (!value) return true;
|
|
228
|
+
return isValidHex(value) || "Please enter a valid hex color (e.g., #6366f1)";
|
|
229
|
+
}
|
|
142
230
|
}
|
|
143
231
|
]);
|
|
144
|
-
if (response.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
type: "text",
|
|
148
|
-
name: "brand",
|
|
149
|
-
message: "Brand color (OKLCH)",
|
|
150
|
-
initial: themeColors.brand
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
type: "text",
|
|
154
|
-
name: "success",
|
|
155
|
-
message: "Success color (OKLCH)",
|
|
156
|
-
initial: themeColors.success
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
type: "text",
|
|
160
|
-
name: "warning",
|
|
161
|
-
message: "Warning color (OKLCH)",
|
|
162
|
-
initial: themeColors.warning
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
type: "text",
|
|
166
|
-
name: "info",
|
|
167
|
-
message: "Info color (OKLCH)",
|
|
168
|
-
initial: themeColors.info
|
|
169
|
-
}
|
|
170
|
-
]);
|
|
171
|
-
themeColors = {
|
|
172
|
-
brand: colorResponse.brand || themeColors.brand,
|
|
173
|
-
success: colorResponse.success || themeColors.success,
|
|
174
|
-
warning: colorResponse.warning || themeColors.warning,
|
|
175
|
-
info: colorResponse.info || themeColors.info
|
|
176
|
-
};
|
|
232
|
+
if (response.brand && isValidHex(response.brand)) {
|
|
233
|
+
brandColor = hexToOklch(response.brand);
|
|
234
|
+
console.log(chalk.dim(`Converted: ${response.brand} \u2192 ${brandColor}`));
|
|
177
235
|
}
|
|
178
236
|
}
|
|
237
|
+
const brandForeground = getForegroundColor(brandColor);
|
|
179
238
|
const spinner = ora("Configuring Frontic registry...").start();
|
|
180
239
|
try {
|
|
181
240
|
await updateConfig({
|
|
@@ -190,32 +249,31 @@ async function init(options) {
|
|
|
190
249
|
spinner.fail("Failed to configure registry");
|
|
191
250
|
throw error;
|
|
192
251
|
}
|
|
193
|
-
const themeSpinner = ora("Installing theme...").start();
|
|
252
|
+
const themeSpinner = ora("Installing Frontic theme...").start();
|
|
194
253
|
try {
|
|
195
|
-
await spawnShadcn(["add", "theme", "--yes"], { silent: true });
|
|
196
|
-
themeSpinner.succeed("
|
|
254
|
+
await spawnShadcn(["add", "@frontic/theme", "--yes"], { silent: true });
|
|
255
|
+
themeSpinner.succeed("Frontic theme installed");
|
|
197
256
|
} catch {
|
|
198
|
-
themeSpinner.warn("Theme installation skipped (may already exist)");
|
|
257
|
+
themeSpinner.warn("Theme installation skipped (may already exist or registry not available)");
|
|
199
258
|
}
|
|
200
259
|
console.log();
|
|
201
260
|
console.log(chalk.green("\u2713 Frontic UI initialized successfully!"));
|
|
202
261
|
console.log();
|
|
262
|
+
console.log(chalk.dim("Your brand color:"));
|
|
263
|
+
console.log(` --brand: ${chalk.cyan(brandColor)}`);
|
|
264
|
+
console.log(` --brand-foreground: ${chalk.cyan(brandForeground)}`);
|
|
265
|
+
console.log();
|
|
203
266
|
console.log("Next steps:");
|
|
204
267
|
console.log(chalk.dim(" 1. Add components:"));
|
|
205
268
|
console.log(` ${chalk.cyan("npx @frontic/ui add button")}`);
|
|
206
269
|
console.log();
|
|
207
|
-
console.log(chalk.dim(" 2.
|
|
270
|
+
console.log(chalk.dim(" 2. Customize your brand color in your CSS:"));
|
|
271
|
+
console.log(` ${chalk.cyan("--brand: " + brandColor + ";")}`);
|
|
272
|
+
console.log();
|
|
273
|
+
console.log(chalk.dim(" 3. Set up MCP for AI assistants (optional):"));
|
|
208
274
|
console.log(` ${chalk.cyan("npx @frontic/ui mcp init")}`);
|
|
209
275
|
console.log();
|
|
210
276
|
}
|
|
211
|
-
function getDefaultThemeColors() {
|
|
212
|
-
return {
|
|
213
|
-
brand: "oklch(58% 0.25 265)",
|
|
214
|
-
success: "oklch(55% 0.2 145)",
|
|
215
|
-
warning: "oklch(75% 0.18 85)",
|
|
216
|
-
info: "oklch(60% 0.2 230)"
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
277
|
|
|
220
278
|
// src/commands/add.ts
|
|
221
279
|
import chalk2 from "chalk";
|
|
@@ -371,7 +429,7 @@ function getMcpConfig() {
|
|
|
371
429
|
|
|
372
430
|
// src/index.ts
|
|
373
431
|
var program = new Command();
|
|
374
|
-
program.name("frontic-ui").description("CLI for adding Frontic UI components to your Vue project").version("0.0.
|
|
432
|
+
program.name("frontic-ui").description("CLI for adding Frontic UI components to your Vue project").version("0.0.5");
|
|
375
433
|
registerInitCommand(program);
|
|
376
434
|
registerAddCommand(program);
|
|
377
435
|
registerMcpCommand(program);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/spawn-shadcn.ts","../src/utils/config.ts","../src/utils/constants.ts","../src/commands/add.ts","../src/commands/mcp.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerMcpCommand } from \"./commands/mcp.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"frontic-ui\")\n .description(\"CLI for adding Frontic UI components to your Vue project\")\n .version(\"0.0.3\");\n\nregisterInitCommand(program);\nregisterAddCommand(program);\nregisterMcpCommand(program);\n\nexport function run() {\n program.parse();\n}\n\nexport { program };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { updateConfig, configExists } from \"../utils/config.js\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ninterface InitOptions {\n yes?: boolean;\n defaults?: boolean;\n force?: boolean;\n}\n\nexport function registerInitCommand(program: Command) {\n program\n .command(\"init\")\n .description(\"Initialize Frontic UI in your Vue project\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-d, --defaults\", \"Use default configuration\")\n .option(\"-f, --force\", \"Force overwrite of existing configuration\")\n .action(async (options: InitOptions) => {\n await init(options);\n });\n}\n\nasync function init(options: InitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI\"));\n console.log(chalk.dim(\"Initializing your project...\"));\n console.log();\n\n const hasConfig = await configExists();\n\n // Run shadcn-vue init if no config exists\n if (!hasConfig) {\n console.log(chalk.blue(\"Running shadcn-vue init...\"));\n console.log();\n\n const args = [\"init\"];\n if (options.yes) args.push(\"--yes\");\n if (options.defaults) args.push(\"--defaults\");\n if (options.force) args.push(\"--force\");\n\n try {\n await spawnShadcn(args);\n } catch (error) {\n console.log();\n console.log(chalk.red(\"Failed to initialize shadcn-vue.\"));\n console.log();\n console.log(chalk.yellow(\"Common issues:\"));\n console.log(chalk.dim(\" • Tailwind CSS not installed - run: npx nuxi module add @nuxtjs/tailwindcss\"));\n console.log(chalk.dim(\" • Not in a Vue/Nuxt project root directory\"));\n console.log(chalk.dim(\" • Existing components.json with invalid config - try: npx @frontic/ui init --force\"));\n console.log();\n process.exit(1);\n }\n console.log();\n }\n\n // Prompt for theme colors (unless skipped)\n let themeColors = getDefaultThemeColors();\n\n if (!options.yes && !options.defaults) {\n const response = await prompts([\n {\n type: \"confirm\",\n name: \"customizeColors\",\n message: \"Would you like to customize theme colors?\",\n initial: false,\n },\n ]);\n\n if (response.customizeColors) {\n const colorResponse = await prompts([\n {\n type: \"text\",\n name: \"brand\",\n message: \"Brand color (OKLCH)\",\n initial: themeColors.brand,\n },\n {\n type: \"text\",\n name: \"success\",\n message: \"Success color (OKLCH)\",\n initial: themeColors.success,\n },\n {\n type: \"text\",\n name: \"warning\",\n message: \"Warning color (OKLCH)\",\n initial: themeColors.warning,\n },\n {\n type: \"text\",\n name: \"info\",\n message: \"Info color (OKLCH)\",\n initial: themeColors.info,\n },\n ]);\n\n themeColors = {\n brand: colorResponse.brand || themeColors.brand,\n success: colorResponse.success || themeColors.success,\n warning: colorResponse.warning || themeColors.warning,\n info: colorResponse.info || themeColors.info,\n };\n }\n }\n\n // Update components.json with Frontic registry\n const spinner = ora(\"Configuring Frontic registry...\").start();\n\n try {\n await updateConfig({\n registries: {\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n spinner.succeed(\"Frontic registry configured\");\n } catch (error) {\n spinner.fail(\"Failed to configure registry\");\n throw error;\n }\n\n // Install theme\n const themeSpinner = ora(\"Installing theme...\").start();\n try {\n await spawnShadcn([\"add\", \"theme\", \"--yes\"], { silent: true });\n themeSpinner.succeed(\"Theme installed\");\n } catch {\n themeSpinner.warn(\"Theme installation skipped (may already exist)\");\n }\n\n console.log();\n console.log(chalk.green(\"✓ Frontic UI initialized successfully!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.dim(\" 1. Add components:\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log();\n console.log(chalk.dim(\" 2. Set up MCP for AI assistants (optional):\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui mcp init\")}`);\n console.log();\n}\n\nfunction getDefaultThemeColors() {\n return {\n brand: \"oklch(58% 0.25 265)\",\n success: \"oklch(55% 0.2 145)\",\n warning: \"oklch(75% 0.18 85)\",\n info: \"oklch(60% 0.2 230)\",\n };\n}\n","import { execa } from \"execa\";\n\ninterface SpawnOptions {\n silent?: boolean;\n}\n\nexport async function spawnShadcn(\n args: string[],\n options: SpawnOptions = {}\n): Promise<void> {\n const { silent = false } = options;\n\n try {\n await execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: silent ? \"pipe\" : \"inherit\",\n shell: true,\n });\n } catch (error) {\n if (!silent) {\n throw error;\n }\n // Silently ignore errors when silent mode is enabled\n }\n}\n","import { readFile, writeFile, access } from \"fs/promises\";\nimport { join } from \"path\";\nimport { CONFIG_FILE, FRONTIC_REGISTRY_URL } from \"./constants.js\";\n\nexport interface ComponentsConfig {\n $schema?: string;\n style?: string;\n typescript?: boolean;\n tailwind?: {\n css?: string;\n baseColor?: string;\n cssVariables?: boolean;\n };\n aliases?: {\n components?: string;\n utils?: string;\n ui?: string;\n lib?: string;\n composables?: string;\n };\n registries?: {\n [key: string]: {\n url: string;\n };\n };\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await access(join(process.cwd(), CONFIG_FILE));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readConfig(): Promise<ComponentsConfig | null> {\n try {\n const content = await readFile(join(process.cwd(), CONFIG_FILE), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function writeConfig(config: ComponentsConfig): Promise<void> {\n await writeFile(\n join(process.cwd(), CONFIG_FILE),\n JSON.stringify(config, null, 2)\n );\n}\n\nexport async function updateConfig(\n updates: Partial<ComponentsConfig>\n): Promise<void> {\n const existing = await readConfig();\n\n if (!existing) {\n throw new Error(\n \"components.json not found. Run `npx @frontic/ui init` first.\"\n );\n }\n\n const merged = deepMerge(existing, updates);\n await writeConfig(merged);\n}\n\nexport async function ensureFronticRegistry(): Promise<void> {\n const config = await readConfig();\n\n if (!config) {\n throw new Error(\"components.json not found\");\n }\n\n // Check if Frontic registry is already configured\n if (config.registries?.[\"@frontic\"]?.url === FRONTIC_REGISTRY_URL) {\n return;\n }\n\n // Add Frontic registry\n await updateConfig({\n registries: {\n ...config.registries,\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n}\n\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === \"object\" &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return result;\n}\n","export const FRONTIC_REGISTRY_URL = \"https://registry.frontic.io/r/{name}.json\";\n\nexport const CONFIG_FILE = \"components.json\";\n\nexport const DEFAULT_THEME_COLORS = {\n brand: \"oklch(58% 0.25 265)\",\n \"brand-foreground\": \"oklch(100% 0 0)\",\n success: \"oklch(55% 0.2 145)\",\n \"success-foreground\": \"oklch(100% 0 0)\",\n warning: \"oklch(75% 0.18 85)\",\n \"warning-foreground\": \"oklch(20% 0 0)\",\n info: \"oklch(60% 0.2 230)\",\n \"info-foreground\": \"oklch(100% 0 0)\",\n};\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { ensureFronticRegistry } from \"../utils/config.js\";\n\ninterface AddOptions {\n overwrite?: boolean;\n all?: boolean;\n path?: string;\n yes?: boolean;\n}\n\nexport function registerAddCommand(program: Command) {\n program\n .command(\"add\")\n .description(\"Add components to your project\")\n .argument(\"[components...]\", \"Components to add\")\n .option(\"-o, --overwrite\", \"Overwrite existing files\")\n .option(\"-a, --all\", \"Add all available components\")\n .option(\"-p, --path <path>\", \"Custom installation path\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .action(async (components: string[], options: AddOptions) => {\n await add(components, options);\n });\n}\n\nasync function add(components: string[], options: AddOptions) {\n // Validate input\n if (!options.all && components.length === 0) {\n console.log(chalk.red(\"Error: Please specify components to add or use --all\"));\n console.log();\n console.log(\"Usage:\");\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button dialog card\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add --all\")}`);\n process.exit(1);\n }\n\n // Ensure Frontic registry is configured\n const spinner = ora(\"Checking configuration...\").start();\n try {\n await ensureFronticRegistry();\n spinner.succeed(\"Configuration verified\");\n } catch {\n spinner.fail(\"Configuration error\");\n console.log();\n console.log(chalk.yellow(\"Run `npx @frontic/ui init` first to set up your project.\"));\n process.exit(1);\n }\n\n // Build shadcn-vue arguments\n const args = [\"add\"];\n\n if (options.all) {\n args.push(\"--all\");\n } else {\n args.push(...components);\n }\n\n if (options.overwrite) {\n args.push(\"--overwrite\");\n }\n\n if (options.path) {\n args.push(\"--path\", options.path);\n }\n\n if (options.yes) {\n args.push(\"--yes\");\n }\n\n console.log();\n console.log(chalk.blue(\"Adding components...\"));\n console.log();\n\n // Run shadcn-vue add\n await spawnShadcn(args);\n\n console.log();\n console.log(chalk.green(\"✓ Components added successfully!\"));\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { writeFile, readFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport prompts from \"prompts\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ntype McpClient = \"claude\" | \"cursor\" | \"vscode\";\n\ninterface McpInitOptions {\n client?: McpClient;\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program\n .command(\"mcp\")\n .description(\"MCP (Model Context Protocol) commands\");\n\n mcp\n .command(\"init\")\n .description(\"Set up MCP for AI assistants\")\n .option(\"-c, --client <client>\", \"Target client (claude, cursor, vscode)\")\n .action(async (options: McpInitOptions) => {\n await initMcp(options);\n });\n}\n\nasync function initMcp(options: McpInitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI - MCP Setup\"));\n console.log(chalk.dim(\"Configure AI assistant integration\"));\n console.log();\n\n let client = options.client as McpClient | undefined;\n\n // Prompt for client if not specified\n if (!client) {\n const response = await prompts({\n type: \"select\",\n name: \"client\",\n message: \"Select your AI client:\",\n choices: [\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Cursor\", value: \"cursor\" },\n { title: \"VS Code\", value: \"vscode\" },\n ],\n });\n\n client = response.client;\n\n if (!client) {\n console.log(chalk.yellow(\"Setup cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Creating MCP configuration...\").start();\n\n try {\n await createMcpConfig(client);\n spinner.succeed(\"MCP configuration created\");\n } catch (error) {\n spinner.fail(\"Failed to create MCP configuration\");\n throw error;\n }\n\n console.log();\n console.log(chalk.green(\"✓ MCP configured successfully!\"));\n console.log();\n console.log(\"Your AI assistant can now:\");\n console.log(chalk.dim(\" • Browse available Frontic UI components\"));\n console.log(chalk.dim(\" • Add components using natural language\"));\n console.log(chalk.dim(' • Example: \"Add a button component\"'));\n console.log();\n}\n\nasync function createMcpConfig(client: McpClient) {\n const config = getMcpConfig();\n const configPath = getMcpConfigPath(client);\n const configDir = join(process.cwd(), configPath.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create directory if needed\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n const fullPath = join(process.cwd(), configPath);\n\n // Read existing config or create new\n let existingConfig: Record<string, unknown> = {};\n try {\n const content = await readFile(fullPath, \"utf-8\");\n existingConfig = JSON.parse(content);\n } catch {\n // File doesn't exist, use empty config\n }\n\n // Merge with existing config\n const mergedConfig = {\n ...existingConfig,\n mcpServers: {\n ...(existingConfig.mcpServers as Record<string, unknown> || {}),\n ...config.mcpServers,\n },\n };\n\n await writeFile(fullPath, JSON.stringify(mergedConfig, null, 2));\n\n console.log(chalk.dim(` Config written to: ${configPath}`));\n}\n\nfunction getMcpConfigPath(client: McpClient): string {\n switch (client) {\n case \"claude\":\n return \".mcp.json\";\n case \"cursor\":\n return \".cursor/mcp.json\";\n case \"vscode\":\n return \".vscode/mcp.json\";\n }\n}\n\nfunction getMcpConfig() {\n return {\n mcpServers: {\n \"frontic-ui\": {\n command: \"npx\",\n args: [\"shadcn-vue@latest\", \"mcp\"],\n env: {\n SHADCN_REGISTRY_URL: FRONTIC_REGISTRY_URL,\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["program","chalk","ora","program","chalk","ora","chalk","ora","writeFile","readFile","join","prompts","program","chalk","prompts","ora","join","readFile","writeFile"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/spawn-shadcn.ts","../src/utils/config.ts","../src/utils/constants.ts","../src/utils/colors.ts","../src/commands/add.ts","../src/commands/mcp.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerAddCommand } from \"./commands/add.js\";\nimport { registerMcpCommand } from \"./commands/mcp.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"frontic-ui\")\n .description(\"CLI for adding Frontic UI components to your Vue project\")\n .version(\"0.0.5\");\n\nregisterInitCommand(program);\nregisterAddCommand(program);\nregisterMcpCommand(program);\n\nexport function run() {\n program.parse();\n}\n\nexport { program };\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { updateConfig, configExists } from \"../utils/config.js\";\nimport { FRONTIC_REGISTRY_URL, DEFAULT_BRAND_COLOR } from \"../utils/constants.js\";\nimport { hexToOklch, isValidHex, getForegroundColor } from \"../utils/colors.js\";\n\ninterface InitOptions {\n yes?: boolean;\n defaults?: boolean;\n force?: boolean;\n brand?: string;\n}\n\nexport function registerInitCommand(program: Command) {\n program\n .command(\"init\")\n .description(\"Initialize Frontic UI in your Vue project\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"-d, --defaults\", \"Use default configuration\")\n .option(\"-f, --force\", \"Force overwrite of existing configuration\")\n .option(\"-b, --brand <color>\", \"Brand color in hex format (e.g., #6366f1)\")\n .action(async (options: InitOptions) => {\n await init(options);\n });\n}\n\nasync function init(options: InitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI\"));\n console.log(chalk.dim(\"Initializing your project...\"));\n console.log();\n\n const hasConfig = await configExists();\n\n // Run shadcn-vue init if no config exists\n if (!hasConfig) {\n console.log(chalk.blue(\"Running shadcn-vue init...\"));\n console.log();\n\n const args = [\"init\"];\n if (options.yes) args.push(\"--yes\");\n if (options.defaults) args.push(\"--defaults\");\n if (options.force) args.push(\"--force\");\n\n try {\n await spawnShadcn(args);\n } catch {\n console.log();\n console.log(chalk.red(\"Failed to initialize shadcn-vue.\"));\n console.log();\n console.log(chalk.yellow(\"Common issues:\"));\n console.log(chalk.dim(\" • Tailwind CSS not installed - run: npx nuxi module add @nuxtjs/tailwindcss\"));\n console.log(chalk.dim(\" • Not in a Vue/Nuxt project root directory\"));\n console.log(chalk.dim(\" • Existing components.json with invalid config - try: npx @frontic/ui init --force\"));\n console.log();\n process.exit(1);\n }\n console.log();\n }\n\n // Get brand color\n let brandColor = DEFAULT_BRAND_COLOR;\n\n // Check if brand was provided via CLI flag\n if (options.brand) {\n if (isValidHex(options.brand)) {\n brandColor = hexToOklch(options.brand);\n console.log(chalk.dim(`Using brand color: ${options.brand} → ${brandColor}`));\n } else {\n console.log(chalk.yellow(`Invalid hex color: ${options.brand}, using default`));\n }\n } else if (!options.yes && !options.defaults) {\n // Prompt for brand color\n const response = await prompts([\n {\n type: \"text\",\n name: \"brand\",\n message: \"Brand color (hex, e.g., #6366f1)\",\n initial: \"#6366f1\",\n validate: (value: string) => {\n if (!value) return true; // Allow empty to use default\n return isValidHex(value) || \"Please enter a valid hex color (e.g., #6366f1)\";\n },\n },\n ]);\n\n if (response.brand && isValidHex(response.brand)) {\n brandColor = hexToOklch(response.brand);\n console.log(chalk.dim(`Converted: ${response.brand} → ${brandColor}`));\n }\n }\n\n // Calculate foreground color based on brand\n const brandForeground = getForegroundColor(brandColor);\n\n // Update components.json with Frontic registry\n const spinner = ora(\"Configuring Frontic registry...\").start();\n\n try {\n await updateConfig({\n registries: {\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n spinner.succeed(\"Frontic registry configured\");\n } catch (error) {\n spinner.fail(\"Failed to configure registry\");\n throw error;\n }\n\n // Install Frontic theme from registry\n const themeSpinner = ora(\"Installing Frontic theme...\").start();\n try {\n await spawnShadcn([\"add\", \"@frontic/theme\", \"--yes\"], { silent: true });\n themeSpinner.succeed(\"Frontic theme installed\");\n } catch {\n themeSpinner.warn(\"Theme installation skipped (may already exist or registry not available)\");\n }\n\n // TODO: In future, inject brand color into user's CSS\n // For now, we log it so users know what to set\n console.log();\n console.log(chalk.green(\"✓ Frontic UI initialized successfully!\"));\n console.log();\n console.log(chalk.dim(\"Your brand color:\"));\n console.log(` --brand: ${chalk.cyan(brandColor)}`);\n console.log(` --brand-foreground: ${chalk.cyan(brandForeground)}`);\n console.log();\n console.log(\"Next steps:\");\n console.log(chalk.dim(\" 1. Add components:\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log();\n console.log(chalk.dim(\" 2. Customize your brand color in your CSS:\"));\n console.log(` ${chalk.cyan(\"--brand: \" + brandColor + \";\")}`);\n console.log();\n console.log(chalk.dim(\" 3. Set up MCP for AI assistants (optional):\"));\n console.log(` ${chalk.cyan(\"npx @frontic/ui mcp init\")}`);\n console.log();\n}\n","import { execa } from \"execa\";\n\ninterface SpawnOptions {\n silent?: boolean;\n}\n\nexport async function spawnShadcn(\n args: string[],\n options: SpawnOptions = {}\n): Promise<void> {\n const { silent = false } = options;\n\n try {\n await execa(\"npx\", [\"shadcn-vue@latest\", ...args], {\n stdio: silent ? \"pipe\" : \"inherit\",\n shell: true,\n });\n } catch (error) {\n if (!silent) {\n throw error;\n }\n // Silently ignore errors when silent mode is enabled\n }\n}\n","import { readFile, writeFile, access } from \"fs/promises\";\nimport { join } from \"path\";\nimport { CONFIG_FILE, FRONTIC_REGISTRY_URL } from \"./constants.js\";\n\nexport interface ComponentsConfig {\n $schema?: string;\n style?: string;\n typescript?: boolean;\n tailwind?: {\n css?: string;\n baseColor?: string;\n cssVariables?: boolean;\n };\n aliases?: {\n components?: string;\n utils?: string;\n ui?: string;\n lib?: string;\n composables?: string;\n };\n registries?: {\n [key: string]: {\n url: string;\n };\n };\n}\n\nexport async function configExists(): Promise<boolean> {\n try {\n await access(join(process.cwd(), CONFIG_FILE));\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function readConfig(): Promise<ComponentsConfig | null> {\n try {\n const content = await readFile(join(process.cwd(), CONFIG_FILE), \"utf-8\");\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport async function writeConfig(config: ComponentsConfig): Promise<void> {\n await writeFile(\n join(process.cwd(), CONFIG_FILE),\n JSON.stringify(config, null, 2)\n );\n}\n\nexport async function updateConfig(\n updates: Partial<ComponentsConfig>\n): Promise<void> {\n const existing = await readConfig();\n\n if (!existing) {\n throw new Error(\n \"components.json not found. Run `npx @frontic/ui init` first.\"\n );\n }\n\n const merged = deepMerge(existing, updates);\n await writeConfig(merged);\n}\n\nexport async function ensureFronticRegistry(): Promise<void> {\n const config = await readConfig();\n\n if (!config) {\n throw new Error(\"components.json not found\");\n }\n\n // Check if Frontic registry is already configured\n if (config.registries?.[\"@frontic\"]?.url === FRONTIC_REGISTRY_URL) {\n return;\n }\n\n // Add Frontic registry\n await updateConfig({\n registries: {\n ...config.registries,\n \"@frontic\": {\n url: FRONTIC_REGISTRY_URL,\n },\n },\n });\n}\n\nfunction deepMerge<T extends object>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n const sourceValue = source[key];\n const targetValue = target[key];\n\n if (\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue) &&\n targetValue &&\n typeof targetValue === \"object\" &&\n !Array.isArray(targetValue)\n ) {\n (result as Record<string, unknown>)[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n );\n } else {\n (result as Record<string, unknown>)[key] = sourceValue;\n }\n }\n\n return result;\n}\n","export const FRONTIC_REGISTRY_URL = \"https://registry.frontic.io/r/{name}.json\";\n\nexport const CONFIG_FILE = \"components.json\";\n\n// Default brand color (purple - similar to Indigo 500)\nexport const DEFAULT_BRAND_COLOR = \"oklch(58% 0.25 265)\";\n","/**\n * 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 { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { spawnShadcn } from \"../utils/spawn-shadcn.js\";\nimport { ensureFronticRegistry } from \"../utils/config.js\";\n\ninterface AddOptions {\n overwrite?: boolean;\n all?: boolean;\n path?: string;\n yes?: boolean;\n}\n\nexport function registerAddCommand(program: Command) {\n program\n .command(\"add\")\n .description(\"Add components to your project\")\n .argument(\"[components...]\", \"Components to add\")\n .option(\"-o, --overwrite\", \"Overwrite existing files\")\n .option(\"-a, --all\", \"Add all available components\")\n .option(\"-p, --path <path>\", \"Custom installation path\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .action(async (components: string[], options: AddOptions) => {\n await add(components, options);\n });\n}\n\nasync function add(components: string[], options: AddOptions) {\n // Validate input\n if (!options.all && components.length === 0) {\n console.log(chalk.red(\"Error: Please specify components to add or use --all\"));\n console.log();\n console.log(\"Usage:\");\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add button dialog card\")}`);\n console.log(` ${chalk.cyan(\"npx @frontic/ui add --all\")}`);\n process.exit(1);\n }\n\n // Ensure Frontic registry is configured\n const spinner = ora(\"Checking configuration...\").start();\n try {\n await ensureFronticRegistry();\n spinner.succeed(\"Configuration verified\");\n } catch {\n spinner.fail(\"Configuration error\");\n console.log();\n console.log(chalk.yellow(\"Run `npx @frontic/ui init` first to set up your project.\"));\n process.exit(1);\n }\n\n // Build shadcn-vue arguments\n const args = [\"add\"];\n\n if (options.all) {\n args.push(\"--all\");\n } else {\n args.push(...components);\n }\n\n if (options.overwrite) {\n args.push(\"--overwrite\");\n }\n\n if (options.path) {\n args.push(\"--path\", options.path);\n }\n\n if (options.yes) {\n args.push(\"--yes\");\n }\n\n console.log();\n console.log(chalk.blue(\"Adding components...\"));\n console.log();\n\n // Run shadcn-vue add\n await spawnShadcn(args);\n\n console.log();\n console.log(chalk.green(\"✓ Components added successfully!\"));\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { writeFile, readFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport prompts from \"prompts\";\nimport { FRONTIC_REGISTRY_URL } from \"../utils/constants.js\";\n\ntype McpClient = \"claude\" | \"cursor\" | \"vscode\";\n\ninterface McpInitOptions {\n client?: McpClient;\n}\n\nexport function registerMcpCommand(program: Command) {\n const mcp = program\n .command(\"mcp\")\n .description(\"MCP (Model Context Protocol) commands\");\n\n mcp\n .command(\"init\")\n .description(\"Set up MCP for AI assistants\")\n .option(\"-c, --client <client>\", \"Target client (claude, cursor, vscode)\")\n .action(async (options: McpInitOptions) => {\n await initMcp(options);\n });\n}\n\nasync function initMcp(options: McpInitOptions) {\n console.log();\n console.log(chalk.bold(\"Frontic UI - MCP Setup\"));\n console.log(chalk.dim(\"Configure AI assistant integration\"));\n console.log();\n\n let client = options.client as McpClient | undefined;\n\n // Prompt for client if not specified\n if (!client) {\n const response = await prompts({\n type: \"select\",\n name: \"client\",\n message: \"Select your AI client:\",\n choices: [\n { title: \"Claude Code\", value: \"claude\" },\n { title: \"Cursor\", value: \"cursor\" },\n { title: \"VS Code\", value: \"vscode\" },\n ],\n });\n\n client = response.client;\n\n if (!client) {\n console.log(chalk.yellow(\"Setup cancelled.\"));\n return;\n }\n }\n\n const spinner = ora(\"Creating MCP configuration...\").start();\n\n try {\n await createMcpConfig(client);\n spinner.succeed(\"MCP configuration created\");\n } catch (error) {\n spinner.fail(\"Failed to create MCP configuration\");\n throw error;\n }\n\n console.log();\n console.log(chalk.green(\"✓ MCP configured successfully!\"));\n console.log();\n console.log(\"Your AI assistant can now:\");\n console.log(chalk.dim(\" • Browse available Frontic UI components\"));\n console.log(chalk.dim(\" • Add components using natural language\"));\n console.log(chalk.dim(' • Example: \"Add a button component\"'));\n console.log();\n}\n\nasync function createMcpConfig(client: McpClient) {\n const config = getMcpConfig();\n const configPath = getMcpConfigPath(client);\n const configDir = join(process.cwd(), configPath.split(\"/\").slice(0, -1).join(\"/\"));\n\n // Create directory if needed\n if (!existsSync(configDir)) {\n await mkdir(configDir, { recursive: true });\n }\n\n const fullPath = join(process.cwd(), configPath);\n\n // Read existing config or create new\n let existingConfig: Record<string, unknown> = {};\n try {\n const content = await readFile(fullPath, \"utf-8\");\n existingConfig = JSON.parse(content);\n } catch {\n // File doesn't exist, use empty config\n }\n\n // Merge with existing config\n const mergedConfig = {\n ...existingConfig,\n mcpServers: {\n ...(existingConfig.mcpServers as Record<string, unknown> || {}),\n ...config.mcpServers,\n },\n };\n\n await writeFile(fullPath, JSON.stringify(mergedConfig, null, 2));\n\n console.log(chalk.dim(` Config written to: ${configPath}`));\n}\n\nfunction getMcpConfigPath(client: McpClient): string {\n switch (client) {\n case \"claude\":\n return \".mcp.json\";\n case \"cursor\":\n return \".cursor/mcp.json\";\n case \"vscode\":\n return \".vscode/mcp.json\";\n }\n}\n\nfunction getMcpConfig() {\n return {\n mcpServers: {\n \"frontic-ui\": {\n command: \"npx\",\n args: [\"shadcn-vue@latest\", \"mcp\"],\n env: {\n SHADCN_REGISTRY_URL: FRONTIC_REGISTRY_URL,\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["program","chalk","ora","program","chalk","ora","chalk","ora","writeFile","readFile","join","prompts","program","chalk","prompts","ora","join","readFile","writeFile"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frontic/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "CLI for adding Frontic UI components to your Vue project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,16 +11,6 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist"
|
|
13
13
|
],
|
|
14
|
-
"scripts": {
|
|
15
|
-
"dev": "tsup --watch",
|
|
16
|
-
"build": "tsup",
|
|
17
|
-
"typecheck": "tsc --noEmit",
|
|
18
|
-
"test": "vitest run",
|
|
19
|
-
"test:unit": "vitest run tests/unit",
|
|
20
|
-
"test:integration": "vitest run tests/integration",
|
|
21
|
-
"test:watch": "vitest",
|
|
22
|
-
"clean": "rm -rf dist"
|
|
23
|
-
},
|
|
24
14
|
"dependencies": {
|
|
25
15
|
"chalk": "^5.3.0",
|
|
26
16
|
"commander": "^12.1.0",
|
|
@@ -51,5 +41,15 @@
|
|
|
51
41
|
"cli"
|
|
52
42
|
],
|
|
53
43
|
"author": "Frontic",
|
|
54
|
-
"license": "MIT"
|
|
55
|
-
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"scripts": {
|
|
46
|
+
"dev": "tsup --watch",
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:unit": "vitest run tests/unit",
|
|
51
|
+
"test:integration": "vitest run tests/integration",
|
|
52
|
+
"test:watch": "vitest",
|
|
53
|
+
"clean": "rm -rf dist"
|
|
54
|
+
}
|
|
55
|
+
}
|