shadcn-vue 2.3.0 → 2.3.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 +204 -67
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +3 -311
- package/dist/mcp-ebpb1d4Z.js +304 -0
- package/dist/mcp-ebpb1d4Z.js.map +1 -0
- package/dist/registry/index.js +1 -2
- package/dist/{api-CeF87728.js → registry-CVURNCtV.js} +148 -77
- package/dist/registry-CVURNCtV.js.map +1 -0
- package/package.json +9 -9
- package/dist/api-CeF87728.js.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/registry-DbRg0ZNQ.js +0 -97
- package/dist/registry-DbRg0ZNQ.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { BASE_COLORS, BUILTIN_REGISTRIES, DEFAULT_COMPONENTS, DEFAULT_TAILWIND_CONFIG, DEFAULT_TAILWIND_CSS, DEFAULT_UTILS, DEPRECATED_COMPONENTS, ICON_LIBRARIES, RegistryNotConfiguredError, _createSourceFile, _getQuoteChar, buildUrlAndHeadersForRegistryItem, clearRegistryContext, configWithDefaults, createConfig, fetchRegistryItems, fetchTree, findCommonRoot, findExistingEnvFile, findPackageRoot, getConfig, getItemTargetPath, getNewEnvKeys, getPackageInfo, getProjectConfig, getProjectInfo, getProjectTailwindVersionFromConfig, getRegistriesConfig, getRegistriesIndex, getRegistry, getRegistryBaseColor, getRegistryBaseColors, getRegistryIcons, getRegistryItems, getRegistryStyles, getShadcnRegistryIndex, getWorkspaceConfig, handleError, highlighter, isUniversalRegistryItem, logger, mergeEnvContent, parseRegistryAndItemFromString, resolveConfigPaths, resolveRegistryItems, resolveRegistryTree, resolveTree, spinner, transform, updateFiles, updateTailwindConfig } from "./
|
|
2
|
+
import { BASE_COLORS, BUILTIN_REGISTRIES, DEFAULT_COMPONENTS, DEFAULT_TAILWIND_CONFIG, DEFAULT_TAILWIND_CSS, DEFAULT_UTILS, DEPRECATED_COMPONENTS, ICON_LIBRARIES, RegistryNotConfiguredError, _createSourceFile, _getQuoteChar, buildUrlAndHeadersForRegistryItem, clearRegistryContext, configWithDefaults, createConfig, fetchRegistryItems, fetchTree, findCommonRoot, findExistingEnvFile, findPackageRoot, getConfig, getItemTargetPath, getNewEnvKeys, getPackageInfo, getProjectConfig, getProjectInfo, getProjectTailwindVersionFromConfig, getRegistriesConfig, getRegistriesIndex, getRegistry, getRegistryBaseColor, getRegistryBaseColors, getRegistryIcons, getRegistryItems, getRegistryStyles, getShadcnRegistryIndex, getWorkspaceConfig, handleError, highlighter, isUniversalRegistryItem, logger, mergeEnvContent, parseRegistryAndItemFromString, resolveConfigPaths, resolveRegistryItems, resolveRegistryTree, resolveTree, spinner, transform, updateFiles, updateTailwindConfig } from "./registry-CVURNCtV.js";
|
|
3
3
|
import { rawConfigSchema, registryItemSchema, registrySchema } from "./schema-PrLX5K_R.js";
|
|
4
|
+
import { server } from "./mcp-ebpb1d4Z.js";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
import path, { isAbsolute, join, normalize, resolve, sep } from "pathe";
|
|
6
7
|
import prompts from "prompts";
|
|
7
|
-
import { z } from "zod";
|
|
8
|
+
import z$1, { z } from "zod";
|
|
8
9
|
import { existsSync, promises } from "fs";
|
|
9
10
|
import deepmerge from "deepmerge";
|
|
10
11
|
import fsExtra from "fs-extra";
|
|
@@ -16,8 +17,10 @@ import { Project, ScriptKind, SyntaxKind } from "ts-morph";
|
|
|
16
17
|
import { randomBytes } from "crypto";
|
|
17
18
|
import postcss from "postcss";
|
|
18
19
|
import AtRule from "postcss/lib/at-rule";
|
|
19
|
-
import {
|
|
20
|
+
import { addDependency, detectPackageManager } from "nypm";
|
|
20
21
|
import { diffLines } from "diff";
|
|
22
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
23
|
+
import { x } from "tinyexec";
|
|
21
24
|
|
|
22
25
|
//#region src/utils/errors.ts
|
|
23
26
|
const MISSING_DIR_OR_EMPTY_PROJECT = "1";
|
|
@@ -151,14 +154,12 @@ async function updateCss(css, config, options) {
|
|
|
151
154
|
const cssFilepath = config.resolvedPaths.tailwindCss;
|
|
152
155
|
const cssFilepathRelative = path.relative(config.resolvedPaths.cwd, cssFilepath);
|
|
153
156
|
const cssSpinner = spinner(`Updating ${highlighter.info(cssFilepathRelative)}`, { silent: options.silent }).start();
|
|
154
|
-
|
|
155
|
-
let output = await transformCss(raw, css);
|
|
157
|
+
let output = await transformCss(await promises.readFile(cssFilepath, "utf8"), css);
|
|
156
158
|
await promises.writeFile(cssFilepath, output, "utf8");
|
|
157
159
|
cssSpinner.succeed();
|
|
158
160
|
}
|
|
159
161
|
async function transformCss(input, css) {
|
|
160
|
-
const
|
|
161
|
-
const result = await postcss(plugins).process(input, { from: void 0 });
|
|
162
|
+
const result = await postcss([updateCssPlugin(css)]).process(input, { from: void 0 });
|
|
162
163
|
let output = result.css;
|
|
163
164
|
const root = result.root;
|
|
164
165
|
if (root.nodes && root.nodes.length > 0) {
|
|
@@ -309,7 +310,8 @@ function updateCssPlugin(css) {
|
|
|
309
310
|
existingDecl ? existingDecl.replaceWith(decl) : utilityAtRule.append(decl);
|
|
310
311
|
} else if (typeof value === "object") processRule(utilityAtRule, prop, value);
|
|
311
312
|
}
|
|
312
|
-
} else
|
|
313
|
+
} else if (name$1 === "property") processRule(root, selector, properties);
|
|
314
|
+
else processAtRule(root, name$1, params, properties);
|
|
313
315
|
} else processRule(root, selector, properties);
|
|
314
316
|
}
|
|
315
317
|
};
|
|
@@ -400,10 +402,7 @@ function processRule(parent, selector, properties) {
|
|
|
400
402
|
});
|
|
401
403
|
const existingDecl = rule.nodes?.find((node) => node.type === "decl" && node.prop === prop);
|
|
402
404
|
existingDecl ? existingDecl.replaceWith(decl) : rule.append(decl);
|
|
403
|
-
} else if (typeof value === "object") {
|
|
404
|
-
const nestedSelector = prop.startsWith("&") ? selector.replace(/^([^:]+)/, `$1${prop.substring(1)}`) : prop;
|
|
405
|
-
processRule(parent, nestedSelector, value);
|
|
406
|
-
}
|
|
405
|
+
} else if (typeof value === "object") processRule(parent, prop.startsWith("&") ? selector.replace(/^([^:]+)/, `$1${prop.substring(1)}`) : prop, value);
|
|
407
406
|
} else if (typeof properties === "string") try {
|
|
408
407
|
const tempRule = postcss.parse(`.temp{${properties}}`).first;
|
|
409
408
|
if (tempRule && tempRule.nodes) tempRule.nodes.forEach((node) => {
|
|
@@ -434,8 +433,7 @@ async function updateCssVars(cssVars, config, options) {
|
|
|
434
433
|
const cssFilepath = config.resolvedPaths.tailwindCss;
|
|
435
434
|
const cssFilepathRelative = path.relative(config.resolvedPaths.cwd, cssFilepath);
|
|
436
435
|
const cssVarsSpinner = spinner(`Updating CSS variables in ${highlighter.info(cssFilepathRelative)}`, { silent: options.silent }).start();
|
|
437
|
-
const
|
|
438
|
-
const output = await transformCssVars(raw, cssVars ?? {}, config, {
|
|
436
|
+
const output = await transformCssVars(await promises.readFile(cssFilepath, "utf8"), cssVars ?? {}, config, {
|
|
439
437
|
cleanupDefaultNextStyles: options.cleanupDefaultNextStyles,
|
|
440
438
|
tailwindVersion: options.tailwindVersion,
|
|
441
439
|
tailwindConfig: options.tailwindConfig,
|
|
@@ -891,7 +889,7 @@ function isLocalHSLValue(value) {
|
|
|
891
889
|
return chunks.length === 3 && chunks.slice(1, 3).every((chunk) => chunk.includes("%"));
|
|
892
890
|
}
|
|
893
891
|
function isColorValue(value) {
|
|
894
|
-
return value.startsWith("hsl") || value.startsWith("rgb") || value.startsWith("#") || value.startsWith("oklch");
|
|
892
|
+
return value.startsWith("hsl") || value.startsWith("rgb") || value.startsWith("#") || value.startsWith("oklch") || value.startsWith("var(--color-");
|
|
895
893
|
}
|
|
896
894
|
|
|
897
895
|
//#endregion
|
|
@@ -906,22 +904,16 @@ async function updateDependencies(dependencies$1, devDependencies$1, config, opt
|
|
|
906
904
|
};
|
|
907
905
|
const dependenciesSpinner = spinner(`Installing dependencies.`, { silent: options.silent })?.start();
|
|
908
906
|
dependenciesSpinner?.start();
|
|
909
|
-
if (dependencies$1?.length) {
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
cwd: config.resolvedPaths.cwd,
|
|
920
|
-
silent: true,
|
|
921
|
-
dev: true
|
|
922
|
-
}));
|
|
923
|
-
await Promise.all(ensureDevDeps);
|
|
924
|
-
}
|
|
907
|
+
if (dependencies$1?.length) await addDependency(dependencies$1, {
|
|
908
|
+
cwd: config.resolvedPaths.cwd,
|
|
909
|
+
silent: true,
|
|
910
|
+
dev: false
|
|
911
|
+
});
|
|
912
|
+
if (devDependencies$1?.length) await addDependency(devDependencies$1, {
|
|
913
|
+
cwd: config.resolvedPaths.cwd,
|
|
914
|
+
silent: true,
|
|
915
|
+
dev: true
|
|
916
|
+
});
|
|
925
917
|
dependenciesSpinner?.succeed();
|
|
926
918
|
}
|
|
927
919
|
|
|
@@ -1024,7 +1016,8 @@ async function addProjectComponents(components, config, options) {
|
|
|
1024
1016
|
await updateDependencies(tree.dependencies, tree.devDependencies, config, { silent: options.silent });
|
|
1025
1017
|
await updateFiles(tree.files, config, {
|
|
1026
1018
|
overwrite: options.overwrite,
|
|
1027
|
-
silent: options.silent
|
|
1019
|
+
silent: options.silent,
|
|
1020
|
+
path: options.path
|
|
1028
1021
|
});
|
|
1029
1022
|
if (tree.docs) logger.info(tree.docs);
|
|
1030
1023
|
}
|
|
@@ -1089,7 +1082,8 @@ async function addWorkspaceComponents(components, config, workspaceConfig, optio
|
|
|
1089
1082
|
silent: true,
|
|
1090
1083
|
rootSpinner,
|
|
1091
1084
|
isRemote: options.isRemote,
|
|
1092
|
-
isWorkspace: true
|
|
1085
|
+
isWorkspace: true,
|
|
1086
|
+
path: options.path
|
|
1093
1087
|
});
|
|
1094
1088
|
filesCreated.push(...files$1.filesCreated.map((file) => path.relative(typeWorkspaceRoot, path.join(packageRoot, file))));
|
|
1095
1089
|
filesUpdated.push(...files$1.filesUpdated.map((file) => path.relative(typeWorkspaceRoot, path.join(packageRoot, file))));
|
|
@@ -1270,8 +1264,7 @@ async function updateTailwindContent(content, config, options) {
|
|
|
1270
1264
|
};
|
|
1271
1265
|
const tailwindFileRelativePath = path.relative(config.resolvedPaths.cwd, config.resolvedPaths.tailwindConfig);
|
|
1272
1266
|
const tailwindSpinner = spinner(`Updating ${highlighter.info(tailwindFileRelativePath)}`, { silent: options.silent }).start();
|
|
1273
|
-
const
|
|
1274
|
-
const output = await transformTailwindContent(raw, content, config);
|
|
1267
|
+
const output = await transformTailwindContent(await promises.readFile(config.resolvedPaths.tailwindConfig, "utf8"), content, config);
|
|
1275
1268
|
await promises.writeFile(config.resolvedPaths.tailwindConfig, output, "utf8");
|
|
1276
1269
|
tailwindSpinner?.succeed();
|
|
1277
1270
|
}
|
|
@@ -1346,8 +1339,7 @@ const init = new Command().name("init").description("initialize your project and
|
|
|
1346
1339
|
const componentsJsonPath = path.resolve(options.cwd, "components.json");
|
|
1347
1340
|
if (fsExtra.existsSync(componentsJsonPath)) {
|
|
1348
1341
|
const existingConfig = await fsExtra.readJson(componentsJsonPath);
|
|
1349
|
-
|
|
1350
|
-
shadowConfig = configWithDefaults(config);
|
|
1342
|
+
shadowConfig = configWithDefaults(rawConfigSchema.partial().parse(existingConfig));
|
|
1351
1343
|
createFileBackup(componentsJsonPath);
|
|
1352
1344
|
}
|
|
1353
1345
|
const { config: updatedConfig } = await ensureRegistriesInConfig(components, shadowConfig, { silent: true });
|
|
@@ -1390,15 +1382,13 @@ async function runInit(options) {
|
|
|
1390
1382
|
if (!proceed) process.exit(0);
|
|
1391
1383
|
}
|
|
1392
1384
|
const components = [...options.baseStyle ? ["index"] : [], ...options.components ?? []];
|
|
1393
|
-
const
|
|
1394
|
-
const { config: configWithRegistries } = await ensureRegistriesInConfig(components, fullConfigForRegistry, { silent: true });
|
|
1385
|
+
const { config: configWithRegistries } = await ensureRegistriesInConfig(components, await resolveConfigPaths(options.cwd, config), { silent: true });
|
|
1395
1386
|
if (configWithRegistries.registries) config.registries = configWithRegistries.registries;
|
|
1396
1387
|
const componentSpinner = spinner(`Writing components.json.`).start();
|
|
1397
1388
|
const targetPath = path.resolve(options.cwd, "components.json");
|
|
1398
1389
|
const backupPath = `${targetPath}${FILE_BACKUP_SUFFIX}`;
|
|
1399
1390
|
if (!options.force && fsExtra.existsSync(backupPath)) {
|
|
1400
|
-
const
|
|
1401
|
-
const { registries,...merged } = deepmerge(existingConfig, config);
|
|
1391
|
+
const { registries,...merged } = deepmerge(await fsExtra.readJson(backupPath), config);
|
|
1402
1392
|
config = {
|
|
1403
1393
|
...merged,
|
|
1404
1394
|
registries
|
|
@@ -1570,10 +1560,9 @@ async function preFlightAdd(options) {
|
|
|
1570
1560
|
};
|
|
1571
1561
|
}
|
|
1572
1562
|
try {
|
|
1573
|
-
const config = await getConfig(options.cwd);
|
|
1574
1563
|
return {
|
|
1575
1564
|
errors,
|
|
1576
|
-
config
|
|
1565
|
+
config: await getConfig(options.cwd)
|
|
1577
1566
|
};
|
|
1578
1567
|
} catch (error) {
|
|
1579
1568
|
logger.break();
|
|
@@ -1759,12 +1748,11 @@ const buildOptionsSchema = z.object({
|
|
|
1759
1748
|
});
|
|
1760
1749
|
const build = new Command().name("build").description("build components for a shadcn registry").argument("[registry]", "path to registry.json file", "./registry.json").option("-o, --output <path>", "destination directory for json files", "./public/r").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).action(async (registry, opts) => {
|
|
1761
1750
|
try {
|
|
1762
|
-
const
|
|
1751
|
+
const { resolvePaths } = await preFlightBuild(buildOptionsSchema.parse({
|
|
1763
1752
|
cwd: path.resolve(opts.cwd),
|
|
1764
1753
|
registryFile: registry,
|
|
1765
1754
|
outputDir: opts.output
|
|
1766
|
-
});
|
|
1767
|
-
const { resolvePaths } = await preFlightBuild(options);
|
|
1755
|
+
}));
|
|
1768
1756
|
const content = await fs.readFile(resolvePaths.registryFile, "utf-8");
|
|
1769
1757
|
const result = registrySchema.safeParse(JSON.parse(content));
|
|
1770
1758
|
if (!result.success) {
|
|
@@ -1823,10 +1811,7 @@ const diff = new Command().name("diff").description("check for updates against t
|
|
|
1823
1811
|
if (!options.component) {
|
|
1824
1812
|
const targetDir = config.resolvedPaths.components;
|
|
1825
1813
|
const projectComponents = registryIndex.filter((item) => {
|
|
1826
|
-
for (const file of item.files ?? [])
|
|
1827
|
-
const filePath = path.resolve(targetDir, typeof file === "string" ? file : file.path);
|
|
1828
|
-
if (existsSync(filePath)) return true;
|
|
1829
|
-
}
|
|
1814
|
+
for (const file of item.files ?? []) if (existsSync(path.resolve(targetDir, typeof file === "string" ? file : file.path))) return true;
|
|
1830
1815
|
return false;
|
|
1831
1816
|
});
|
|
1832
1817
|
const componentsWithUpdates = [];
|
|
@@ -1882,13 +1867,12 @@ async function diffComponent(component, config) {
|
|
|
1882
1867
|
if (!existsSync(filePath)) continue;
|
|
1883
1868
|
const fileContent = await promises.readFile(filePath, "utf8");
|
|
1884
1869
|
if (typeof file === "string" || !file.content) continue;
|
|
1885
|
-
const
|
|
1870
|
+
const patch = diffLines(await transform({
|
|
1886
1871
|
filename: file.path,
|
|
1887
1872
|
raw: file.content,
|
|
1888
1873
|
config,
|
|
1889
1874
|
baseColor
|
|
1890
|
-
});
|
|
1891
|
-
const patch = diffLines(registryContent, fileContent);
|
|
1875
|
+
}), fileContent);
|
|
1892
1876
|
if (patch.length > 1) changes.push({
|
|
1893
1877
|
filePath,
|
|
1894
1878
|
patch
|
|
@@ -1962,8 +1946,7 @@ async function migrateIcons(config) {
|
|
|
1962
1946
|
await Promise.all(files$1.map(async (file) => {
|
|
1963
1947
|
migrationSpinner.text = `Migrating ${file}...`;
|
|
1964
1948
|
const filePath = path.join(uiPath, file);
|
|
1965
|
-
const
|
|
1966
|
-
const content = await migrateIconsFile(fileContent, migrateOptions.sourceLibrary, migrateOptions.targetLibrary, registryIcons);
|
|
1949
|
+
const content = await migrateIconsFile(await promises.readFile(filePath, "utf-8"), migrateOptions.sourceLibrary, migrateOptions.targetLibrary, registryIcons);
|
|
1967
1950
|
await promises.writeFile(filePath, content);
|
|
1968
1951
|
}));
|
|
1969
1952
|
migrationSpinner.succeed("Migration complete.");
|
|
@@ -2014,10 +1997,9 @@ async function preFlightMigrate(options) {
|
|
|
2014
1997
|
};
|
|
2015
1998
|
}
|
|
2016
1999
|
try {
|
|
2017
|
-
const config = await getConfig(options.cwd);
|
|
2018
2000
|
return {
|
|
2019
2001
|
errors,
|
|
2020
|
-
config
|
|
2002
|
+
config: await getConfig(options.cwd)
|
|
2021
2003
|
};
|
|
2022
2004
|
} catch (error) {
|
|
2023
2005
|
logger.break();
|
|
@@ -2064,11 +2046,166 @@ const migrate = new Command().name("migrate").description("run a migration.").ar
|
|
|
2064
2046
|
}
|
|
2065
2047
|
});
|
|
2066
2048
|
|
|
2049
|
+
//#endregion
|
|
2050
|
+
//#region src/commands/mcp.ts
|
|
2051
|
+
const SHADCN_MCP_VERSION = "latest";
|
|
2052
|
+
const CLIENTS = [
|
|
2053
|
+
{
|
|
2054
|
+
name: "claude",
|
|
2055
|
+
label: "Claude Code",
|
|
2056
|
+
configPath: ".mcp.json",
|
|
2057
|
+
config: { mcpServers: { shadcnVue: {
|
|
2058
|
+
command: "npx",
|
|
2059
|
+
args: [`shadcn-vue@${SHADCN_MCP_VERSION}`, "mcp"]
|
|
2060
|
+
} } }
|
|
2061
|
+
},
|
|
2062
|
+
{
|
|
2063
|
+
name: "cursor",
|
|
2064
|
+
label: "Cursor",
|
|
2065
|
+
configPath: ".cursor/mcp.json",
|
|
2066
|
+
config: { mcpServers: { shadcnVue: {
|
|
2067
|
+
command: "npx",
|
|
2068
|
+
args: [`shadcn-vue@${SHADCN_MCP_VERSION}`, "mcp"]
|
|
2069
|
+
} } }
|
|
2070
|
+
},
|
|
2071
|
+
{
|
|
2072
|
+
name: "vscode",
|
|
2073
|
+
label: "VS Code",
|
|
2074
|
+
configPath: ".vscode/mcp.json",
|
|
2075
|
+
config: { servers: { shadcnVue: {
|
|
2076
|
+
command: "npx",
|
|
2077
|
+
args: [`shadcn-vue@${SHADCN_MCP_VERSION}`, "mcp"]
|
|
2078
|
+
} } }
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
name: "codex",
|
|
2082
|
+
label: "Codex",
|
|
2083
|
+
configPath: ".codex/config.toml",
|
|
2084
|
+
config: `[mcp_servers.shadcn_vue]
|
|
2085
|
+
command = "npx"
|
|
2086
|
+
args = ["shadcn-vue@${SHADCN_MCP_VERSION}", "mcp"]
|
|
2087
|
+
`
|
|
2088
|
+
}
|
|
2089
|
+
];
|
|
2090
|
+
const DEPENDENCIES = [`shadcn-vue@${SHADCN_MCP_VERSION}`];
|
|
2091
|
+
const mcp = new Command().name("mcp").description("MCP server and configuration commands").option("-c, --cwd <cwd>", "the working directory. defaults to the current directory.", process.cwd()).action(async (options) => {
|
|
2092
|
+
try {
|
|
2093
|
+
await loadEnvFiles(options.cwd);
|
|
2094
|
+
const transport = new StdioServerTransport();
|
|
2095
|
+
await server.connect(transport);
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
logger.break();
|
|
2098
|
+
handleError(error);
|
|
2099
|
+
}
|
|
2100
|
+
});
|
|
2101
|
+
const mcpInitOptionsSchema = z$1.object({
|
|
2102
|
+
client: z$1.enum([
|
|
2103
|
+
"claude",
|
|
2104
|
+
"cursor",
|
|
2105
|
+
"vscode",
|
|
2106
|
+
"codex"
|
|
2107
|
+
]),
|
|
2108
|
+
cwd: z$1.string()
|
|
2109
|
+
});
|
|
2110
|
+
mcp.command("init").description("Initialize MCP configuration for your client").option("--client <client>", `MCP client (${CLIENTS.map((c) => c.name).join(", ")})`).action(async (opts, command) => {
|
|
2111
|
+
try {
|
|
2112
|
+
const cwd = (command.parent?.opts() || {}).cwd || process.cwd();
|
|
2113
|
+
let client = opts.client;
|
|
2114
|
+
if (!client) {
|
|
2115
|
+
const response = await prompts({
|
|
2116
|
+
type: "select",
|
|
2117
|
+
name: "client",
|
|
2118
|
+
message: "Which MCP client are you using?",
|
|
2119
|
+
choices: CLIENTS.map((c) => ({
|
|
2120
|
+
title: c.label,
|
|
2121
|
+
value: c.name
|
|
2122
|
+
}))
|
|
2123
|
+
});
|
|
2124
|
+
if (!response.client) {
|
|
2125
|
+
logger.break();
|
|
2126
|
+
process.exit(1);
|
|
2127
|
+
}
|
|
2128
|
+
client = response.client;
|
|
2129
|
+
}
|
|
2130
|
+
const options = mcpInitOptionsSchema.parse({
|
|
2131
|
+
client,
|
|
2132
|
+
cwd
|
|
2133
|
+
});
|
|
2134
|
+
const config = await getConfig(options.cwd);
|
|
2135
|
+
if (options.client === "codex") {
|
|
2136
|
+
if (config) await updateDependencies([], DEPENDENCIES, config, { silent: false });
|
|
2137
|
+
else {
|
|
2138
|
+
const packageManager = await detectPackageManager(options.cwd);
|
|
2139
|
+
const installCommand = packageManager?.name === "npm" ? "install" : "add";
|
|
2140
|
+
const devFlag = packageManager?.name === "npm" ? "--save-dev" : "-D";
|
|
2141
|
+
const installSpinner = spinner("Installing dependencies...").start();
|
|
2142
|
+
await x(packageManager?.name || "npm", [
|
|
2143
|
+
installCommand,
|
|
2144
|
+
devFlag,
|
|
2145
|
+
...DEPENDENCIES
|
|
2146
|
+
], { nodeOptions: { cwd: options.cwd } });
|
|
2147
|
+
installSpinner.succeed("Installing dependencies.");
|
|
2148
|
+
}
|
|
2149
|
+
logger.break();
|
|
2150
|
+
logger.log("To configure the shadcn-vue MCP server in Codex:");
|
|
2151
|
+
logger.break();
|
|
2152
|
+
logger.log(`1. Open or create the file ${highlighter.info("~/.codex/config.toml")}`);
|
|
2153
|
+
logger.log("2. Add the following configuration:");
|
|
2154
|
+
logger.log();
|
|
2155
|
+
logger.info(`[mcp_servers.shadcn_vue]
|
|
2156
|
+
command = "npx"
|
|
2157
|
+
args = ["shadcn-vue@${SHADCN_MCP_VERSION}", "mcp"]`);
|
|
2158
|
+
logger.break();
|
|
2159
|
+
logger.info("3. Restart Codex to load the MCP server");
|
|
2160
|
+
logger.break();
|
|
2161
|
+
process.exit(0);
|
|
2162
|
+
}
|
|
2163
|
+
const configSpinner = spinner("Configuring MCP server...").start();
|
|
2164
|
+
const configPath = await runMcpInit(options);
|
|
2165
|
+
configSpinner.succeed("Configuring MCP server.");
|
|
2166
|
+
if (config) await updateDependencies([], DEPENDENCIES, config, { silent: false });
|
|
2167
|
+
else {
|
|
2168
|
+
const packageManager = await detectPackageManager(options.cwd);
|
|
2169
|
+
const installCommand = packageManager?.name === "npm" ? "install" : "add";
|
|
2170
|
+
const devFlag = packageManager?.name === "npm" ? "--save-dev" : "-D";
|
|
2171
|
+
const installSpinner = spinner("Installing dependencies...").start();
|
|
2172
|
+
await x(packageManager?.name || "npm", [
|
|
2173
|
+
installCommand,
|
|
2174
|
+
devFlag,
|
|
2175
|
+
...DEPENDENCIES
|
|
2176
|
+
], { nodeOptions: { cwd: options.cwd } });
|
|
2177
|
+
installSpinner.succeed("Installing dependencies.");
|
|
2178
|
+
}
|
|
2179
|
+
logger.break();
|
|
2180
|
+
logger.success(`Configuration saved to ${configPath}.`);
|
|
2181
|
+
logger.break();
|
|
2182
|
+
} catch (error) {
|
|
2183
|
+
handleError(error);
|
|
2184
|
+
}
|
|
2185
|
+
});
|
|
2186
|
+
const overwriteMerge = (_, sourceArray) => sourceArray;
|
|
2187
|
+
async function runMcpInit(options) {
|
|
2188
|
+
const { client, cwd } = options;
|
|
2189
|
+
const clientInfo = CLIENTS.find((c) => c.name === client);
|
|
2190
|
+
if (!clientInfo) throw new Error(`Unknown client: ${client}. Available clients: ${CLIENTS.map((c) => c.name).join(", ")}`);
|
|
2191
|
+
const configPath = path.join(cwd, clientInfo.configPath);
|
|
2192
|
+
const dir = path.dirname(configPath);
|
|
2193
|
+
await fsExtra.ensureDir(dir);
|
|
2194
|
+
let existingConfig = {};
|
|
2195
|
+
try {
|
|
2196
|
+
const content = await promises.readFile(configPath, "utf-8");
|
|
2197
|
+
existingConfig = JSON.parse(content);
|
|
2198
|
+
} catch {}
|
|
2199
|
+
const mergedConfig = deepmerge(existingConfig, clientInfo.config, { arrayMerge: overwriteMerge });
|
|
2200
|
+
await promises.writeFile(configPath, `${JSON.stringify(mergedConfig, null, 2)}\n`, "utf-8");
|
|
2201
|
+
return clientInfo.configPath;
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2067
2204
|
//#endregion
|
|
2068
2205
|
//#region package.json
|
|
2069
2206
|
var name = "shadcn-vue";
|
|
2070
2207
|
var type = "module";
|
|
2071
|
-
var version = "2.3.
|
|
2208
|
+
var version = "2.3.2";
|
|
2072
2209
|
var description = "Add components to your apps.";
|
|
2073
2210
|
var publishConfig = { "access": "public" };
|
|
2074
2211
|
var license = "MIT";
|
|
@@ -2128,10 +2265,10 @@ var scripts = {
|
|
|
2128
2265
|
};
|
|
2129
2266
|
var dependencies = {
|
|
2130
2267
|
"@dotenvx/dotenvx": "^1.51.0",
|
|
2131
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
2268
|
+
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
2132
2269
|
"@unovue/detypes": "^0.8.5",
|
|
2133
2270
|
"@vue/compiler-sfc": "^3.5",
|
|
2134
|
-
"c12": "^3.3.
|
|
2271
|
+
"c12": "^3.3.1",
|
|
2135
2272
|
"commander": "^14.0.1",
|
|
2136
2273
|
"consola": "^3.4.2",
|
|
2137
2274
|
"dedent": "^1.7.0",
|
|
@@ -2139,7 +2276,7 @@ var dependencies = {
|
|
|
2139
2276
|
"diff": "^8.0.2",
|
|
2140
2277
|
"fs-extra": "^11.3.2",
|
|
2141
2278
|
"fuzzysort": "^3.1.0",
|
|
2142
|
-
"get-tsconfig": "^4.
|
|
2279
|
+
"get-tsconfig": "^4.12.0",
|
|
2143
2280
|
"magic-string": "^0.30.19",
|
|
2144
2281
|
"nypm": "^0.6.2",
|
|
2145
2282
|
"ofetch": "^1.4.1",
|
|
@@ -2148,12 +2285,12 @@ var dependencies = {
|
|
|
2148
2285
|
"postcss": "^8.5.6",
|
|
2149
2286
|
"prompts": "^2.4.2",
|
|
2150
2287
|
"reka-ui": "catalog:",
|
|
2151
|
-
"semver": "^7.7.
|
|
2288
|
+
"semver": "^7.7.3",
|
|
2152
2289
|
"stringify-object": "^6.0.0",
|
|
2153
2290
|
"tailwindcss": "^4.1.14",
|
|
2154
2291
|
"tinyexec": "^1.0.1",
|
|
2155
2292
|
"tinyglobby": "catalog:",
|
|
2156
|
-
"ts-morph": "^27.0.
|
|
2293
|
+
"ts-morph": "^27.0.2",
|
|
2157
2294
|
"undici": "^7.16.0",
|
|
2158
2295
|
"vue-metamorph": "^3.3.3",
|
|
2159
2296
|
"zod": "catalog:",
|
|
@@ -2165,9 +2302,9 @@ var devDependencies = {
|
|
|
2165
2302
|
"@types/prompts": "^2.4.9",
|
|
2166
2303
|
"@types/semver": "^7.7.1",
|
|
2167
2304
|
"@types/stringify-object": "^4.0.5",
|
|
2168
|
-
"msw": "^2.11.
|
|
2169
|
-
"tsdown": "^0.15.
|
|
2170
|
-
"type-fest": "^5.0
|
|
2305
|
+
"msw": "^2.11.5",
|
|
2306
|
+
"tsdown": "^0.15.7",
|
|
2307
|
+
"type-fest": "^5.1.0",
|
|
2171
2308
|
"typescript": "catalog:"
|
|
2172
2309
|
};
|
|
2173
2310
|
var package_default = {
|
|
@@ -2193,7 +2330,7 @@ process.on("SIGINT", () => process.exit(0));
|
|
|
2193
2330
|
process.on("SIGTERM", () => process.exit(0));
|
|
2194
2331
|
async function main() {
|
|
2195
2332
|
const program = new Command().name("shadcn-vue").description("add components and dependencies to your project").version(package_default.version || "1.0.0", "-v, --version", "display the version number");
|
|
2196
|
-
program.addCommand(init).addCommand(add).addCommand(diff).addCommand(migrate).addCommand(info).addCommand(build);
|
|
2333
|
+
program.addCommand(init).addCommand(add).addCommand(diff).addCommand(migrate).addCommand(info).addCommand(build).addCommand(mcp);
|
|
2197
2334
|
program.parse();
|
|
2198
2335
|
}
|
|
2199
2336
|
main();
|