@fragments-sdk/cli 0.15.1 → 0.15.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/bin.js +148 -523
- package/dist/bin.js.map +1 -1
- package/dist/{create-IH4R45GE.js → create-JVAU3YKN.js} +53 -7
- package/dist/create-JVAU3YKN.js.map +1 -0
- package/dist/doctor-BDPMYYE6.js +385 -0
- package/dist/doctor-BDPMYYE6.js.map +1 -0
- package/package.json +18 -18
- package/src/bin.ts +4 -1
- package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/label.contract.json +1 -1
- package/src/commands/__fixtures__/shadcn-label-wrapper/src/components/ui/primitive.contract.json +1 -1
- package/src/commands/__tests__/init.test.ts +10 -2
- package/src/commands/create.ts +60 -6
- package/src/theme/generator.ts +14 -0
- package/dist/create-IH4R45GE.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -62,10 +62,10 @@ import "./chunk-7DZC4YEV.js";
|
|
|
62
62
|
|
|
63
63
|
// src/bin.ts
|
|
64
64
|
import { Command } from "commander";
|
|
65
|
-
import
|
|
65
|
+
import pc25 from "picocolors";
|
|
66
66
|
import { readFileSync } from "fs";
|
|
67
67
|
import { fileURLToPath } from "url";
|
|
68
|
-
import { dirname as dirname6, join as
|
|
68
|
+
import { dirname as dirname6, join as join11 } from "path";
|
|
69
69
|
|
|
70
70
|
// src/commands/validate.ts
|
|
71
71
|
import pc from "picocolors";
|
|
@@ -5921,421 +5921,45 @@ ${pc21.bold("Summary")}`);
|
|
|
5921
5921
|
};
|
|
5922
5922
|
}
|
|
5923
5923
|
|
|
5924
|
-
// src/commands/doctor.ts
|
|
5925
|
-
import { readFile as readFile11, access as access3 } from "fs/promises";
|
|
5926
|
-
import { join as join11, resolve as resolve12 } from "path";
|
|
5927
|
-
import pc22 from "picocolors";
|
|
5928
|
-
import { NEUTRAL_PALETTES } from "@fragments-sdk/viewer/docs-data";
|
|
5929
|
-
var VALID_NEUTRALS = NEUTRAL_PALETTES.map((p) => p.name);
|
|
5930
|
-
var VALID_DENSITIES = ["compact", "default", "relaxed"];
|
|
5931
|
-
var VALID_RADII = ["sharp", "subtle", "default", "rounded", "pill"];
|
|
5932
|
-
async function checkPackageInstalled(root) {
|
|
5933
|
-
try {
|
|
5934
|
-
const pkgPath = join11(root, "package.json");
|
|
5935
|
-
const content = await readFile11(pkgPath, "utf-8");
|
|
5936
|
-
const pkg2 = JSON.parse(content);
|
|
5937
|
-
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
5938
|
-
if (allDeps["@fragments-sdk/ui"]) {
|
|
5939
|
-
return {
|
|
5940
|
-
name: "Package installed",
|
|
5941
|
-
status: "pass",
|
|
5942
|
-
message: `@fragments-sdk/ui ${allDeps["@fragments-sdk/ui"]} found in dependencies`
|
|
5943
|
-
};
|
|
5944
|
-
}
|
|
5945
|
-
return {
|
|
5946
|
-
name: "Package installed",
|
|
5947
|
-
status: "fail",
|
|
5948
|
-
message: "@fragments-sdk/ui not found in package.json",
|
|
5949
|
-
fix: "npm install @fragments-sdk/ui"
|
|
5950
|
-
};
|
|
5951
|
-
} catch {
|
|
5952
|
-
return {
|
|
5953
|
-
name: "Package installed",
|
|
5954
|
-
status: "fail",
|
|
5955
|
-
message: "No package.json found"
|
|
5956
|
-
};
|
|
5957
|
-
}
|
|
5958
|
-
}
|
|
5959
|
-
async function checkStylesImport(root) {
|
|
5960
|
-
const entryPatterns = [
|
|
5961
|
-
"src/main.tsx",
|
|
5962
|
-
"src/main.ts",
|
|
5963
|
-
"src/index.tsx",
|
|
5964
|
-
"src/index.ts",
|
|
5965
|
-
"src/App.tsx",
|
|
5966
|
-
"src/App.ts",
|
|
5967
|
-
"app/layout.tsx",
|
|
5968
|
-
"app/layout.ts",
|
|
5969
|
-
"src/app/layout.tsx",
|
|
5970
|
-
"src/app/layout.ts",
|
|
5971
|
-
"app/root.tsx",
|
|
5972
|
-
"pages/_app.tsx",
|
|
5973
|
-
"pages/_app.ts"
|
|
5974
|
-
];
|
|
5975
|
-
for (const pattern of entryPatterns) {
|
|
5976
|
-
try {
|
|
5977
|
-
const content = await readFile11(join11(root, pattern), "utf-8");
|
|
5978
|
-
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
5979
|
-
return {
|
|
5980
|
-
name: "Styles import",
|
|
5981
|
-
status: "pass",
|
|
5982
|
-
message: `Found styles import in ${pattern}`
|
|
5983
|
-
};
|
|
5984
|
-
}
|
|
5985
|
-
if (content.includes("@fragments-sdk/ui/globals")) {
|
|
5986
|
-
return {
|
|
5987
|
-
name: "Styles import",
|
|
5988
|
-
status: "warn",
|
|
5989
|
-
message: `${pattern} uses deprecated '@fragments-sdk/ui/globals'. Use '@fragments-sdk/ui/styles' instead`,
|
|
5990
|
-
fix: `Replace '@fragments-sdk/ui/globals' with '@fragments-sdk/ui/styles' in ${pattern}`
|
|
5991
|
-
};
|
|
5992
|
-
}
|
|
5993
|
-
} catch {
|
|
5994
|
-
}
|
|
5995
|
-
}
|
|
5996
|
-
const scssPatterns = [
|
|
5997
|
-
"src/styles/globals.scss",
|
|
5998
|
-
"src/globals.scss",
|
|
5999
|
-
"styles/globals.scss",
|
|
6000
|
-
"app/globals.scss",
|
|
6001
|
-
"src/app/globals.scss",
|
|
6002
|
-
"app/styles/globals.scss"
|
|
6003
|
-
];
|
|
6004
|
-
for (const pattern of scssPatterns) {
|
|
6005
|
-
try {
|
|
6006
|
-
const content = await readFile11(join11(root, pattern), "utf-8");
|
|
6007
|
-
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
6008
|
-
return {
|
|
6009
|
-
name: "Styles import",
|
|
6010
|
-
status: "pass",
|
|
6011
|
-
message: `Found SCSS @use import in ${pattern}`
|
|
6012
|
-
};
|
|
6013
|
-
}
|
|
6014
|
-
} catch {
|
|
6015
|
-
}
|
|
6016
|
-
}
|
|
6017
|
-
return {
|
|
6018
|
-
name: "Styles import",
|
|
6019
|
-
status: "fail",
|
|
6020
|
-
message: "No @fragments-sdk/ui/styles import found in entry files",
|
|
6021
|
-
fix: "Add `import '@fragments-sdk/ui/styles'` to your app's entry file"
|
|
6022
|
-
};
|
|
6023
|
-
}
|
|
6024
|
-
async function checkThemeProvider(root) {
|
|
6025
|
-
const providerPatterns = [
|
|
6026
|
-
"src/main.tsx",
|
|
6027
|
-
"src/App.tsx",
|
|
6028
|
-
"src/providers.tsx",
|
|
6029
|
-
"app/layout.tsx",
|
|
6030
|
-
"app/providers.tsx",
|
|
6031
|
-
"src/app/layout.tsx",
|
|
6032
|
-
"src/app/providers.tsx",
|
|
6033
|
-
"app/root.tsx",
|
|
6034
|
-
"pages/_app.tsx"
|
|
6035
|
-
];
|
|
6036
|
-
for (const pattern of providerPatterns) {
|
|
6037
|
-
try {
|
|
6038
|
-
const content = await readFile11(join11(root, pattern), "utf-8");
|
|
6039
|
-
if (content.includes("ThemeProvider")) {
|
|
6040
|
-
if (content.includes("defaultTheme=") || content.includes("defaultTheme =")) {
|
|
6041
|
-
return {
|
|
6042
|
-
name: "ThemeProvider",
|
|
6043
|
-
status: "warn",
|
|
6044
|
-
message: `${pattern} uses deprecated 'defaultTheme' prop. Use 'defaultMode' instead`,
|
|
6045
|
-
fix: `Replace 'defaultTheme' with 'defaultMode' in ${pattern}`
|
|
6046
|
-
};
|
|
6047
|
-
}
|
|
6048
|
-
return {
|
|
6049
|
-
name: "ThemeProvider",
|
|
6050
|
-
status: "pass",
|
|
6051
|
-
message: `ThemeProvider found in ${pattern}`
|
|
6052
|
-
};
|
|
6053
|
-
}
|
|
6054
|
-
} catch {
|
|
6055
|
-
}
|
|
6056
|
-
}
|
|
6057
|
-
return {
|
|
6058
|
-
name: "ThemeProvider",
|
|
6059
|
-
status: "warn",
|
|
6060
|
-
message: "ThemeProvider not found in common entry files (optional but recommended)",
|
|
6061
|
-
fix: 'Wrap your app with <ThemeProvider defaultMode="system">'
|
|
6062
|
-
};
|
|
6063
|
-
}
|
|
6064
|
-
async function checkScssSeeds(root) {
|
|
6065
|
-
const checks = [];
|
|
6066
|
-
const scssPatterns = [
|
|
6067
|
-
"src/styles/globals.scss",
|
|
6068
|
-
"src/globals.scss",
|
|
6069
|
-
"styles/globals.scss",
|
|
6070
|
-
"app/globals.scss",
|
|
6071
|
-
"src/app/globals.scss",
|
|
6072
|
-
"app/styles/globals.scss"
|
|
6073
|
-
];
|
|
6074
|
-
for (const pattern of scssPatterns) {
|
|
6075
|
-
try {
|
|
6076
|
-
const content = await readFile11(join11(root, pattern), "utf-8");
|
|
6077
|
-
if (!content.includes("@fragments-sdk/ui/styles")) continue;
|
|
6078
|
-
const standalonePattern = /^\$fui-\w+:\s*.+;$/m;
|
|
6079
|
-
if (standalonePattern.test(content) && !content.includes("@use")) {
|
|
6080
|
-
checks.push({
|
|
6081
|
-
name: "SCSS syntax",
|
|
6082
|
-
status: "fail",
|
|
6083
|
-
message: `${pattern} uses standalone $fui- variables. Must use @use...with() syntax`,
|
|
6084
|
-
fix: "@use '@fragments-sdk/ui/styles' with ($fui-brand: #0066ff);"
|
|
6085
|
-
});
|
|
6086
|
-
}
|
|
6087
|
-
const neutralMatch = content.match(/\$fui-neutral:\s*"([^"]+)"/);
|
|
6088
|
-
if (neutralMatch && !VALID_NEUTRALS.includes(neutralMatch[1])) {
|
|
6089
|
-
checks.push({
|
|
6090
|
-
name: "SCSS seed: neutral",
|
|
6091
|
-
status: "fail",
|
|
6092
|
-
message: `Invalid $fui-neutral: "${neutralMatch[1]}" in ${pattern}`,
|
|
6093
|
-
fix: `Valid neutrals: ${VALID_NEUTRALS.join(", ")}`
|
|
6094
|
-
});
|
|
6095
|
-
}
|
|
6096
|
-
const densityMatch = content.match(/\$fui-density:\s*"([^"]+)"/);
|
|
6097
|
-
if (densityMatch && !VALID_DENSITIES.includes(densityMatch[1])) {
|
|
6098
|
-
checks.push({
|
|
6099
|
-
name: "SCSS seed: density",
|
|
6100
|
-
status: "fail",
|
|
6101
|
-
message: `Invalid $fui-density: "${densityMatch[1]}" in ${pattern}`,
|
|
6102
|
-
fix: `Valid densities: ${VALID_DENSITIES.join(", ")}`
|
|
6103
|
-
});
|
|
6104
|
-
}
|
|
6105
|
-
const radiusMatch = content.match(/\$fui-radius-style:\s*"([^"]+)"/);
|
|
6106
|
-
if (radiusMatch && !VALID_RADII.includes(radiusMatch[1])) {
|
|
6107
|
-
checks.push({
|
|
6108
|
-
name: "SCSS seed: radius-style",
|
|
6109
|
-
status: "fail",
|
|
6110
|
-
message: `Invalid $fui-radius-style: "${radiusMatch[1]}" in ${pattern}`,
|
|
6111
|
-
fix: `Valid radius styles: ${VALID_RADII.join(", ")}`
|
|
6112
|
-
});
|
|
6113
|
-
}
|
|
6114
|
-
const brandMatch = content.match(/\$fui-brand:\s*(#[0-9a-fA-F]+)/);
|
|
6115
|
-
if (brandMatch) {
|
|
6116
|
-
const hex = brandMatch[1];
|
|
6117
|
-
if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) {
|
|
6118
|
-
checks.push({
|
|
6119
|
-
name: "SCSS seed: brand",
|
|
6120
|
-
status: "fail",
|
|
6121
|
-
message: `Invalid $fui-brand color: "${hex}" in ${pattern}`,
|
|
6122
|
-
fix: "Must be a valid hex color (e.g., #0066ff)"
|
|
6123
|
-
});
|
|
6124
|
-
}
|
|
6125
|
-
}
|
|
6126
|
-
if (checks.length === 0) {
|
|
6127
|
-
checks.push({
|
|
6128
|
-
name: "SCSS seeds",
|
|
6129
|
-
status: "pass",
|
|
6130
|
-
message: `Seed values in ${pattern} are valid`
|
|
6131
|
-
});
|
|
6132
|
-
}
|
|
6133
|
-
return checks;
|
|
6134
|
-
} catch {
|
|
6135
|
-
}
|
|
6136
|
-
}
|
|
6137
|
-
checks.push({
|
|
6138
|
-
name: "SCSS seeds",
|
|
6139
|
-
status: "pass",
|
|
6140
|
-
message: "No custom SCSS seeds configured (using defaults)"
|
|
6141
|
-
});
|
|
6142
|
-
return checks;
|
|
6143
|
-
}
|
|
6144
|
-
async function checkPeerDeps(root) {
|
|
6145
|
-
const checks = [];
|
|
6146
|
-
try {
|
|
6147
|
-
const pkgPath = join11(root, "package.json");
|
|
6148
|
-
const content = await readFile11(pkgPath, "utf-8");
|
|
6149
|
-
const pkg2 = JSON.parse(content);
|
|
6150
|
-
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
6151
|
-
if (!allDeps["react"]) {
|
|
6152
|
-
checks.push({
|
|
6153
|
-
name: "Peer dep: react",
|
|
6154
|
-
status: "fail",
|
|
6155
|
-
message: "react not found in dependencies (required)",
|
|
6156
|
-
fix: "npm install react react-dom"
|
|
6157
|
-
});
|
|
6158
|
-
} else {
|
|
6159
|
-
checks.push({
|
|
6160
|
-
name: "Peer dep: react",
|
|
6161
|
-
status: "pass",
|
|
6162
|
-
message: `react ${allDeps["react"]} installed`
|
|
6163
|
-
});
|
|
6164
|
-
}
|
|
6165
|
-
if (!allDeps["sass"]) {
|
|
6166
|
-
checks.push({
|
|
6167
|
-
name: "Peer dep: sass",
|
|
6168
|
-
status: "warn",
|
|
6169
|
-
message: "sass not installed (needed for custom SCSS theming)",
|
|
6170
|
-
fix: "npm install -D sass"
|
|
6171
|
-
});
|
|
6172
|
-
}
|
|
6173
|
-
const optionalPeers = [
|
|
6174
|
-
{ pkg: "recharts", components: "Chart" },
|
|
6175
|
-
{ pkg: "shiki", components: "CodeBlock" },
|
|
6176
|
-
{ pkg: "react-day-picker", components: "DatePicker" },
|
|
6177
|
-
{ pkg: "@tanstack/react-table", components: "DataTable" }
|
|
6178
|
-
];
|
|
6179
|
-
for (const peer of optionalPeers) {
|
|
6180
|
-
if (allDeps[peer.pkg]) {
|
|
6181
|
-
checks.push({
|
|
6182
|
-
name: `Optional dep: ${peer.pkg}`,
|
|
6183
|
-
status: "pass",
|
|
6184
|
-
message: `${peer.pkg} installed (enables ${peer.components})`
|
|
6185
|
-
});
|
|
6186
|
-
}
|
|
6187
|
-
}
|
|
6188
|
-
} catch {
|
|
6189
|
-
checks.push({
|
|
6190
|
-
name: "Peer dependencies",
|
|
6191
|
-
status: "fail",
|
|
6192
|
-
message: "Could not read package.json"
|
|
6193
|
-
});
|
|
6194
|
-
}
|
|
6195
|
-
return checks;
|
|
6196
|
-
}
|
|
6197
|
-
async function checkMcpConfig(root) {
|
|
6198
|
-
const mcpConfigPaths = [
|
|
6199
|
-
".mcp.json",
|
|
6200
|
-
".cursor/mcp.json",
|
|
6201
|
-
".vscode/mcp.json"
|
|
6202
|
-
];
|
|
6203
|
-
for (const configPath of mcpConfigPaths) {
|
|
6204
|
-
try {
|
|
6205
|
-
const fullPath = join11(root, configPath);
|
|
6206
|
-
const content = await readFile11(fullPath, "utf-8");
|
|
6207
|
-
const config = JSON.parse(content);
|
|
6208
|
-
const servers = config.mcpServers || config.servers || {};
|
|
6209
|
-
const hasFragments = Object.values(servers).some((server) => {
|
|
6210
|
-
const s = server;
|
|
6211
|
-
return s.args?.some((arg) => arg.includes("@fragments-sdk/mcp")) || s.command?.includes("fragments");
|
|
6212
|
-
});
|
|
6213
|
-
if (hasFragments) {
|
|
6214
|
-
return {
|
|
6215
|
-
name: "MCP configuration",
|
|
6216
|
-
status: "pass",
|
|
6217
|
-
message: `Fragments MCP server configured in ${configPath}`
|
|
6218
|
-
};
|
|
6219
|
-
}
|
|
6220
|
-
} catch {
|
|
6221
|
-
}
|
|
6222
|
-
}
|
|
6223
|
-
return {
|
|
6224
|
-
name: "MCP configuration",
|
|
6225
|
-
status: "warn",
|
|
6226
|
-
message: "No Fragments MCP server configuration found (optional)",
|
|
6227
|
-
fix: "Run `fragments init` or add @fragments-sdk/mcp to your MCP config"
|
|
6228
|
-
};
|
|
6229
|
-
}
|
|
6230
|
-
async function checkTypeScript(root) {
|
|
6231
|
-
try {
|
|
6232
|
-
const tsconfigPath = join11(root, "tsconfig.json");
|
|
6233
|
-
await access3(tsconfigPath);
|
|
6234
|
-
return {
|
|
6235
|
-
name: "TypeScript",
|
|
6236
|
-
status: "pass",
|
|
6237
|
-
message: "tsconfig.json found"
|
|
6238
|
-
};
|
|
6239
|
-
} catch {
|
|
6240
|
-
return {
|
|
6241
|
-
name: "TypeScript",
|
|
6242
|
-
status: "warn",
|
|
6243
|
-
message: "No tsconfig.json found (TypeScript recommended but not required)"
|
|
6244
|
-
};
|
|
6245
|
-
}
|
|
6246
|
-
}
|
|
6247
|
-
async function doctor(options = {}) {
|
|
6248
|
-
const root = resolve12(options.root ?? process.cwd());
|
|
6249
|
-
const checks = [];
|
|
6250
|
-
if (!options.json) {
|
|
6251
|
-
console.log(pc22.cyan(`
|
|
6252
|
-
${BRAND.name} Doctor
|
|
6253
|
-
`));
|
|
6254
|
-
console.log(pc22.dim(`Checking project at ${root}
|
|
6255
|
-
`));
|
|
6256
|
-
}
|
|
6257
|
-
checks.push(await checkPackageInstalled(root));
|
|
6258
|
-
checks.push(await checkStylesImport(root));
|
|
6259
|
-
checks.push(await checkThemeProvider(root));
|
|
6260
|
-
checks.push(...await checkScssSeeds(root));
|
|
6261
|
-
checks.push(...await checkPeerDeps(root));
|
|
6262
|
-
checks.push(await checkMcpConfig(root));
|
|
6263
|
-
checks.push(await checkTypeScript(root));
|
|
6264
|
-
const passed = checks.filter((c) => c.status === "pass").length;
|
|
6265
|
-
const warned = checks.filter((c) => c.status === "warn").length;
|
|
6266
|
-
const failed = checks.filter((c) => c.status === "fail").length;
|
|
6267
|
-
const result = {
|
|
6268
|
-
success: failed === 0,
|
|
6269
|
-
checks,
|
|
6270
|
-
passed,
|
|
6271
|
-
warned,
|
|
6272
|
-
failed
|
|
6273
|
-
};
|
|
6274
|
-
if (options.json) {
|
|
6275
|
-
console.log(JSON.stringify(result, null, 2));
|
|
6276
|
-
} else {
|
|
6277
|
-
for (const check of checks) {
|
|
6278
|
-
const icon = check.status === "pass" ? pc22.green("\u2713") : check.status === "warn" ? pc22.yellow("!") : pc22.red("\u2717");
|
|
6279
|
-
const msg = check.status === "pass" ? check.message : check.status === "warn" ? pc22.yellow(check.message) : pc22.red(check.message);
|
|
6280
|
-
console.log(` ${icon} ${pc22.bold(check.name)}: ${msg}`);
|
|
6281
|
-
if (check.fix && check.status !== "pass") {
|
|
6282
|
-
console.log(pc22.dim(` \u2192 ${check.fix}`));
|
|
6283
|
-
}
|
|
6284
|
-
}
|
|
6285
|
-
console.log();
|
|
6286
|
-
if (failed === 0 && warned === 0) {
|
|
6287
|
-
console.log(pc22.green(`\u2713 All ${passed} checks passed \u2014 your setup looks great!`));
|
|
6288
|
-
} else if (failed === 0) {
|
|
6289
|
-
console.log(pc22.green(`\u2713 ${passed} passed`) + pc22.yellow(`, ${warned} warning(s)`));
|
|
6290
|
-
} else {
|
|
6291
|
-
console.log(
|
|
6292
|
-
pc22.red(`\u2717 ${failed} failed`) + (warned > 0 ? pc22.yellow(`, ${warned} warning(s)`) : "") + pc22.dim(`, ${passed} passed`)
|
|
6293
|
-
);
|
|
6294
|
-
}
|
|
6295
|
-
console.log();
|
|
6296
|
-
}
|
|
6297
|
-
return result;
|
|
6298
|
-
}
|
|
6299
|
-
|
|
6300
5924
|
// src/commands/sync.ts
|
|
6301
|
-
import
|
|
6302
|
-
import { readFile as
|
|
5925
|
+
import pc22 from "picocolors";
|
|
5926
|
+
import { readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
|
|
6303
5927
|
import { resolveComponentSourcePath } from "@fragments-sdk/extract";
|
|
6304
5928
|
import { createComponentExtractor } from "@fragments-sdk/extract";
|
|
6305
5929
|
async function sync(options = {}) {
|
|
6306
5930
|
const { config, configDir } = await loadConfig(options.config);
|
|
6307
|
-
console.log(
|
|
5931
|
+
console.log(pc22.cyan(`
|
|
6308
5932
|
${BRAND.name} Sync
|
|
6309
5933
|
`));
|
|
6310
5934
|
if (options.dryRun) {
|
|
6311
|
-
console.log(
|
|
5935
|
+
console.log(pc22.dim("Dry run \u2014 no files will be modified.\n"));
|
|
6312
5936
|
}
|
|
6313
5937
|
const result = await runSync(config, configDir, options);
|
|
6314
5938
|
if (result.updated.length > 0) {
|
|
6315
5939
|
const verb = options.dryRun ? "Would update" : "Updated";
|
|
6316
|
-
console.log(
|
|
5940
|
+
console.log(pc22.bold(`${verb} ${result.updated.length} fragment(s):
|
|
6317
5941
|
`));
|
|
6318
5942
|
for (const comp of result.updated) {
|
|
6319
|
-
console.log(` ${
|
|
5943
|
+
console.log(` ${pc22.green("\u2713")} ${pc22.bold(comp.name)} ${pc22.dim(`(${comp.file})`)}`);
|
|
6320
5944
|
for (const change of comp.changes) {
|
|
6321
|
-
console.log(` ${
|
|
5945
|
+
console.log(` ${pc22.dim("\u2022")} ${change}`);
|
|
6322
5946
|
}
|
|
6323
5947
|
}
|
|
6324
5948
|
console.log();
|
|
6325
5949
|
}
|
|
6326
5950
|
if (result.skipped.length > 0) {
|
|
6327
|
-
console.log(
|
|
5951
|
+
console.log(pc22.dim(`Skipped ${result.skipped.length}: ${result.skipped.map((s) => s.name).join(", ")}
|
|
6328
5952
|
`));
|
|
6329
5953
|
}
|
|
6330
5954
|
if (result.errors.length > 0) {
|
|
6331
|
-
console.log(
|
|
5955
|
+
console.log(pc22.red(pc22.bold("Errors:")));
|
|
6332
5956
|
for (const err of result.errors) {
|
|
6333
|
-
console.log(` ${
|
|
5957
|
+
console.log(` ${pc22.red("\u2717")} ${pc22.bold(err.file)}: ${err.message}`);
|
|
6334
5958
|
}
|
|
6335
5959
|
console.log();
|
|
6336
5960
|
}
|
|
6337
5961
|
if (result.updated.length === 0 && result.errors.length === 0) {
|
|
6338
|
-
console.log(
|
|
5962
|
+
console.log(pc22.green("All fragments are in sync \u2014 nothing to update.\n"));
|
|
6339
5963
|
}
|
|
6340
5964
|
return result;
|
|
6341
5965
|
}
|
|
@@ -6354,7 +5978,7 @@ async function runSync(config, configDir, options) {
|
|
|
6354
5978
|
const fragment = await loadFragmentFile(file.absolutePath);
|
|
6355
5979
|
if (!fragment?.meta?.name) continue;
|
|
6356
5980
|
if (options.component && fragment.meta.name !== options.component) continue;
|
|
6357
|
-
const fileContent = await
|
|
5981
|
+
const fileContent = await readFile11(file.absolutePath, "utf-8");
|
|
6358
5982
|
const parsed = parseFragmentFile(fileContent, file.absolutePath);
|
|
6359
5983
|
if (!parsed.componentImport) {
|
|
6360
5984
|
skipped.push({ name: fragment.meta.name, reason: "No component import found" });
|
|
@@ -6516,9 +6140,9 @@ function escapeRegex(str) {
|
|
|
6516
6140
|
}
|
|
6517
6141
|
|
|
6518
6142
|
// src/commands/govern.ts
|
|
6519
|
-
import
|
|
6143
|
+
import pc23 from "picocolors";
|
|
6520
6144
|
async function governCheck(options = {}) {
|
|
6521
|
-
console.log(
|
|
6145
|
+
console.log(pc23.cyan(`
|
|
6522
6146
|
${BRAND.name} Governance Check
|
|
6523
6147
|
`));
|
|
6524
6148
|
const { cliCheck, formatVerdict } = await import("@fragments-sdk/govern");
|
|
@@ -6529,10 +6153,10 @@ ${BRAND.name} Governance Check
|
|
|
6529
6153
|
console.log();
|
|
6530
6154
|
}
|
|
6531
6155
|
if (result.verdict.passed) {
|
|
6532
|
-
console.log(
|
|
6156
|
+
console.log(pc23.green(`\u2713 Governance check passed (score: ${result.verdict.score}/100)
|
|
6533
6157
|
`));
|
|
6534
6158
|
} else {
|
|
6535
|
-
console.log(
|
|
6159
|
+
console.log(pc23.red(`\u2717 Governance check failed (score: ${result.verdict.score}/100)
|
|
6536
6160
|
`));
|
|
6537
6161
|
}
|
|
6538
6162
|
return { exitCode: result.exitCode };
|
|
@@ -6540,7 +6164,7 @@ ${BRAND.name} Governance Check
|
|
|
6540
6164
|
async function governInit(options = {}) {
|
|
6541
6165
|
const { writeFile: writeFile11 } = await import("fs/promises");
|
|
6542
6166
|
const { existsSync: existsSync4 } = await import("fs");
|
|
6543
|
-
const { resolve:
|
|
6167
|
+
const { resolve: resolve14 } = await import("path");
|
|
6544
6168
|
const { generateConfigTemplate } = await import("@fragments-sdk/govern");
|
|
6545
6169
|
const { findTailwindConfig } = await import("./token-normalizer-TEPOVBPV.js");
|
|
6546
6170
|
const cwd = process.cwd();
|
|
@@ -6553,7 +6177,7 @@ async function governInit(options = {}) {
|
|
|
6553
6177
|
const { relative: relative9 } = await import("path");
|
|
6554
6178
|
detected.tokenIncludes.push(relative9(cwd, tailwindPath));
|
|
6555
6179
|
detected.projectType = "tailwind";
|
|
6556
|
-
console.log(
|
|
6180
|
+
console.log(pc23.dim(` Detected Tailwind config: ${detected.tokenIncludes[0]}`));
|
|
6557
6181
|
}
|
|
6558
6182
|
if (detected.tokenIncludes.length === 0) {
|
|
6559
6183
|
const candidates = [
|
|
@@ -6569,49 +6193,49 @@ async function governInit(options = {}) {
|
|
|
6569
6193
|
"src/tokens.json"
|
|
6570
6194
|
];
|
|
6571
6195
|
for (const candidate of candidates) {
|
|
6572
|
-
if (existsSync4(
|
|
6196
|
+
if (existsSync4(resolve14(cwd, candidate))) {
|
|
6573
6197
|
detected.tokenIncludes.push(candidate);
|
|
6574
6198
|
detected.projectType = candidate.endsWith(".scss") ? "scss" : candidate.endsWith(".json") ? "dtcg" : "css";
|
|
6575
|
-
console.log(
|
|
6199
|
+
console.log(pc23.dim(` Detected token source: ${candidate}`));
|
|
6576
6200
|
}
|
|
6577
6201
|
}
|
|
6578
6202
|
}
|
|
6579
6203
|
if (detected.tokenIncludes.length === 0) {
|
|
6580
|
-
console.log(
|
|
6204
|
+
console.log(pc23.dim(" No token sources auto-detected. You can add them manually."));
|
|
6581
6205
|
}
|
|
6582
|
-
const outputPath =
|
|
6206
|
+
const outputPath = resolve14(options.output ?? "fragments.config.ts");
|
|
6583
6207
|
const template = generateConfigTemplate({ tokenIncludes: detected.tokenIncludes });
|
|
6584
6208
|
await writeFile11(outputPath, template, "utf-8");
|
|
6585
|
-
console.log(
|
|
6209
|
+
console.log(pc23.green(`
|
|
6586
6210
|
\u2713 Created ${outputPath}
|
|
6587
6211
|
`));
|
|
6588
6212
|
if (detected.tokenIncludes.length > 0) {
|
|
6589
6213
|
console.log(
|
|
6590
|
-
|
|
6214
|
+
pc23.dim(` Token sources configured: ${detected.tokenIncludes.join(", ")}`)
|
|
6591
6215
|
);
|
|
6592
6216
|
}
|
|
6593
6217
|
console.log(
|
|
6594
|
-
|
|
6218
|
+
pc23.dim(" Run ") + pc23.cyan("fragments govern scan") + pc23.dim(" to check your project.\n")
|
|
6595
6219
|
);
|
|
6596
6220
|
}
|
|
6597
6221
|
async function governConnect() {
|
|
6598
|
-
const { readFile:
|
|
6222
|
+
const { readFile: readFile13, writeFile: writeFile11, appendFile } = await import("fs/promises");
|
|
6599
6223
|
const { existsSync: existsSync4 } = await import("fs");
|
|
6600
|
-
const { resolve:
|
|
6224
|
+
const { resolve: resolve14 } = await import("path");
|
|
6601
6225
|
const { platform } = await import("os");
|
|
6602
6226
|
const { exec } = await import("child_process");
|
|
6603
6227
|
const { password, confirm } = await import("@inquirer/prompts");
|
|
6604
6228
|
const cloudUrl = process.env.FRAGMENTS_URL ?? "https://app.usefragments.com";
|
|
6605
|
-
console.log(
|
|
6229
|
+
console.log(pc23.cyan(`
|
|
6606
6230
|
${BRAND.name} \u2014 Connect to Cloud
|
|
6607
6231
|
`));
|
|
6608
6232
|
console.log(
|
|
6609
|
-
|
|
6233
|
+
pc23.dim(" This will connect your project to the Fragments dashboard\n") + pc23.dim(" for centralized audit tracking and team visibility.\n")
|
|
6610
6234
|
);
|
|
6611
|
-
console.log(
|
|
6235
|
+
console.log(pc23.bold(" Step 1 of 3: Get your API key\n"));
|
|
6612
6236
|
const dashboardUrl = `${cloudUrl}/api-keys`;
|
|
6613
|
-
console.log(
|
|
6614
|
-
console.log(
|
|
6237
|
+
console.log(pc23.dim(` \u2192 Opening the dashboard in your browser...`));
|
|
6238
|
+
console.log(pc23.dim(` Copy your API key from Settings \u2192 API Keys
|
|
6615
6239
|
`));
|
|
6616
6240
|
const os = platform();
|
|
6617
6241
|
const openCmd = os === "darwin" ? `open "${dashboardUrl}"` : os === "win32" ? `start "" "${dashboardUrl}"` : `xdg-open "${dashboardUrl}"`;
|
|
@@ -6624,120 +6248,120 @@ async function governConnect() {
|
|
|
6624
6248
|
mask: "*"
|
|
6625
6249
|
});
|
|
6626
6250
|
if (!apiKey.trim()) {
|
|
6627
|
-
console.log(
|
|
6251
|
+
console.log(pc23.yellow("\n API key cannot be empty. Please try again.\n"));
|
|
6628
6252
|
continue;
|
|
6629
6253
|
}
|
|
6630
|
-
console.log(
|
|
6254
|
+
console.log(pc23.dim("\n Verifying..."));
|
|
6631
6255
|
try {
|
|
6632
6256
|
const response = await fetch(`${cloudUrl}/api/verify`, {
|
|
6633
6257
|
headers: { Authorization: `Bearer ${apiKey.trim()}` }
|
|
6634
6258
|
});
|
|
6635
6259
|
if (!response.ok) {
|
|
6636
|
-
console.log(
|
|
6260
|
+
console.log(pc23.red(`
|
|
6637
6261
|
\u2717 Invalid API key (HTTP ${response.status}). Please try again.
|
|
6638
6262
|
`));
|
|
6639
6263
|
continue;
|
|
6640
6264
|
}
|
|
6641
6265
|
const data = await response.json();
|
|
6642
6266
|
if (!data.valid) {
|
|
6643
|
-
console.log(
|
|
6267
|
+
console.log(pc23.red("\n \u2717 API key not recognized. Please try again.\n"));
|
|
6644
6268
|
continue;
|
|
6645
6269
|
}
|
|
6646
6270
|
orgName = data.orgName ?? "your organization";
|
|
6647
|
-
console.log(
|
|
6271
|
+
console.log(pc23.green(`
|
|
6648
6272
|
\u2713 Connected to "${orgName}" (verified)
|
|
6649
6273
|
`));
|
|
6650
6274
|
break;
|
|
6651
6275
|
} catch (error) {
|
|
6652
6276
|
console.log(
|
|
6653
|
-
|
|
6277
|
+
pc23.red("\n \u2717 Could not reach the dashboard.")
|
|
6654
6278
|
);
|
|
6655
6279
|
console.log(
|
|
6656
|
-
|
|
6280
|
+
pc23.dim(` ${error instanceof Error ? error.message : "Network error"}
|
|
6657
6281
|
`)
|
|
6658
6282
|
);
|
|
6659
6283
|
continue;
|
|
6660
6284
|
}
|
|
6661
6285
|
}
|
|
6662
|
-
console.log(
|
|
6286
|
+
console.log(pc23.bold(" Step 2 of 3: Save configuration\n"));
|
|
6663
6287
|
const saveToEnv = await confirm({
|
|
6664
6288
|
message: "Save API key to .env file?",
|
|
6665
6289
|
default: true
|
|
6666
6290
|
});
|
|
6667
6291
|
if (saveToEnv) {
|
|
6668
|
-
const envPath =
|
|
6292
|
+
const envPath = resolve14(".env");
|
|
6669
6293
|
const envEntry = `FRAGMENTS_API_KEY=${apiKey.trim()}`;
|
|
6670
6294
|
if (existsSync4(envPath)) {
|
|
6671
|
-
const envContent = await
|
|
6295
|
+
const envContent = await readFile13(envPath, "utf-8");
|
|
6672
6296
|
if (envContent.includes("FRAGMENTS_API_KEY=")) {
|
|
6673
6297
|
const updated = envContent.replace(
|
|
6674
6298
|
/^FRAGMENTS_API_KEY=.*$/m,
|
|
6675
6299
|
envEntry
|
|
6676
6300
|
);
|
|
6677
6301
|
await writeFile11(envPath, updated, "utf-8");
|
|
6678
|
-
console.log(
|
|
6302
|
+
console.log(pc23.green(" \u2713 Updated FRAGMENTS_API_KEY in .env"));
|
|
6679
6303
|
} else {
|
|
6680
6304
|
await appendFile(envPath, `
|
|
6681
6305
|
${envEntry}
|
|
6682
6306
|
`, "utf-8");
|
|
6683
|
-
console.log(
|
|
6307
|
+
console.log(pc23.green(" \u2713 Added FRAGMENTS_API_KEY to .env"));
|
|
6684
6308
|
}
|
|
6685
6309
|
} else {
|
|
6686
6310
|
await writeFile11(envPath, `${envEntry}
|
|
6687
6311
|
`, "utf-8");
|
|
6688
|
-
console.log(
|
|
6312
|
+
console.log(pc23.green(" \u2713 Created .env with FRAGMENTS_API_KEY"));
|
|
6689
6313
|
}
|
|
6690
6314
|
if (cloudUrl !== "https://app.usefragments.com") {
|
|
6691
|
-
const envContent = await
|
|
6315
|
+
const envContent = await readFile13(envPath, "utf-8");
|
|
6692
6316
|
if (!envContent.includes("FRAGMENTS_URL=")) {
|
|
6693
6317
|
await appendFile(envPath, `FRAGMENTS_URL=${cloudUrl}
|
|
6694
6318
|
`, "utf-8");
|
|
6695
|
-
console.log(
|
|
6319
|
+
console.log(pc23.green(` \u2713 Added FRAGMENTS_URL to .env`));
|
|
6696
6320
|
}
|
|
6697
6321
|
}
|
|
6698
|
-
const gitignorePath =
|
|
6322
|
+
const gitignorePath = resolve14(".gitignore");
|
|
6699
6323
|
if (existsSync4(gitignorePath)) {
|
|
6700
|
-
const gitignore = await
|
|
6324
|
+
const gitignore = await readFile13(gitignorePath, "utf-8");
|
|
6701
6325
|
if (!gitignore.split("\n").some((line) => line.trim() === ".env")) {
|
|
6702
6326
|
await appendFile(gitignorePath, "\n.env\n", "utf-8");
|
|
6703
|
-
console.log(
|
|
6327
|
+
console.log(pc23.green(" \u2713 Added .env to .gitignore"));
|
|
6704
6328
|
}
|
|
6705
6329
|
} else {
|
|
6706
6330
|
await writeFile11(gitignorePath, ".env\n", "utf-8");
|
|
6707
|
-
console.log(
|
|
6331
|
+
console.log(pc23.green(" \u2713 Created .gitignore with .env entry"));
|
|
6708
6332
|
}
|
|
6709
6333
|
}
|
|
6710
|
-
console.log(
|
|
6334
|
+
console.log(pc23.bold("\n Step 3 of 3: Config check\n"));
|
|
6711
6335
|
const { findGovernConfig } = await import("@fragments-sdk/govern");
|
|
6712
6336
|
const configPath = findGovernConfig();
|
|
6713
6337
|
if (configPath) {
|
|
6714
|
-
console.log(
|
|
6338
|
+
console.log(pc23.green(` \u2713 Found govern config: ${configPath}`));
|
|
6715
6339
|
} else {
|
|
6716
6340
|
console.log(
|
|
6717
|
-
|
|
6341
|
+
pc23.yellow(" No govern config found \u2014 run `fragments govern init` to create one")
|
|
6718
6342
|
);
|
|
6719
6343
|
}
|
|
6720
|
-
console.log(
|
|
6721
|
-
console.log(
|
|
6722
|
-
console.log(
|
|
6344
|
+
console.log(pc23.dim("\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
6345
|
+
console.log(pc23.green(" \u2713 All set!") + " Run `fragments govern check` to send your first audit.\n");
|
|
6346
|
+
console.log(pc23.dim(` Dashboard: ${cloudUrl}/overview
|
|
6723
6347
|
`));
|
|
6724
6348
|
}
|
|
6725
6349
|
async function governReport() {
|
|
6726
|
-
const { readFile:
|
|
6727
|
-
console.log(
|
|
6350
|
+
const { readFile: readFile13 } = await import("fs/promises");
|
|
6351
|
+
console.log(pc23.cyan(`
|
|
6728
6352
|
${BRAND.name} Governance Report
|
|
6729
6353
|
`));
|
|
6730
6354
|
let raw;
|
|
6731
6355
|
try {
|
|
6732
|
-
raw = await
|
|
6356
|
+
raw = await readFile13(".govern-audit.jsonl", "utf-8");
|
|
6733
6357
|
} catch {
|
|
6734
|
-
console.log(
|
|
6735
|
-
console.log(
|
|
6358
|
+
console.log(pc23.yellow("No audit log found (.govern-audit.jsonl)\n"));
|
|
6359
|
+
console.log(pc23.dim("Run `fragments govern check` to generate audit data.\n"));
|
|
6736
6360
|
return;
|
|
6737
6361
|
}
|
|
6738
6362
|
const lines = raw.trim().split("\n").filter(Boolean);
|
|
6739
6363
|
if (lines.length === 0) {
|
|
6740
|
-
console.log(
|
|
6364
|
+
console.log(pc23.yellow("Audit log is empty.\n"));
|
|
6741
6365
|
return;
|
|
6742
6366
|
}
|
|
6743
6367
|
let totalScore = 0;
|
|
@@ -6762,13 +6386,13 @@ ${BRAND.name} Governance Report
|
|
|
6762
6386
|
}
|
|
6763
6387
|
|
|
6764
6388
|
// src/commands/migrate-contract.ts
|
|
6765
|
-
import
|
|
6389
|
+
import pc24 from "picocolors";
|
|
6766
6390
|
import fg4 from "fast-glob";
|
|
6767
|
-
import { resolve as
|
|
6391
|
+
import { resolve as resolve13 } from "path";
|
|
6768
6392
|
|
|
6769
6393
|
// src/migrate/fragment-to-contract.ts
|
|
6770
|
-
import { readFile as
|
|
6771
|
-
import { resolve as
|
|
6394
|
+
import { readFile as readFile12, writeFile as writeFile10 } from "fs/promises";
|
|
6395
|
+
import { resolve as resolve12, dirname as dirname5, relative as relative8 } from "path";
|
|
6772
6396
|
import { createComponentExtractor as createComponentExtractor2 } from "@fragments-sdk/extract";
|
|
6773
6397
|
import { resolveComponentSourcePath as resolveComponentSourcePath2 } from "@fragments-sdk/extract";
|
|
6774
6398
|
function compilePropsSummaryFromExtracted(props) {
|
|
@@ -6807,8 +6431,8 @@ function compilePropsSummaryFromDocs(props) {
|
|
|
6807
6431
|
}
|
|
6808
6432
|
async function migrateFragmentToContract(fragmentPath, configDir, options) {
|
|
6809
6433
|
const warnings = [];
|
|
6810
|
-
const absFragmentPath =
|
|
6811
|
-
const content = await
|
|
6434
|
+
const absFragmentPath = resolve12(fragmentPath);
|
|
6435
|
+
const content = await readFile12(absFragmentPath, "utf-8");
|
|
6812
6436
|
const parsed = parseFragmentFile(content, fragmentPath);
|
|
6813
6437
|
warnings.push(...parsed.warnings);
|
|
6814
6438
|
if (!parsed.meta.name) {
|
|
@@ -6843,7 +6467,7 @@ async function migrateFragmentToContract(fragmentPath, configDir, options) {
|
|
|
6843
6467
|
}
|
|
6844
6468
|
} else {
|
|
6845
6469
|
const fragDir = dirname5(absFragmentPath);
|
|
6846
|
-
sourcePath = relative8(configDir,
|
|
6470
|
+
sourcePath = relative8(configDir, resolve12(fragDir, "index.tsx"));
|
|
6847
6471
|
warnings.push("No component import found; assuming ./index.tsx");
|
|
6848
6472
|
}
|
|
6849
6473
|
const exportName = parsed.componentName ?? parsed.meta.name;
|
|
@@ -6946,20 +6570,20 @@ async function migrateFragmentToContract(fragmentPath, configDir, options) {
|
|
|
6946
6570
|
async function migrateContract(options) {
|
|
6947
6571
|
const { config, configDir } = await loadConfig(options.config);
|
|
6948
6572
|
const pattern = options.glob ?? "src/**/*.fragment.tsx";
|
|
6949
|
-
console.log(
|
|
6573
|
+
console.log(pc24.blue(`Migrating fragment files matching: ${pattern}`));
|
|
6950
6574
|
if (options.dryRun) {
|
|
6951
|
-
console.log(
|
|
6575
|
+
console.log(pc24.yellow("(dry run \u2014 no files will be written)"));
|
|
6952
6576
|
}
|
|
6953
6577
|
const files = await fg4(pattern, { cwd: configDir, absolute: true });
|
|
6954
6578
|
if (files.length === 0) {
|
|
6955
|
-
console.log(
|
|
6579
|
+
console.log(pc24.yellow("No fragment files found matching pattern."));
|
|
6956
6580
|
return { migrated: 0, failed: 0, warnings: 0 };
|
|
6957
6581
|
}
|
|
6958
|
-
console.log(
|
|
6582
|
+
console.log(pc24.dim(`Found ${files.length} fragment file(s)`));
|
|
6959
6583
|
let migrated = 0;
|
|
6960
6584
|
let failed = 0;
|
|
6961
6585
|
let totalWarnings = 0;
|
|
6962
|
-
const tsconfigPath = options.tsconfig ?
|
|
6586
|
+
const tsconfigPath = options.tsconfig ? resolve13(options.tsconfig) : void 0;
|
|
6963
6587
|
for (const file of files) {
|
|
6964
6588
|
try {
|
|
6965
6589
|
const result = await migrateFragmentToContract(file, configDir, {
|
|
@@ -6968,32 +6592,32 @@ async function migrateContract(options) {
|
|
|
6968
6592
|
});
|
|
6969
6593
|
migrated++;
|
|
6970
6594
|
const verb = options.dryRun ? "Would migrate" : "Migrated";
|
|
6971
|
-
console.log(
|
|
6595
|
+
console.log(pc24.green(` \u2713 ${verb}: ${result.contractPath}`));
|
|
6972
6596
|
if (result.warnings.length > 0) {
|
|
6973
6597
|
totalWarnings += result.warnings.length;
|
|
6974
6598
|
for (const w of result.warnings) {
|
|
6975
|
-
console.log(
|
|
6599
|
+
console.log(pc24.yellow(` \u26A0 ${w}`));
|
|
6976
6600
|
}
|
|
6977
6601
|
}
|
|
6978
6602
|
} catch (error) {
|
|
6979
6603
|
failed++;
|
|
6980
|
-
console.log(
|
|
6981
|
-
console.log(
|
|
6604
|
+
console.log(pc24.red(` \u2717 Failed: ${file}`));
|
|
6605
|
+
console.log(pc24.dim(` ${error instanceof Error ? error.message : String(error)}`));
|
|
6982
6606
|
}
|
|
6983
6607
|
}
|
|
6984
6608
|
console.log("");
|
|
6985
|
-
console.log(
|
|
6986
|
-
console.log(` ${
|
|
6609
|
+
console.log(pc24.bold("Migration summary:"));
|
|
6610
|
+
console.log(` ${pc24.green(`${migrated} migrated`)} ${pc24.red(`${failed} failed`)} ${pc24.yellow(`${totalWarnings} warnings`)}`);
|
|
6987
6611
|
if (!options.dryRun && migrated > 0) {
|
|
6988
6612
|
console.log("");
|
|
6989
|
-
console.log(
|
|
6613
|
+
console.log(pc24.dim("Run `fragments build` to verify migrated contracts compile correctly."));
|
|
6990
6614
|
}
|
|
6991
6615
|
return { migrated, failed, warnings: totalWarnings };
|
|
6992
6616
|
}
|
|
6993
6617
|
|
|
6994
6618
|
// src/bin.ts
|
|
6995
6619
|
var __dirname = dirname6(fileURLToPath(import.meta.url));
|
|
6996
|
-
var pkg = JSON.parse(readFileSync(
|
|
6620
|
+
var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
|
|
6997
6621
|
var EXPERIMENTAL = process.env.FRAGMENTS_EXPERIMENTAL === "1";
|
|
6998
6622
|
var program = new Command();
|
|
6999
6623
|
program.name(BRAND.cliCommand).description(`${BRAND.name} - Design system documentation and compliance tool`).version(pkg.version);
|
|
@@ -7004,7 +6628,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
|
|
|
7004
6628
|
process.exit(1);
|
|
7005
6629
|
}
|
|
7006
6630
|
} catch (error) {
|
|
7007
|
-
console.error(
|
|
6631
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7008
6632
|
process.exit(1);
|
|
7009
6633
|
}
|
|
7010
6634
|
});
|
|
@@ -7020,7 +6644,7 @@ program.command("sync").description("Auto-update fragment files from component s
|
|
|
7020
6644
|
process.exit(1);
|
|
7021
6645
|
}
|
|
7022
6646
|
} catch (error) {
|
|
7023
|
-
console.error(
|
|
6647
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7024
6648
|
process.exit(1);
|
|
7025
6649
|
}
|
|
7026
6650
|
});
|
|
@@ -7042,7 +6666,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
|
|
|
7042
6666
|
process.exit(1);
|
|
7043
6667
|
}
|
|
7044
6668
|
} catch (error) {
|
|
7045
|
-
console.error(
|
|
6669
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7046
6670
|
process.exit(1);
|
|
7047
6671
|
}
|
|
7048
6672
|
});
|
|
@@ -7061,7 +6685,7 @@ program.command("context").description("Generate AI-ready context for your desig
|
|
|
7061
6685
|
process.exit(1);
|
|
7062
6686
|
}
|
|
7063
6687
|
} catch (error) {
|
|
7064
|
-
console.error(
|
|
6688
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7065
6689
|
process.exit(1);
|
|
7066
6690
|
}
|
|
7067
6691
|
});
|
|
@@ -7088,7 +6712,7 @@ program.command("ai").description("Generate context optimized for AI assistants
|
|
|
7088
6712
|
}
|
|
7089
6713
|
}
|
|
7090
6714
|
} catch (error) {
|
|
7091
|
-
console.error(
|
|
6715
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7092
6716
|
process.exit(1);
|
|
7093
6717
|
}
|
|
7094
6718
|
});
|
|
@@ -7096,7 +6720,7 @@ program.command("list").description("List all discovered fragment files").option
|
|
|
7096
6720
|
try {
|
|
7097
6721
|
await list(options);
|
|
7098
6722
|
} catch (error) {
|
|
7099
|
-
console.error(
|
|
6723
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7100
6724
|
process.exit(1);
|
|
7101
6725
|
}
|
|
7102
6726
|
});
|
|
@@ -7104,7 +6728,7 @@ program.command("reset").description("Reset to initial state (delete all generat
|
|
|
7104
6728
|
try {
|
|
7105
6729
|
await reset(options);
|
|
7106
6730
|
} catch (error) {
|
|
7107
|
-
console.error(
|
|
6731
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7108
6732
|
process.exit(1);
|
|
7109
6733
|
}
|
|
7110
6734
|
});
|
|
@@ -7118,7 +6742,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
|
|
|
7118
6742
|
variants: options.variants
|
|
7119
6743
|
});
|
|
7120
6744
|
} catch (error) {
|
|
7121
|
-
console.error(
|
|
6745
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7122
6746
|
process.exit(1);
|
|
7123
6747
|
}
|
|
7124
6748
|
});
|
|
@@ -7133,7 +6757,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
|
|
|
7133
6757
|
exclude: options.exclude
|
|
7134
6758
|
});
|
|
7135
6759
|
} catch (error) {
|
|
7136
|
-
console.error(
|
|
6760
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7137
6761
|
process.exit(1);
|
|
7138
6762
|
}
|
|
7139
6763
|
});
|
|
@@ -7153,7 +6777,7 @@ program.command("screenshot").description("Capture screenshots of component vari
|
|
|
7153
6777
|
process.exit(1);
|
|
7154
6778
|
}
|
|
7155
6779
|
} catch (error) {
|
|
7156
|
-
console.error(
|
|
6780
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7157
6781
|
process.exit(1);
|
|
7158
6782
|
}
|
|
7159
6783
|
});
|
|
@@ -7172,7 +6796,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
|
|
|
7172
6796
|
process.exit(1);
|
|
7173
6797
|
}
|
|
7174
6798
|
} catch (error) {
|
|
7175
|
-
console.error(
|
|
6799
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7176
6800
|
process.exit(1);
|
|
7177
6801
|
}
|
|
7178
6802
|
});
|
|
@@ -7191,8 +6815,8 @@ program.command("compare").argument("[component]", "Component name to compare").
|
|
|
7191
6815
|
process.exit(1);
|
|
7192
6816
|
}
|
|
7193
6817
|
} catch (error) {
|
|
7194
|
-
console.error(
|
|
7195
|
-
console.log(
|
|
6818
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
6819
|
+
console.log(pc25.dim(`
|
|
7196
6820
|
Make sure a dev server is running on the expected port.`));
|
|
7197
6821
|
process.exit(1);
|
|
7198
6822
|
}
|
|
@@ -7211,7 +6835,7 @@ program.command("analyze").description("Analyze design system and generate repor
|
|
|
7211
6835
|
process.exit(1);
|
|
7212
6836
|
}
|
|
7213
6837
|
} catch (error) {
|
|
7214
|
-
console.error(
|
|
6838
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7215
6839
|
process.exit(1);
|
|
7216
6840
|
}
|
|
7217
6841
|
});
|
|
@@ -7230,7 +6854,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
|
|
|
7230
6854
|
if (options.ci) {
|
|
7231
6855
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
|
|
7232
6856
|
} else {
|
|
7233
|
-
console.error(
|
|
6857
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7234
6858
|
}
|
|
7235
6859
|
process.exit(1);
|
|
7236
6860
|
}
|
|
@@ -7247,7 +6871,7 @@ program.command("audit").description("Scan all fragments and show compliance met
|
|
|
7247
6871
|
if (options.json) {
|
|
7248
6872
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
|
|
7249
6873
|
} else {
|
|
7250
|
-
console.error(
|
|
6874
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7251
6875
|
}
|
|
7252
6876
|
process.exit(1);
|
|
7253
6877
|
}
|
|
@@ -7269,7 +6893,7 @@ program.command("a11y").description("Run accessibility checks on all component v
|
|
|
7269
6893
|
if (options.json) {
|
|
7270
6894
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
|
|
7271
6895
|
} else {
|
|
7272
|
-
console.error(
|
|
6896
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7273
6897
|
}
|
|
7274
6898
|
process.exit(1);
|
|
7275
6899
|
}
|
|
@@ -7292,7 +6916,7 @@ program.command("enhance").description("AI-powered documentation generation from
|
|
|
7292
6916
|
if (options.format === "json") {
|
|
7293
6917
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
|
|
7294
6918
|
} else {
|
|
7295
|
-
console.error(
|
|
6919
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7296
6920
|
}
|
|
7297
6921
|
process.exit(1);
|
|
7298
6922
|
}
|
|
@@ -7313,7 +6937,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
|
|
|
7313
6937
|
process.exit(1);
|
|
7314
6938
|
}
|
|
7315
6939
|
} catch (error) {
|
|
7316
|
-
console.error(
|
|
6940
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7317
6941
|
process.exit(1);
|
|
7318
6942
|
}
|
|
7319
6943
|
});
|
|
@@ -7329,7 +6953,7 @@ program.command("migrate-contract").description("Migrate .fragment.tsx files to
|
|
|
7329
6953
|
process.exit(1);
|
|
7330
6954
|
}
|
|
7331
6955
|
} catch (error) {
|
|
7332
|
-
console.error(
|
|
6956
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7333
6957
|
process.exit(1);
|
|
7334
6958
|
}
|
|
7335
6959
|
});
|
|
@@ -7342,7 +6966,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
|
|
|
7342
6966
|
format: options.format
|
|
7343
6967
|
});
|
|
7344
6968
|
} catch (error) {
|
|
7345
|
-
console.error(
|
|
6969
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7346
6970
|
process.exit(1);
|
|
7347
6971
|
}
|
|
7348
6972
|
});
|
|
@@ -7354,7 +6978,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
|
|
|
7354
6978
|
json: options.json
|
|
7355
6979
|
});
|
|
7356
6980
|
} catch (error) {
|
|
7357
|
-
console.error(
|
|
6981
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7358
6982
|
process.exit(1);
|
|
7359
6983
|
}
|
|
7360
6984
|
});
|
|
@@ -7368,9 +6992,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
|
|
|
7368
6992
|
port: options.port
|
|
7369
6993
|
});
|
|
7370
6994
|
} catch (error) {
|
|
7371
|
-
console.error(
|
|
6995
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7372
6996
|
if (action === "update") {
|
|
7373
|
-
console.log(
|
|
6997
|
+
console.log(pc25.dim(`
|
|
7374
6998
|
Make sure a dev server is running on the expected port.`));
|
|
7375
6999
|
}
|
|
7376
7000
|
process.exit(1);
|
|
@@ -7383,22 +7007,22 @@ program.command("view").description(`Generate a static HTML viewer for ${BRAND.o
|
|
|
7383
7007
|
const path = await import("path");
|
|
7384
7008
|
const inputPath = path.resolve(process.cwd(), options.input);
|
|
7385
7009
|
const outputPath = path.resolve(process.cwd(), options.output);
|
|
7386
|
-
console.log(
|
|
7010
|
+
console.log(pc25.cyan(`
|
|
7387
7011
|
${BRAND.name} Viewer Generator
|
|
7388
7012
|
`));
|
|
7389
7013
|
try {
|
|
7390
7014
|
await fs2.access(inputPath);
|
|
7391
7015
|
} catch {
|
|
7392
|
-
console.log(
|
|
7393
|
-
console.log(
|
|
7394
|
-
Run ${
|
|
7016
|
+
console.log(pc25.red(`Error: ${options.input} not found.`));
|
|
7017
|
+
console.log(pc25.dim(`
|
|
7018
|
+
Run ${pc25.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
7395
7019
|
`));
|
|
7396
7020
|
process.exit(1);
|
|
7397
7021
|
}
|
|
7398
|
-
console.log(
|
|
7022
|
+
console.log(pc25.dim(`Reading: ${options.input}`));
|
|
7399
7023
|
const html = await generateViewerFromJson(inputPath);
|
|
7400
7024
|
await fs2.writeFile(outputPath, html);
|
|
7401
|
-
console.log(
|
|
7025
|
+
console.log(pc25.green(`
|
|
7402
7026
|
\u2713 Generated: ${options.output}
|
|
7403
7027
|
`));
|
|
7404
7028
|
if (options.open) {
|
|
@@ -7407,7 +7031,7 @@ Run ${pc26.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
|
7407
7031
|
exec(`${openCmd} "${outputPath}"`);
|
|
7408
7032
|
}
|
|
7409
7033
|
} catch (error) {
|
|
7410
|
-
console.error(
|
|
7034
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7411
7035
|
process.exit(1);
|
|
7412
7036
|
}
|
|
7413
7037
|
});
|
|
@@ -7420,13 +7044,13 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
|
|
|
7420
7044
|
component: options.component
|
|
7421
7045
|
});
|
|
7422
7046
|
} catch (error) {
|
|
7423
|
-
console.error(
|
|
7047
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7424
7048
|
process.exit(1);
|
|
7425
7049
|
}
|
|
7426
7050
|
});
|
|
7427
7051
|
program.command("create").argument("[name]", "Project name").description("Create a new project with Fragments UI and your custom theme").option("-t, --template <template>", "Framework template (nextjs, vite)", "nextjs").option("--pm <manager>", "Package manager (npm, pnpm, yarn, bun)").option("--theme <encoded>", "Encoded theme string").option("--preset <id>", "Theme preset ID from usefragments.com/create").option("--brand <color>", "Brand color hex (e.g., #6366f1)").option("--scss", "Use SCSS output (installs sass)").option("--mcp", "Configure MCP server for AI tooling").option("-y, --yes", "Skip interactive prompts").option("--no-git", "Skip git initialization").action(async (name, options) => {
|
|
7428
7052
|
try {
|
|
7429
|
-
const { create } = await import("./create-
|
|
7053
|
+
const { create } = await import("./create-JVAU3YKN.js");
|
|
7430
7054
|
const result = await create({
|
|
7431
7055
|
name,
|
|
7432
7056
|
template: options.template,
|
|
@@ -7440,11 +7064,11 @@ program.command("create").argument("[name]", "Project name").description("Create
|
|
|
7440
7064
|
noGit: !options.git
|
|
7441
7065
|
});
|
|
7442
7066
|
if (!result.success) {
|
|
7443
|
-
if (result.error) console.error(
|
|
7067
|
+
if (result.error) console.error(pc25.red(`Error: ${result.error}`));
|
|
7444
7068
|
process.exit(1);
|
|
7445
7069
|
}
|
|
7446
7070
|
} catch (error) {
|
|
7447
|
-
console.error(
|
|
7071
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7448
7072
|
process.exit(1);
|
|
7449
7073
|
}
|
|
7450
7074
|
});
|
|
@@ -7461,7 +7085,7 @@ program.command("setup").description("Configure @fragments-sdk/ui in a consumer
|
|
|
7461
7085
|
process.exit(1);
|
|
7462
7086
|
}
|
|
7463
7087
|
} catch (error) {
|
|
7464
|
-
console.error(
|
|
7088
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7465
7089
|
process.exit(1);
|
|
7466
7090
|
}
|
|
7467
7091
|
});
|
|
@@ -7473,9 +7097,9 @@ initCmd.action(async (options) => {
|
|
|
7473
7097
|
try {
|
|
7474
7098
|
if (options.cloud) {
|
|
7475
7099
|
if (!EXPERIMENTAL) {
|
|
7476
|
-
console.log(
|
|
7100
|
+
console.log(pc25.yellow(`
|
|
7477
7101
|
Fragments Cloud is not yet publicly available.`));
|
|
7478
|
-
console.log(
|
|
7102
|
+
console.log(pc25.dim(` Set FRAGMENTS_EXPERIMENTAL=1 to enable preview features.
|
|
7479
7103
|
`));
|
|
7480
7104
|
process.exit(1);
|
|
7481
7105
|
}
|
|
@@ -7504,14 +7128,14 @@ initCmd.action(async (options) => {
|
|
|
7504
7128
|
govern: options.govern
|
|
7505
7129
|
});
|
|
7506
7130
|
if (!result.success) {
|
|
7507
|
-
console.error(
|
|
7131
|
+
console.error(pc25.red("\nInit failed with errors:"));
|
|
7508
7132
|
for (const error of result.errors) {
|
|
7509
|
-
console.error(
|
|
7133
|
+
console.error(pc25.red(` - ${error}`));
|
|
7510
7134
|
}
|
|
7511
7135
|
process.exit(1);
|
|
7512
7136
|
}
|
|
7513
7137
|
} catch (error) {
|
|
7514
|
-
console.error(
|
|
7138
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7515
7139
|
process.exit(1);
|
|
7516
7140
|
}
|
|
7517
7141
|
});
|
|
@@ -7529,7 +7153,7 @@ program.command("snapshot").description("Run visual snapshot tests per component
|
|
|
7529
7153
|
process.exit(1);
|
|
7530
7154
|
}
|
|
7531
7155
|
} catch (error) {
|
|
7532
|
-
console.error(
|
|
7156
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7533
7157
|
process.exit(1);
|
|
7534
7158
|
}
|
|
7535
7159
|
});
|
|
@@ -7549,7 +7173,7 @@ tokensCmd.command("list", { isDefault: true }).description("Discover and list de
|
|
|
7549
7173
|
process.exit(1);
|
|
7550
7174
|
}
|
|
7551
7175
|
} catch (error) {
|
|
7552
|
-
console.error(
|
|
7176
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7553
7177
|
process.exit(1);
|
|
7554
7178
|
}
|
|
7555
7179
|
});
|
|
@@ -7565,7 +7189,7 @@ tokensCmd.command("generate").description("Generate CSS, SCSS, Tailwind, or Figm
|
|
|
7565
7189
|
verbose: options.verbose
|
|
7566
7190
|
});
|
|
7567
7191
|
} catch (error) {
|
|
7568
|
-
console.error(
|
|
7192
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7569
7193
|
process.exit(1);
|
|
7570
7194
|
}
|
|
7571
7195
|
});
|
|
@@ -7579,7 +7203,7 @@ tokensCmd.command("push").description("Push code tokens to Fragments Cloud for d
|
|
|
7579
7203
|
verbose: options.verbose
|
|
7580
7204
|
});
|
|
7581
7205
|
} catch (error) {
|
|
7582
|
-
console.error(
|
|
7206
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7583
7207
|
process.exit(1);
|
|
7584
7208
|
}
|
|
7585
7209
|
});
|
|
@@ -7593,11 +7217,11 @@ program.command("generate").description("Generate fragment files from component
|
|
|
7593
7217
|
componentPattern: options.pattern
|
|
7594
7218
|
});
|
|
7595
7219
|
if (!result.success) {
|
|
7596
|
-
console.error(
|
|
7220
|
+
console.error(pc25.red("\nGenerate completed with errors"));
|
|
7597
7221
|
process.exit(1);
|
|
7598
7222
|
}
|
|
7599
7223
|
} catch (error) {
|
|
7600
|
-
console.error(
|
|
7224
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7601
7225
|
process.exit(1);
|
|
7602
7226
|
}
|
|
7603
7227
|
});
|
|
@@ -7605,7 +7229,7 @@ program.command("graph").description("Query the component relationship graph").a
|
|
|
7605
7229
|
try {
|
|
7606
7230
|
await graph(component, options);
|
|
7607
7231
|
} catch (error) {
|
|
7608
|
-
console.error(
|
|
7232
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7609
7233
|
process.exit(1);
|
|
7610
7234
|
}
|
|
7611
7235
|
});
|
|
@@ -7623,7 +7247,7 @@ program.command("inspect").description("Inspect a single component from compiled
|
|
|
7623
7247
|
if (options.json) {
|
|
7624
7248
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Inspect failed" }));
|
|
7625
7249
|
} else {
|
|
7626
|
-
console.error(
|
|
7250
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7627
7251
|
}
|
|
7628
7252
|
process.exit(1);
|
|
7629
7253
|
}
|
|
@@ -7642,7 +7266,7 @@ program.command("discover").description("List and filter components from compile
|
|
|
7642
7266
|
if (options.json) {
|
|
7643
7267
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Discover failed" }));
|
|
7644
7268
|
} else {
|
|
7645
|
-
console.error(
|
|
7269
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7646
7270
|
}
|
|
7647
7271
|
process.exit(1);
|
|
7648
7272
|
}
|
|
@@ -7661,7 +7285,7 @@ program.command("perf").description("Profile component bundle sizes and performa
|
|
|
7661
7285
|
process.exit(1);
|
|
7662
7286
|
}
|
|
7663
7287
|
} catch (error) {
|
|
7664
|
-
console.error(
|
|
7288
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7665
7289
|
process.exit(1);
|
|
7666
7290
|
}
|
|
7667
7291
|
});
|
|
@@ -7701,12 +7325,13 @@ program.command("test").description("Run interaction tests for fragments with pl
|
|
|
7701
7325
|
});
|
|
7702
7326
|
process.exit(exitCode);
|
|
7703
7327
|
} catch (error) {
|
|
7704
|
-
console.error(
|
|
7328
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7705
7329
|
process.exit(1);
|
|
7706
7330
|
}
|
|
7707
7331
|
});
|
|
7708
7332
|
program.command("doctor").description("Diagnose design system configuration issues").option("--root <dir>", "Project root directory", process.cwd()).option("--json", "Output results as JSON").option("--fix", "Auto-fix issues where possible").action(async (options) => {
|
|
7709
7333
|
try {
|
|
7334
|
+
const { doctor } = await import("./doctor-BDPMYYE6.js");
|
|
7710
7335
|
const result = await doctor({
|
|
7711
7336
|
root: options.root,
|
|
7712
7337
|
json: options.json,
|
|
@@ -7716,15 +7341,15 @@ program.command("doctor").description("Diagnose design system configuration issu
|
|
|
7716
7341
|
process.exit(1);
|
|
7717
7342
|
}
|
|
7718
7343
|
} catch (error) {
|
|
7719
|
-
console.error(
|
|
7344
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7720
7345
|
process.exit(1);
|
|
7721
7346
|
}
|
|
7722
7347
|
});
|
|
7723
7348
|
var governCmd = program.command("govern").description(EXPERIMENTAL ? "AI UI governance checks" : "AI UI governance checks (preview \u2014 set FRAGMENTS_EXPERIMENTAL=1)").hook("preAction", () => {
|
|
7724
7349
|
if (!EXPERIMENTAL) {
|
|
7725
|
-
console.log(
|
|
7350
|
+
console.log(pc25.yellow(`
|
|
7726
7351
|
Fragments governance is not yet publicly available.`));
|
|
7727
|
-
console.log(
|
|
7352
|
+
console.log(pc25.dim(` Set FRAGMENTS_EXPERIMENTAL=1 to enable preview features.
|
|
7728
7353
|
`));
|
|
7729
7354
|
process.exit(1);
|
|
7730
7355
|
}
|
|
@@ -7739,7 +7364,7 @@ governCmd.command("check").description("Validate a UISpec against governance pol
|
|
|
7739
7364
|
});
|
|
7740
7365
|
process.exit(exitCode);
|
|
7741
7366
|
} catch (error) {
|
|
7742
|
-
console.error(
|
|
7367
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7743
7368
|
process.exit(1);
|
|
7744
7369
|
}
|
|
7745
7370
|
});
|
|
@@ -7747,7 +7372,7 @@ governCmd.command("init").description("Generate a fragments.config.ts with gover
|
|
|
7747
7372
|
try {
|
|
7748
7373
|
await governInit({ output: options.output });
|
|
7749
7374
|
} catch (error) {
|
|
7750
|
-
console.error(
|
|
7375
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7751
7376
|
process.exit(1);
|
|
7752
7377
|
}
|
|
7753
7378
|
});
|
|
@@ -7755,7 +7380,7 @@ governCmd.command("report").description("Summarize governance audit log").action
|
|
|
7755
7380
|
try {
|
|
7756
7381
|
await governReport();
|
|
7757
7382
|
} catch (error) {
|
|
7758
|
-
console.error(
|
|
7383
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7759
7384
|
process.exit(1);
|
|
7760
7385
|
}
|
|
7761
7386
|
});
|
|
@@ -7763,7 +7388,7 @@ governCmd.command("connect").description("Connect your project to the Fragments
|
|
|
7763
7388
|
try {
|
|
7764
7389
|
await governConnect();
|
|
7765
7390
|
} catch (error) {
|
|
7766
|
-
console.error(
|
|
7391
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7767
7392
|
process.exit(1);
|
|
7768
7393
|
}
|
|
7769
7394
|
});
|
|
@@ -7778,7 +7403,7 @@ governCmd.command("scan").description("Scan JSX/TSX codebase for governance viol
|
|
|
7778
7403
|
});
|
|
7779
7404
|
process.exit(exitCode);
|
|
7780
7405
|
} catch (error) {
|
|
7781
|
-
console.error(
|
|
7406
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7782
7407
|
process.exit(1);
|
|
7783
7408
|
}
|
|
7784
7409
|
});
|
|
@@ -7792,7 +7417,7 @@ governCmd.command("watch").description("Watch JSX/TSX files and re-check on chan
|
|
|
7792
7417
|
debounce: parseInt(options.debounce, 10)
|
|
7793
7418
|
});
|
|
7794
7419
|
} catch (error) {
|
|
7795
|
-
console.error(
|
|
7420
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7796
7421
|
process.exit(1);
|
|
7797
7422
|
}
|
|
7798
7423
|
});
|
|
@@ -7807,7 +7432,7 @@ governCmd.command("push-contracts").description("Push component contracts to Fra
|
|
|
7807
7432
|
});
|
|
7808
7433
|
process.exit(exitCode);
|
|
7809
7434
|
} catch (error) {
|
|
7810
|
-
console.error(
|
|
7435
|
+
console.error(pc25.red("Error:"), error instanceof Error ? error.message : error);
|
|
7811
7436
|
process.exit(1);
|
|
7812
7437
|
}
|
|
7813
7438
|
});
|