@fragments-sdk/cli 0.8.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +517 -77
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-WI6SLMSO.js → chunk-5GT62FCB.js} +2 -2
- package/dist/{chunk-CJEGT3WD.js → chunk-BW3ZATBW.js} +20 -3
- package/dist/chunk-BW3ZATBW.js.map +1 -0
- package/dist/{chunk-2JIKCJX3.js → chunk-D7372LQX.js} +13 -6
- package/dist/chunk-D7372LQX.js.map +1 -0
- package/dist/chunk-EZYXYWNF.js +131 -0
- package/dist/chunk-EZYXYWNF.js.map +1 -0
- package/dist/{chunk-NGIMCIK2.js → chunk-GF6OVPIN.js} +2 -2
- package/dist/{chunk-GOVI6COW.js → chunk-NVSPGSKB.js} +12 -4
- package/dist/chunk-NVSPGSKB.js.map +1 -0
- package/dist/core/index.d.ts +105 -3
- package/dist/core/index.js +12 -2
- package/dist/{defineFragment-D0UTve-I.d.ts → defineFragment-CBMS7Bab.d.ts} +21 -1
- package/dist/generate-LQA2R7FN.js +461 -0
- package/dist/generate-LQA2R7FN.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/{init-KFYN37ZY.js → init-2GEGVIUQ.js} +14 -76
- package/dist/init-2GEGVIUQ.js.map +1 -0
- package/dist/mcp-bin.js +4 -3
- package/dist/mcp-bin.js.map +1 -1
- package/dist/{scan-65RH3QMM.js → scan-JGS65S7P.js} +6 -5
- package/dist/{service-A5GIGGGK.js → service-XP2EAJXD.js} +4 -3
- package/dist/{static-viewer-NSODM5VX.js → static-viewer-XCS7UJTO.js} +4 -3
- package/dist/storyFilters-3LUYAFZF.js +15 -0
- package/dist/storyFilters-3LUYAFZF.js.map +1 -0
- package/dist/{test-RPWZAYSJ.js → test-TD6TJNVY.js} +3 -3
- package/dist/{tokens-NIXSZRX7.js → tokens-2EXPCVP3.js} +5 -4
- package/dist/{tokens-NIXSZRX7.js.map → tokens-2EXPCVP3.js.map} +1 -1
- package/dist/{viewer-HZK4BSDK.js → viewer-RFA2KVBG.js} +249 -22
- package/dist/viewer-RFA2KVBG.js.map +1 -0
- package/package.json +2 -2
- package/src/bin.ts +26 -0
- package/src/build.ts +12 -2
- package/src/commands/build.ts +16 -2
- package/src/commands/doctor.ts +498 -0
- package/src/commands/generate.ts +383 -68
- package/src/commands/init-framework.ts +1 -1
- package/src/commands/init.ts +9 -51
- package/src/core/config.ts +15 -2
- package/src/core/generators/typescript-extractor.ts +10 -0
- package/src/core/index.ts +15 -0
- package/src/core/schema.ts +10 -2
- package/src/core/storyFilters.test.ts +350 -0
- package/src/core/storyFilters.ts +253 -0
- package/src/core/types.ts +22 -0
- package/src/migrate/converter.ts +9 -1
- package/src/migrate/parser.ts +2 -0
- package/src/migrate/types.ts +2 -0
- package/src/setup.ts +69 -24
- package/src/viewer/__tests__/viewer-integration.test.ts +1 -1
- package/src/viewer/components/AccessibilityPanel.tsx +305 -312
- package/src/viewer/components/ActionsPanel.tsx +31 -29
- package/src/viewer/components/AllVariantsPreview.tsx +78 -0
- package/src/viewer/components/App.tsx +187 -740
- package/src/viewer/components/BottomPanel.tsx +228 -132
- package/src/viewer/components/CodePanel.tsx +1 -1
- package/src/viewer/components/CommandPalette.tsx +7 -10
- package/src/viewer/components/ComponentDocView.tsx +164 -0
- package/src/viewer/components/ComponentGraph.tsx +111 -142
- package/src/viewer/components/ContractPanel.tsx +6 -6
- package/src/viewer/components/EmptyVariantMessage.tsx +54 -0
- package/src/viewer/components/FigmaEmbed.tsx +20 -18
- package/src/viewer/components/FragmentEditor.tsx +92 -115
- package/src/viewer/components/HeaderSearch.tsx +24 -0
- package/src/viewer/components/HealthDashboard.tsx +16 -2
- package/src/viewer/components/Icons.tsx +9 -0
- package/src/viewer/components/InteractionsPanel.tsx +101 -117
- package/src/viewer/components/IsolatedPreviewFrame.tsx +1 -0
- package/src/viewer/components/LandingPage.tsx +3 -3
- package/src/viewer/components/LeftSidebar.tsx +141 -63
- package/src/viewer/components/LoadErrorMessage.tsx +102 -0
- package/src/viewer/components/MultiViewportPreview.tsx +61 -142
- package/src/viewer/components/NoVariantsMessage.tsx +59 -0
- package/src/viewer/components/PanelShell.tsx +161 -0
- package/src/viewer/components/PerformancePanel.tsx +31 -28
- package/src/viewer/components/PreviewArea.tsx +1 -1
- package/src/viewer/components/PreviewAside.tsx +168 -0
- package/src/viewer/components/PreviewFrameHost.tsx +3 -3
- package/src/viewer/components/PropsEditor.tsx +70 -156
- package/src/viewer/components/ResizablePanel.tsx +103 -263
- package/src/viewer/components/RightSidebar.tsx +3 -9
- package/src/viewer/components/SkeletonLoader.tsx +13 -13
- package/src/viewer/components/TokenStylePanel.tsx +182 -209
- package/src/viewer/components/TopToolbar.tsx +159 -0
- package/src/viewer/components/VariantMatrix.tsx +42 -86
- package/src/viewer/components/VariantTabs.tsx +3 -3
- package/src/viewer/components/ViewerHeader.tsx +69 -0
- package/src/viewer/components/WebMCPDevTools.tsx +17 -23
- package/src/viewer/components/viewer-utils.ts +16 -0
- package/src/viewer/entry.tsx +5 -0
- package/src/viewer/hooks/useAppState.ts +27 -4
- package/src/viewer/hooks/usePreviewBridge.ts +2 -2
- package/src/viewer/preview-frame.html +6 -12
- package/src/viewer/server.ts +184 -6
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +10 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +274 -0
- package/src/viewer/vendor/shared/src/DocsPageShell.tsx +5 -0
- package/src/viewer/vendor/shared/src/PropsTable.module.scss +68 -0
- package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/PropsTable.tsx +76 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +122 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +134 -0
- package/src/viewer/vendor/shared/src/docs-data/index.ts +32 -0
- package/src/viewer/vendor/shared/src/docs-data/mcp-configs.ts +72 -0
- package/src/viewer/vendor/shared/src/docs-data/palettes.ts +75 -0
- package/src/viewer/vendor/shared/src/docs-data/setup-examples.ts +55 -0
- package/src/viewer/vendor/shared/src/index.ts +8 -0
- package/src/viewer/vendor/shared/src/types.ts +12 -0
- package/src/viewer/vite-plugin.ts +109 -4
- package/dist/chunk-2JIKCJX3.js.map +0 -1
- package/dist/chunk-CJEGT3WD.js.map +0 -1
- package/dist/chunk-GOVI6COW.js.map +0 -1
- package/dist/generate-35OIMW4Y.js +0 -252
- package/dist/generate-35OIMW4Y.js.map +0 -1
- package/dist/init-KFYN37ZY.js.map +0 -1
- package/dist/viewer-HZK4BSDK.js.map +0 -1
- /package/dist/{chunk-WI6SLMSO.js.map → chunk-5GT62FCB.js.map} +0 -0
- /package/dist/{chunk-NGIMCIK2.js.map → chunk-GF6OVPIN.js.map} +0 -0
- /package/dist/{scan-65RH3QMM.js.map → scan-JGS65S7P.js.map} +0 -0
- /package/dist/{service-A5GIGGGK.js.map → service-XP2EAJXD.js.map} +0 -0
- /package/dist/{static-viewer-NSODM5VX.js.map → static-viewer-XCS7UJTO.js.map} +0 -0
- /package/dist/{test-RPWZAYSJ.js.map → test-TD6TJNVY.js.map} +0 -0
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
|
|
3
|
+
import {
|
|
4
|
+
scan
|
|
5
|
+
} from "./chunk-5GT62FCB.js";
|
|
3
6
|
import {
|
|
4
7
|
buildFragments,
|
|
5
8
|
buildFragmentsDir,
|
|
@@ -12,14 +15,11 @@ import {
|
|
|
12
15
|
validateCoverage,
|
|
13
16
|
validateSchema,
|
|
14
17
|
validateSnippets
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
scan
|
|
18
|
-
} from "./chunk-WI6SLMSO.js";
|
|
18
|
+
} from "./chunk-D7372LQX.js";
|
|
19
19
|
import {
|
|
20
20
|
loadConfig,
|
|
21
21
|
loadFragmentFile
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-BW3ZATBW.js";
|
|
23
23
|
import {
|
|
24
24
|
discoverFragmentFiles
|
|
25
25
|
} from "./chunk-AWYCDRPG.js";
|
|
@@ -44,8 +44,9 @@ import {
|
|
|
44
44
|
formatBytes,
|
|
45
45
|
generateContext,
|
|
46
46
|
resolvePerformanceConfig
|
|
47
|
-
} from "./chunk-
|
|
48
|
-
import "./chunk-
|
|
47
|
+
} from "./chunk-GF6OVPIN.js";
|
|
48
|
+
import "./chunk-NVSPGSKB.js";
|
|
49
|
+
import "./chunk-EZYXYWNF.js";
|
|
49
50
|
import {
|
|
50
51
|
BRAND
|
|
51
52
|
} from "./chunk-EKLMXTWU.js";
|
|
@@ -53,10 +54,10 @@ import "./chunk-Z7EY4VHE.js";
|
|
|
53
54
|
|
|
54
55
|
// src/bin.ts
|
|
55
56
|
import { Command } from "commander";
|
|
56
|
-
import
|
|
57
|
+
import pc23 from "picocolors";
|
|
57
58
|
import { readFileSync } from "fs";
|
|
58
59
|
import { fileURLToPath } from "url";
|
|
59
|
-
import { dirname as dirname4, join as
|
|
60
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
60
61
|
|
|
61
62
|
// src/commands/validate.ts
|
|
62
63
|
import pc from "picocolors";
|
|
@@ -176,9 +177,20 @@ ${BRAND.name} Build
|
|
|
176
177
|
}
|
|
177
178
|
fragmentCount = result.fragmentCount;
|
|
178
179
|
outputPath = result.outputPath;
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
if (result.fragmentCount === 0 && result.errors.length === 0) {
|
|
181
|
+
console.log(pc2.dim("No compilable fragment files found. Falling back to source scan...\n"));
|
|
182
|
+
const scanResult = await scan({
|
|
183
|
+
config: options.config,
|
|
184
|
+
output: options.output,
|
|
185
|
+
verbose: options.verbose
|
|
186
|
+
});
|
|
187
|
+
fragmentCount = scanResult.componentCount;
|
|
188
|
+
outputPath = scanResult.outputPath;
|
|
189
|
+
} else {
|
|
190
|
+
console.log(pc2.green(`\u2713 Built ${result.fragmentCount} fragment(s)`));
|
|
191
|
+
console.log(pc2.dim(` Output: ${result.outputPath}
|
|
181
192
|
`));
|
|
193
|
+
}
|
|
182
194
|
}
|
|
183
195
|
if (options.registry || options.registryOnly) {
|
|
184
196
|
console.log(pc2.dim("Generating registry and context...\n"));
|
|
@@ -602,6 +614,7 @@ function parseMeta(content, filePath, warnings) {
|
|
|
602
614
|
);
|
|
603
615
|
if (importMatch) {
|
|
604
616
|
result.componentImport = importMatch[1];
|
|
617
|
+
result.isDefaultImport = false;
|
|
605
618
|
} else {
|
|
606
619
|
const defaultImportMatch = content.match(
|
|
607
620
|
new RegExp(
|
|
@@ -610,6 +623,7 @@ function parseMeta(content, filePath, warnings) {
|
|
|
610
623
|
);
|
|
611
624
|
if (defaultImportMatch) {
|
|
612
625
|
result.componentImport = defaultImportMatch[1];
|
|
626
|
+
result.isDefaultImport = true;
|
|
613
627
|
}
|
|
614
628
|
}
|
|
615
629
|
}
|
|
@@ -1199,6 +1213,7 @@ function convertToFragment(parsed) {
|
|
|
1199
1213
|
const code = generateFragmentCode({
|
|
1200
1214
|
componentName,
|
|
1201
1215
|
componentImport: parsed.meta.componentImport,
|
|
1216
|
+
isDefaultImport: parsed.meta.isDefaultImport,
|
|
1202
1217
|
description: parsed.meta.description,
|
|
1203
1218
|
category,
|
|
1204
1219
|
tags: parsed.meta.tags,
|
|
@@ -1434,6 +1449,7 @@ function generateFragmentCode(options) {
|
|
|
1434
1449
|
const {
|
|
1435
1450
|
componentName,
|
|
1436
1451
|
componentImport,
|
|
1452
|
+
isDefaultImport,
|
|
1437
1453
|
description,
|
|
1438
1454
|
category,
|
|
1439
1455
|
tags,
|
|
@@ -1461,8 +1477,9 @@ ${generated.skippedVariants.map((sv) => ` { name: "${escapeString(sv.name)}
|
|
|
1461
1477
|
},
|
|
1462
1478
|
`;
|
|
1463
1479
|
}
|
|
1480
|
+
const componentImportStatement = isDefaultImport ? `import ${componentName} from "${componentImport}";` : `import { ${componentName} } from "${componentImport}";`;
|
|
1464
1481
|
return `import { defineFragment } from "@fragments-sdk/cli/core";
|
|
1465
|
-
|
|
1482
|
+
${componentImportStatement}
|
|
1466
1483
|
|
|
1467
1484
|
export default defineFragment({
|
|
1468
1485
|
component: ${componentName},
|
|
@@ -1717,27 +1734,48 @@ async function runSetup(options = {}) {
|
|
|
1717
1734
|
const sbConfig = await detectStorybookConfig(configDir);
|
|
1718
1735
|
if (sbConfig) {
|
|
1719
1736
|
log(pc6.dim(` Found Storybook at ${sbConfig.configPath}`));
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1737
|
+
const hasStoryPatterns = config.include.some((p) => p.includes(".stories."));
|
|
1738
|
+
if (hasStoryPatterns) {
|
|
1739
|
+
log(pc6.dim(" Stories included in config \u2014 viewer will load them directly\n"));
|
|
1740
|
+
fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
1741
|
+
if (fragmentFiles.length > 0) {
|
|
1742
|
+
log(pc6.green(` Found ${fragmentFiles.length} story/fragment file(s)`));
|
|
1743
|
+
}
|
|
1744
|
+
} else {
|
|
1745
|
+
log(pc6.dim(" Converting stories to fragments...\n"));
|
|
1746
|
+
const storyFiles = await discoverStoryFiles(configDir, sbConfig.storyPatterns);
|
|
1747
|
+
if (storyFiles.length > 0) {
|
|
1748
|
+
let converted = 0;
|
|
1749
|
+
for (const storyFile of storyFiles) {
|
|
1750
|
+
try {
|
|
1751
|
+
const parsed = await parseStoryFile(storyFile);
|
|
1752
|
+
const fragmentResult = convertToFragment(parsed);
|
|
1753
|
+
await fs2.mkdir(path.dirname(fragmentResult.outputFile), { recursive: true });
|
|
1754
|
+
await fs2.writeFile(fragmentResult.outputFile, fragmentResult.code);
|
|
1755
|
+
converted++;
|
|
1756
|
+
} catch {
|
|
1757
|
+
}
|
|
1732
1758
|
}
|
|
1759
|
+
result.fragmentFilesCreated = converted;
|
|
1760
|
+
log(pc6.green(` Generated ${converted} fragment file(s)`));
|
|
1761
|
+
fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
1733
1762
|
}
|
|
1734
|
-
result.fragmentFilesCreated = converted;
|
|
1735
|
-
log(pc6.green(` Generated ${converted} fragment file(s)`));
|
|
1736
|
-
fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
1737
1763
|
}
|
|
1738
1764
|
} else {
|
|
1739
1765
|
log(pc6.dim(" No Storybook config found"));
|
|
1740
|
-
log(pc6.dim(
|
|
1766
|
+
log(pc6.dim(" Auto-scanning source code...\n"));
|
|
1767
|
+
try {
|
|
1768
|
+
const scanResult = await scan({
|
|
1769
|
+
config: options.configPath,
|
|
1770
|
+
verbose: false
|
|
1771
|
+
});
|
|
1772
|
+
if (scanResult.componentCount > 0) {
|
|
1773
|
+
result.fragmentsBuilt = scanResult.componentCount;
|
|
1774
|
+
log(pc6.green(` Scanned ${scanResult.componentCount} component(s) from source`));
|
|
1775
|
+
}
|
|
1776
|
+
} catch {
|
|
1777
|
+
log(pc6.dim(` Run ${pc6.cyan(`${BRAND.cliCommand} scan`)} to generate documentation from source`));
|
|
1778
|
+
}
|
|
1741
1779
|
}
|
|
1742
1780
|
} else if (fragmentFiles.length > 0) {
|
|
1743
1781
|
log(pc6.green(` Found ${fragmentFiles.length} fragment file(s)`));
|
|
@@ -1757,7 +1795,19 @@ ${reason} ${BRAND.outFile}...`));
|
|
|
1757
1795
|
result.errors.push(`${err.file}: ${err.error}`);
|
|
1758
1796
|
}
|
|
1759
1797
|
}
|
|
1760
|
-
|
|
1798
|
+
if (buildResult.fragmentCount > 0) {
|
|
1799
|
+
log(pc6.green(` Built ${buildResult.fragmentCount} fragment(s)`));
|
|
1800
|
+
} else {
|
|
1801
|
+
log(pc6.dim(" No compilable fragments found, falling back to source scan..."));
|
|
1802
|
+
try {
|
|
1803
|
+
const scanResult = await scan({ verbose: false });
|
|
1804
|
+
if (scanResult.componentCount > 0) {
|
|
1805
|
+
result.fragmentsBuilt = scanResult.componentCount;
|
|
1806
|
+
log(pc6.green(` Scanned ${scanResult.componentCount} component(s) from source`));
|
|
1807
|
+
}
|
|
1808
|
+
} catch {
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1761
1811
|
} catch (error) {
|
|
1762
1812
|
result.errors.push(`Build failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1763
1813
|
}
|
|
@@ -1811,7 +1861,7 @@ ${BRAND.name} Dev Server
|
|
|
1811
1861
|
}
|
|
1812
1862
|
}
|
|
1813
1863
|
}
|
|
1814
|
-
const { createDevServer } = await import("./viewer-
|
|
1864
|
+
const { createDevServer } = await import("./viewer-RFA2KVBG.js");
|
|
1815
1865
|
console.log(pc7.dim("\nStarting dev server..."));
|
|
1816
1866
|
const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
|
|
1817
1867
|
try {
|
|
@@ -5363,9 +5413,384 @@ ${pc21.bold("Summary")}`);
|
|
|
5363
5413
|
};
|
|
5364
5414
|
}
|
|
5365
5415
|
|
|
5416
|
+
// src/commands/doctor.ts
|
|
5417
|
+
import { readFile as readFile8, access as access3 } from "fs/promises";
|
|
5418
|
+
import { join as join10, resolve as resolve8 } from "path";
|
|
5419
|
+
import pc22 from "picocolors";
|
|
5420
|
+
var VALID_NEUTRALS = ["stone", "ice", "earth", "sand", "fire"];
|
|
5421
|
+
var VALID_DENSITIES = ["compact", "default", "relaxed"];
|
|
5422
|
+
var VALID_RADII = ["sharp", "subtle", "default", "rounded", "pill"];
|
|
5423
|
+
async function checkPackageInstalled(root) {
|
|
5424
|
+
try {
|
|
5425
|
+
const pkgPath = join10(root, "package.json");
|
|
5426
|
+
const content = await readFile8(pkgPath, "utf-8");
|
|
5427
|
+
const pkg2 = JSON.parse(content);
|
|
5428
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
5429
|
+
if (allDeps["@fragments-sdk/ui"]) {
|
|
5430
|
+
return {
|
|
5431
|
+
name: "Package installed",
|
|
5432
|
+
status: "pass",
|
|
5433
|
+
message: `@fragments-sdk/ui ${allDeps["@fragments-sdk/ui"]} found in dependencies`
|
|
5434
|
+
};
|
|
5435
|
+
}
|
|
5436
|
+
return {
|
|
5437
|
+
name: "Package installed",
|
|
5438
|
+
status: "fail",
|
|
5439
|
+
message: "@fragments-sdk/ui not found in package.json",
|
|
5440
|
+
fix: "npm install @fragments-sdk/ui"
|
|
5441
|
+
};
|
|
5442
|
+
} catch {
|
|
5443
|
+
return {
|
|
5444
|
+
name: "Package installed",
|
|
5445
|
+
status: "fail",
|
|
5446
|
+
message: "No package.json found"
|
|
5447
|
+
};
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5450
|
+
async function checkStylesImport(root) {
|
|
5451
|
+
const entryPatterns = [
|
|
5452
|
+
"src/main.tsx",
|
|
5453
|
+
"src/main.ts",
|
|
5454
|
+
"src/index.tsx",
|
|
5455
|
+
"src/index.ts",
|
|
5456
|
+
"src/App.tsx",
|
|
5457
|
+
"src/App.ts",
|
|
5458
|
+
"app/layout.tsx",
|
|
5459
|
+
"app/layout.ts",
|
|
5460
|
+
"src/app/layout.tsx",
|
|
5461
|
+
"src/app/layout.ts",
|
|
5462
|
+
"app/root.tsx",
|
|
5463
|
+
"pages/_app.tsx",
|
|
5464
|
+
"pages/_app.ts"
|
|
5465
|
+
];
|
|
5466
|
+
for (const pattern of entryPatterns) {
|
|
5467
|
+
try {
|
|
5468
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5469
|
+
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
5470
|
+
return {
|
|
5471
|
+
name: "Styles import",
|
|
5472
|
+
status: "pass",
|
|
5473
|
+
message: `Found styles import in ${pattern}`
|
|
5474
|
+
};
|
|
5475
|
+
}
|
|
5476
|
+
if (content.includes("@fragments-sdk/ui/globals")) {
|
|
5477
|
+
return {
|
|
5478
|
+
name: "Styles import",
|
|
5479
|
+
status: "warn",
|
|
5480
|
+
message: `${pattern} uses deprecated '@fragments-sdk/ui/globals'. Use '@fragments-sdk/ui/styles' instead`,
|
|
5481
|
+
fix: `Replace '@fragments-sdk/ui/globals' with '@fragments-sdk/ui/styles' in ${pattern}`
|
|
5482
|
+
};
|
|
5483
|
+
}
|
|
5484
|
+
} catch {
|
|
5485
|
+
}
|
|
5486
|
+
}
|
|
5487
|
+
const scssPatterns = [
|
|
5488
|
+
"src/styles/globals.scss",
|
|
5489
|
+
"src/globals.scss",
|
|
5490
|
+
"styles/globals.scss",
|
|
5491
|
+
"app/globals.scss",
|
|
5492
|
+
"src/app/globals.scss",
|
|
5493
|
+
"app/styles/globals.scss"
|
|
5494
|
+
];
|
|
5495
|
+
for (const pattern of scssPatterns) {
|
|
5496
|
+
try {
|
|
5497
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5498
|
+
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
5499
|
+
return {
|
|
5500
|
+
name: "Styles import",
|
|
5501
|
+
status: "pass",
|
|
5502
|
+
message: `Found SCSS @use import in ${pattern}`
|
|
5503
|
+
};
|
|
5504
|
+
}
|
|
5505
|
+
} catch {
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
return {
|
|
5509
|
+
name: "Styles import",
|
|
5510
|
+
status: "fail",
|
|
5511
|
+
message: "No @fragments-sdk/ui/styles import found in entry files",
|
|
5512
|
+
fix: "Add `import '@fragments-sdk/ui/styles'` to your app's entry file"
|
|
5513
|
+
};
|
|
5514
|
+
}
|
|
5515
|
+
async function checkThemeProvider(root) {
|
|
5516
|
+
const providerPatterns = [
|
|
5517
|
+
"src/main.tsx",
|
|
5518
|
+
"src/App.tsx",
|
|
5519
|
+
"src/providers.tsx",
|
|
5520
|
+
"app/layout.tsx",
|
|
5521
|
+
"app/providers.tsx",
|
|
5522
|
+
"src/app/layout.tsx",
|
|
5523
|
+
"src/app/providers.tsx",
|
|
5524
|
+
"app/root.tsx",
|
|
5525
|
+
"pages/_app.tsx"
|
|
5526
|
+
];
|
|
5527
|
+
for (const pattern of providerPatterns) {
|
|
5528
|
+
try {
|
|
5529
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5530
|
+
if (content.includes("ThemeProvider")) {
|
|
5531
|
+
if (content.includes("defaultTheme=") || content.includes("defaultTheme =")) {
|
|
5532
|
+
return {
|
|
5533
|
+
name: "ThemeProvider",
|
|
5534
|
+
status: "warn",
|
|
5535
|
+
message: `${pattern} uses deprecated 'defaultTheme' prop. Use 'defaultMode' instead`,
|
|
5536
|
+
fix: `Replace 'defaultTheme' with 'defaultMode' in ${pattern}`
|
|
5537
|
+
};
|
|
5538
|
+
}
|
|
5539
|
+
return {
|
|
5540
|
+
name: "ThemeProvider",
|
|
5541
|
+
status: "pass",
|
|
5542
|
+
message: `ThemeProvider found in ${pattern}`
|
|
5543
|
+
};
|
|
5544
|
+
}
|
|
5545
|
+
} catch {
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
return {
|
|
5549
|
+
name: "ThemeProvider",
|
|
5550
|
+
status: "warn",
|
|
5551
|
+
message: "ThemeProvider not found in common entry files (optional but recommended)",
|
|
5552
|
+
fix: 'Wrap your app with <ThemeProvider defaultMode="system">'
|
|
5553
|
+
};
|
|
5554
|
+
}
|
|
5555
|
+
async function checkScssSeeds(root) {
|
|
5556
|
+
const checks = [];
|
|
5557
|
+
const scssPatterns = [
|
|
5558
|
+
"src/styles/globals.scss",
|
|
5559
|
+
"src/globals.scss",
|
|
5560
|
+
"styles/globals.scss",
|
|
5561
|
+
"app/globals.scss",
|
|
5562
|
+
"src/app/globals.scss",
|
|
5563
|
+
"app/styles/globals.scss"
|
|
5564
|
+
];
|
|
5565
|
+
for (const pattern of scssPatterns) {
|
|
5566
|
+
try {
|
|
5567
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5568
|
+
if (!content.includes("@fragments-sdk/ui/styles")) continue;
|
|
5569
|
+
const standalonePattern = /^\$fui-\w+:\s*.+;$/m;
|
|
5570
|
+
if (standalonePattern.test(content) && !content.includes("@use")) {
|
|
5571
|
+
checks.push({
|
|
5572
|
+
name: "SCSS syntax",
|
|
5573
|
+
status: "fail",
|
|
5574
|
+
message: `${pattern} uses standalone $fui- variables. Must use @use...with() syntax`,
|
|
5575
|
+
fix: "@use '@fragments-sdk/ui/styles' with ($fui-brand: #0066ff);"
|
|
5576
|
+
});
|
|
5577
|
+
}
|
|
5578
|
+
const neutralMatch = content.match(/\$fui-neutral:\s*"([^"]+)"/);
|
|
5579
|
+
if (neutralMatch && !VALID_NEUTRALS.includes(neutralMatch[1])) {
|
|
5580
|
+
checks.push({
|
|
5581
|
+
name: "SCSS seed: neutral",
|
|
5582
|
+
status: "fail",
|
|
5583
|
+
message: `Invalid $fui-neutral: "${neutralMatch[1]}" in ${pattern}`,
|
|
5584
|
+
fix: `Valid neutrals: ${VALID_NEUTRALS.join(", ")}`
|
|
5585
|
+
});
|
|
5586
|
+
}
|
|
5587
|
+
const densityMatch = content.match(/\$fui-density:\s*"([^"]+)"/);
|
|
5588
|
+
if (densityMatch && !VALID_DENSITIES.includes(densityMatch[1])) {
|
|
5589
|
+
checks.push({
|
|
5590
|
+
name: "SCSS seed: density",
|
|
5591
|
+
status: "fail",
|
|
5592
|
+
message: `Invalid $fui-density: "${densityMatch[1]}" in ${pattern}`,
|
|
5593
|
+
fix: `Valid densities: ${VALID_DENSITIES.join(", ")}`
|
|
5594
|
+
});
|
|
5595
|
+
}
|
|
5596
|
+
const radiusMatch = content.match(/\$fui-radius-style:\s*"([^"]+)"/);
|
|
5597
|
+
if (radiusMatch && !VALID_RADII.includes(radiusMatch[1])) {
|
|
5598
|
+
checks.push({
|
|
5599
|
+
name: "SCSS seed: radius-style",
|
|
5600
|
+
status: "fail",
|
|
5601
|
+
message: `Invalid $fui-radius-style: "${radiusMatch[1]}" in ${pattern}`,
|
|
5602
|
+
fix: `Valid radius styles: ${VALID_RADII.join(", ")}`
|
|
5603
|
+
});
|
|
5604
|
+
}
|
|
5605
|
+
const brandMatch = content.match(/\$fui-brand:\s*(#[0-9a-fA-F]+)/);
|
|
5606
|
+
if (brandMatch) {
|
|
5607
|
+
const hex = brandMatch[1];
|
|
5608
|
+
if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) {
|
|
5609
|
+
checks.push({
|
|
5610
|
+
name: "SCSS seed: brand",
|
|
5611
|
+
status: "fail",
|
|
5612
|
+
message: `Invalid $fui-brand color: "${hex}" in ${pattern}`,
|
|
5613
|
+
fix: "Must be a valid hex color (e.g., #0066ff)"
|
|
5614
|
+
});
|
|
5615
|
+
}
|
|
5616
|
+
}
|
|
5617
|
+
if (checks.length === 0) {
|
|
5618
|
+
checks.push({
|
|
5619
|
+
name: "SCSS seeds",
|
|
5620
|
+
status: "pass",
|
|
5621
|
+
message: `Seed values in ${pattern} are valid`
|
|
5622
|
+
});
|
|
5623
|
+
}
|
|
5624
|
+
return checks;
|
|
5625
|
+
} catch {
|
|
5626
|
+
}
|
|
5627
|
+
}
|
|
5628
|
+
checks.push({
|
|
5629
|
+
name: "SCSS seeds",
|
|
5630
|
+
status: "pass",
|
|
5631
|
+
message: "No custom SCSS seeds configured (using defaults)"
|
|
5632
|
+
});
|
|
5633
|
+
return checks;
|
|
5634
|
+
}
|
|
5635
|
+
async function checkPeerDeps(root) {
|
|
5636
|
+
const checks = [];
|
|
5637
|
+
try {
|
|
5638
|
+
const pkgPath = join10(root, "package.json");
|
|
5639
|
+
const content = await readFile8(pkgPath, "utf-8");
|
|
5640
|
+
const pkg2 = JSON.parse(content);
|
|
5641
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
5642
|
+
if (!allDeps["react"]) {
|
|
5643
|
+
checks.push({
|
|
5644
|
+
name: "Peer dep: react",
|
|
5645
|
+
status: "fail",
|
|
5646
|
+
message: "react not found in dependencies (required)",
|
|
5647
|
+
fix: "npm install react react-dom"
|
|
5648
|
+
});
|
|
5649
|
+
} else {
|
|
5650
|
+
checks.push({
|
|
5651
|
+
name: "Peer dep: react",
|
|
5652
|
+
status: "pass",
|
|
5653
|
+
message: `react ${allDeps["react"]} installed`
|
|
5654
|
+
});
|
|
5655
|
+
}
|
|
5656
|
+
if (!allDeps["sass"]) {
|
|
5657
|
+
checks.push({
|
|
5658
|
+
name: "Peer dep: sass",
|
|
5659
|
+
status: "warn",
|
|
5660
|
+
message: "sass not installed (needed for custom SCSS theming)",
|
|
5661
|
+
fix: "npm install -D sass"
|
|
5662
|
+
});
|
|
5663
|
+
}
|
|
5664
|
+
const optionalPeers = [
|
|
5665
|
+
{ pkg: "recharts", components: "Chart" },
|
|
5666
|
+
{ pkg: "shiki", components: "CodeBlock" },
|
|
5667
|
+
{ pkg: "react-day-picker", components: "DatePicker" },
|
|
5668
|
+
{ pkg: "@tanstack/react-table", components: "DataTable" }
|
|
5669
|
+
];
|
|
5670
|
+
for (const peer of optionalPeers) {
|
|
5671
|
+
if (allDeps[peer.pkg]) {
|
|
5672
|
+
checks.push({
|
|
5673
|
+
name: `Optional dep: ${peer.pkg}`,
|
|
5674
|
+
status: "pass",
|
|
5675
|
+
message: `${peer.pkg} installed (enables ${peer.components})`
|
|
5676
|
+
});
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
} catch {
|
|
5680
|
+
checks.push({
|
|
5681
|
+
name: "Peer dependencies",
|
|
5682
|
+
status: "fail",
|
|
5683
|
+
message: "Could not read package.json"
|
|
5684
|
+
});
|
|
5685
|
+
}
|
|
5686
|
+
return checks;
|
|
5687
|
+
}
|
|
5688
|
+
async function checkMcpConfig(root) {
|
|
5689
|
+
const mcpConfigPaths = [
|
|
5690
|
+
".mcp.json",
|
|
5691
|
+
".cursor/mcp.json",
|
|
5692
|
+
".vscode/mcp.json"
|
|
5693
|
+
];
|
|
5694
|
+
for (const configPath of mcpConfigPaths) {
|
|
5695
|
+
try {
|
|
5696
|
+
const fullPath = join10(root, configPath);
|
|
5697
|
+
const content = await readFile8(fullPath, "utf-8");
|
|
5698
|
+
const config = JSON.parse(content);
|
|
5699
|
+
const servers = config.mcpServers || config.servers || {};
|
|
5700
|
+
const hasFragments = Object.values(servers).some((server) => {
|
|
5701
|
+
const s = server;
|
|
5702
|
+
return s.args?.some((arg) => arg.includes("@fragments-sdk/mcp")) || s.command?.includes("fragments");
|
|
5703
|
+
});
|
|
5704
|
+
if (hasFragments) {
|
|
5705
|
+
return {
|
|
5706
|
+
name: "MCP configuration",
|
|
5707
|
+
status: "pass",
|
|
5708
|
+
message: `Fragments MCP server configured in ${configPath}`
|
|
5709
|
+
};
|
|
5710
|
+
}
|
|
5711
|
+
} catch {
|
|
5712
|
+
}
|
|
5713
|
+
}
|
|
5714
|
+
return {
|
|
5715
|
+
name: "MCP configuration",
|
|
5716
|
+
status: "warn",
|
|
5717
|
+
message: "No Fragments MCP server configuration found (optional)",
|
|
5718
|
+
fix: "Run `fragments init` or add @fragments-sdk/mcp to your MCP config"
|
|
5719
|
+
};
|
|
5720
|
+
}
|
|
5721
|
+
async function checkTypeScript(root) {
|
|
5722
|
+
try {
|
|
5723
|
+
const tsconfigPath = join10(root, "tsconfig.json");
|
|
5724
|
+
await access3(tsconfigPath);
|
|
5725
|
+
return {
|
|
5726
|
+
name: "TypeScript",
|
|
5727
|
+
status: "pass",
|
|
5728
|
+
message: "tsconfig.json found"
|
|
5729
|
+
};
|
|
5730
|
+
} catch {
|
|
5731
|
+
return {
|
|
5732
|
+
name: "TypeScript",
|
|
5733
|
+
status: "warn",
|
|
5734
|
+
message: "No tsconfig.json found (TypeScript recommended but not required)"
|
|
5735
|
+
};
|
|
5736
|
+
}
|
|
5737
|
+
}
|
|
5738
|
+
async function doctor(options = {}) {
|
|
5739
|
+
const root = resolve8(options.root ?? process.cwd());
|
|
5740
|
+
const checks = [];
|
|
5741
|
+
if (!options.json) {
|
|
5742
|
+
console.log(pc22.cyan(`
|
|
5743
|
+
${BRAND.name} Doctor
|
|
5744
|
+
`));
|
|
5745
|
+
console.log(pc22.dim(`Checking project at ${root}
|
|
5746
|
+
`));
|
|
5747
|
+
}
|
|
5748
|
+
checks.push(await checkPackageInstalled(root));
|
|
5749
|
+
checks.push(await checkStylesImport(root));
|
|
5750
|
+
checks.push(await checkThemeProvider(root));
|
|
5751
|
+
checks.push(...await checkScssSeeds(root));
|
|
5752
|
+
checks.push(...await checkPeerDeps(root));
|
|
5753
|
+
checks.push(await checkMcpConfig(root));
|
|
5754
|
+
checks.push(await checkTypeScript(root));
|
|
5755
|
+
const passed = checks.filter((c) => c.status === "pass").length;
|
|
5756
|
+
const warned = checks.filter((c) => c.status === "warn").length;
|
|
5757
|
+
const failed = checks.filter((c) => c.status === "fail").length;
|
|
5758
|
+
const result = {
|
|
5759
|
+
success: failed === 0,
|
|
5760
|
+
checks,
|
|
5761
|
+
passed,
|
|
5762
|
+
warned,
|
|
5763
|
+
failed
|
|
5764
|
+
};
|
|
5765
|
+
if (options.json) {
|
|
5766
|
+
console.log(JSON.stringify(result, null, 2));
|
|
5767
|
+
} else {
|
|
5768
|
+
for (const check of checks) {
|
|
5769
|
+
const icon = check.status === "pass" ? pc22.green("\u2713") : check.status === "warn" ? pc22.yellow("!") : pc22.red("\u2717");
|
|
5770
|
+
const msg = check.status === "pass" ? check.message : check.status === "warn" ? pc22.yellow(check.message) : pc22.red(check.message);
|
|
5771
|
+
console.log(` ${icon} ${pc22.bold(check.name)}: ${msg}`);
|
|
5772
|
+
if (check.fix && check.status !== "pass") {
|
|
5773
|
+
console.log(pc22.dim(` \u2192 ${check.fix}`));
|
|
5774
|
+
}
|
|
5775
|
+
}
|
|
5776
|
+
console.log();
|
|
5777
|
+
if (failed === 0 && warned === 0) {
|
|
5778
|
+
console.log(pc22.green(`\u2713 All ${passed} checks passed \u2014 your setup looks great!`));
|
|
5779
|
+
} else if (failed === 0) {
|
|
5780
|
+
console.log(pc22.green(`\u2713 ${passed} passed`) + pc22.yellow(`, ${warned} warning(s)`));
|
|
5781
|
+
} else {
|
|
5782
|
+
console.log(
|
|
5783
|
+
pc22.red(`\u2717 ${failed} failed`) + (warned > 0 ? pc22.yellow(`, ${warned} warning(s)`) : "") + pc22.dim(`, ${passed} passed`)
|
|
5784
|
+
);
|
|
5785
|
+
}
|
|
5786
|
+
console.log();
|
|
5787
|
+
}
|
|
5788
|
+
return result;
|
|
5789
|
+
}
|
|
5790
|
+
|
|
5366
5791
|
// src/bin.ts
|
|
5367
5792
|
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
5368
|
-
var pkg = JSON.parse(readFileSync(
|
|
5793
|
+
var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
|
|
5369
5794
|
var program = new Command();
|
|
5370
5795
|
program.name(BRAND.cliCommand).description(`${BRAND.name} - Design system documentation and compliance tool`).version(pkg.version);
|
|
5371
5796
|
program.command("validate").description("Validate fragment files").option("-c, --config <path>", "Path to config file").option("--schema", "Validate fragment schema only").option("--coverage", "Validate coverage only").option("--snippets", "Validate snippet/render policy only").option("--snippet-mode <mode>", "Override snippet policy mode (warn|error)").option("--component-start <name>", "Start component name for alphabetical snippet batch validation").option("--component-limit <n>", "Component count for alphabetical snippet batch validation", (value) => Number.parseInt(value, 10)).action(async (options) => {
|
|
@@ -5375,7 +5800,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
|
|
|
5375
5800
|
process.exit(1);
|
|
5376
5801
|
}
|
|
5377
5802
|
} catch (error) {
|
|
5378
|
-
console.error(
|
|
5803
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5379
5804
|
process.exit(1);
|
|
5380
5805
|
}
|
|
5381
5806
|
});
|
|
@@ -5395,7 +5820,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
|
|
|
5395
5820
|
process.exit(1);
|
|
5396
5821
|
}
|
|
5397
5822
|
} catch (error) {
|
|
5398
|
-
console.error(
|
|
5823
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5399
5824
|
process.exit(1);
|
|
5400
5825
|
}
|
|
5401
5826
|
});
|
|
@@ -5414,7 +5839,7 @@ program.command("context").description("Generate AI-ready context for your desig
|
|
|
5414
5839
|
process.exit(1);
|
|
5415
5840
|
}
|
|
5416
5841
|
} catch (error) {
|
|
5417
|
-
console.error(
|
|
5842
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5418
5843
|
process.exit(1);
|
|
5419
5844
|
}
|
|
5420
5845
|
});
|
|
@@ -5441,7 +5866,7 @@ program.command("ai").description("Generate context optimized for AI assistants
|
|
|
5441
5866
|
}
|
|
5442
5867
|
}
|
|
5443
5868
|
} catch (error) {
|
|
5444
|
-
console.error(
|
|
5869
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5445
5870
|
process.exit(1);
|
|
5446
5871
|
}
|
|
5447
5872
|
});
|
|
@@ -5449,7 +5874,7 @@ program.command("list").description("List all discovered fragment files").option
|
|
|
5449
5874
|
try {
|
|
5450
5875
|
await list(options);
|
|
5451
5876
|
} catch (error) {
|
|
5452
|
-
console.error(
|
|
5877
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5453
5878
|
process.exit(1);
|
|
5454
5879
|
}
|
|
5455
5880
|
});
|
|
@@ -5457,7 +5882,7 @@ program.command("reset").description("Reset to initial state (delete all generat
|
|
|
5457
5882
|
try {
|
|
5458
5883
|
await reset(options);
|
|
5459
5884
|
} catch (error) {
|
|
5460
|
-
console.error(
|
|
5885
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5461
5886
|
process.exit(1);
|
|
5462
5887
|
}
|
|
5463
5888
|
});
|
|
@@ -5471,7 +5896,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
|
|
|
5471
5896
|
variants: options.variants
|
|
5472
5897
|
});
|
|
5473
5898
|
} catch (error) {
|
|
5474
|
-
console.error(
|
|
5899
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5475
5900
|
process.exit(1);
|
|
5476
5901
|
}
|
|
5477
5902
|
});
|
|
@@ -5486,7 +5911,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
|
|
|
5486
5911
|
exclude: options.exclude
|
|
5487
5912
|
});
|
|
5488
5913
|
} catch (error) {
|
|
5489
|
-
console.error(
|
|
5914
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5490
5915
|
process.exit(1);
|
|
5491
5916
|
}
|
|
5492
5917
|
});
|
|
@@ -5501,9 +5926,9 @@ program.command("dev").description("Start the development server with live compo
|
|
|
5501
5926
|
skipBuild: options.skipBuild
|
|
5502
5927
|
});
|
|
5503
5928
|
} catch (error) {
|
|
5504
|
-
console.error(
|
|
5929
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5505
5930
|
if (error instanceof Error && error.stack) {
|
|
5506
|
-
console.error(
|
|
5931
|
+
console.error(pc23.dim(error.stack));
|
|
5507
5932
|
}
|
|
5508
5933
|
process.exit(1);
|
|
5509
5934
|
}
|
|
@@ -5524,7 +5949,7 @@ program.command("screenshot").description("Capture screenshots of component vari
|
|
|
5524
5949
|
process.exit(1);
|
|
5525
5950
|
}
|
|
5526
5951
|
} catch (error) {
|
|
5527
|
-
console.error(
|
|
5952
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5528
5953
|
process.exit(1);
|
|
5529
5954
|
}
|
|
5530
5955
|
});
|
|
@@ -5543,7 +5968,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
|
|
|
5543
5968
|
process.exit(1);
|
|
5544
5969
|
}
|
|
5545
5970
|
} catch (error) {
|
|
5546
|
-
console.error(
|
|
5971
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5547
5972
|
process.exit(1);
|
|
5548
5973
|
}
|
|
5549
5974
|
});
|
|
@@ -5562,8 +5987,8 @@ program.command("compare").argument("[component]", "Component name to compare").
|
|
|
5562
5987
|
process.exit(1);
|
|
5563
5988
|
}
|
|
5564
5989
|
} catch (error) {
|
|
5565
|
-
console.error(
|
|
5566
|
-
console.log(
|
|
5990
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5991
|
+
console.log(pc23.dim(`
|
|
5567
5992
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
5568
5993
|
process.exit(1);
|
|
5569
5994
|
}
|
|
@@ -5582,7 +6007,7 @@ program.command("analyze").description("Analyze design system and generate repor
|
|
|
5582
6007
|
process.exit(1);
|
|
5583
6008
|
}
|
|
5584
6009
|
} catch (error) {
|
|
5585
|
-
console.error(
|
|
6010
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5586
6011
|
process.exit(1);
|
|
5587
6012
|
}
|
|
5588
6013
|
});
|
|
@@ -5601,7 +6026,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
|
|
|
5601
6026
|
if (options.ci) {
|
|
5602
6027
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
|
|
5603
6028
|
} else {
|
|
5604
|
-
console.error(
|
|
6029
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5605
6030
|
}
|
|
5606
6031
|
process.exit(1);
|
|
5607
6032
|
}
|
|
@@ -5618,7 +6043,7 @@ program.command("audit").description("Scan all fragments and show compliance met
|
|
|
5618
6043
|
if (options.json) {
|
|
5619
6044
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
|
|
5620
6045
|
} else {
|
|
5621
|
-
console.error(
|
|
6046
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5622
6047
|
}
|
|
5623
6048
|
process.exit(1);
|
|
5624
6049
|
}
|
|
@@ -5640,7 +6065,7 @@ program.command("a11y").description("Run accessibility checks on all component v
|
|
|
5640
6065
|
if (options.json) {
|
|
5641
6066
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
|
|
5642
6067
|
} else {
|
|
5643
|
-
console.error(
|
|
6068
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5644
6069
|
}
|
|
5645
6070
|
process.exit(1);
|
|
5646
6071
|
}
|
|
@@ -5663,7 +6088,7 @@ program.command("enhance").description("AI-powered documentation generation from
|
|
|
5663
6088
|
if (options.format === "json") {
|
|
5664
6089
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
|
|
5665
6090
|
} else {
|
|
5666
|
-
console.error(
|
|
6091
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5667
6092
|
}
|
|
5668
6093
|
process.exit(1);
|
|
5669
6094
|
}
|
|
@@ -5684,7 +6109,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
|
|
|
5684
6109
|
process.exit(1);
|
|
5685
6110
|
}
|
|
5686
6111
|
} catch (error) {
|
|
5687
|
-
console.error(
|
|
6112
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5688
6113
|
process.exit(1);
|
|
5689
6114
|
}
|
|
5690
6115
|
});
|
|
@@ -5697,7 +6122,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
|
|
|
5697
6122
|
format: options.format
|
|
5698
6123
|
});
|
|
5699
6124
|
} catch (error) {
|
|
5700
|
-
console.error(
|
|
6125
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5701
6126
|
process.exit(1);
|
|
5702
6127
|
}
|
|
5703
6128
|
});
|
|
@@ -5709,7 +6134,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
|
|
|
5709
6134
|
json: options.json
|
|
5710
6135
|
});
|
|
5711
6136
|
} catch (error) {
|
|
5712
|
-
console.error(
|
|
6137
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5713
6138
|
process.exit(1);
|
|
5714
6139
|
}
|
|
5715
6140
|
});
|
|
@@ -5723,9 +6148,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
|
|
|
5723
6148
|
port: options.port
|
|
5724
6149
|
});
|
|
5725
6150
|
} catch (error) {
|
|
5726
|
-
console.error(
|
|
6151
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5727
6152
|
if (action === "update") {
|
|
5728
|
-
console.log(
|
|
6153
|
+
console.log(pc23.dim(`
|
|
5729
6154
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
5730
6155
|
}
|
|
5731
6156
|
process.exit(1);
|
|
@@ -5733,27 +6158,27 @@ Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
|
5733
6158
|
});
|
|
5734
6159
|
program.command("view").description(`Generate a static HTML viewer for ${BRAND.outFile}`).option("-i, --input <path>", `Path to ${BRAND.outFile}`, BRAND.outFile).option("-o, --output <path>", "Output HTML file path", BRAND.viewerHtmlFile).option("--open", "Open in browser after generation").action(async (options) => {
|
|
5735
6160
|
try {
|
|
5736
|
-
const { generateViewerFromJson } = await import("./static-viewer-
|
|
6161
|
+
const { generateViewerFromJson } = await import("./static-viewer-XCS7UJTO.js");
|
|
5737
6162
|
const fs2 = await import("fs/promises");
|
|
5738
6163
|
const path = await import("path");
|
|
5739
6164
|
const inputPath = path.resolve(process.cwd(), options.input);
|
|
5740
6165
|
const outputPath = path.resolve(process.cwd(), options.output);
|
|
5741
|
-
console.log(
|
|
6166
|
+
console.log(pc23.cyan(`
|
|
5742
6167
|
${BRAND.name} Viewer Generator
|
|
5743
6168
|
`));
|
|
5744
6169
|
try {
|
|
5745
6170
|
await fs2.access(inputPath);
|
|
5746
6171
|
} catch {
|
|
5747
|
-
console.log(
|
|
5748
|
-
console.log(
|
|
5749
|
-
Run ${
|
|
6172
|
+
console.log(pc23.red(`Error: ${options.input} not found.`));
|
|
6173
|
+
console.log(pc23.dim(`
|
|
6174
|
+
Run ${pc23.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
5750
6175
|
`));
|
|
5751
6176
|
process.exit(1);
|
|
5752
6177
|
}
|
|
5753
|
-
console.log(
|
|
6178
|
+
console.log(pc23.dim(`Reading: ${options.input}`));
|
|
5754
6179
|
const html = await generateViewerFromJson(inputPath);
|
|
5755
6180
|
await fs2.writeFile(outputPath, html);
|
|
5756
|
-
console.log(
|
|
6181
|
+
console.log(pc23.green(`
|
|
5757
6182
|
\u2713 Generated: ${options.output}
|
|
5758
6183
|
`));
|
|
5759
6184
|
if (options.open) {
|
|
@@ -5762,7 +6187,7 @@ Run ${pc22.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
|
5762
6187
|
exec(`${openCmd} "${outputPath}"`);
|
|
5763
6188
|
}
|
|
5764
6189
|
} catch (error) {
|
|
5765
|
-
console.error(
|
|
6190
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5766
6191
|
process.exit(1);
|
|
5767
6192
|
}
|
|
5768
6193
|
});
|
|
@@ -5775,33 +6200,33 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
|
|
|
5775
6200
|
component: options.component
|
|
5776
6201
|
});
|
|
5777
6202
|
} catch (error) {
|
|
5778
|
-
console.error(
|
|
6203
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5779
6204
|
process.exit(1);
|
|
5780
6205
|
}
|
|
5781
6206
|
});
|
|
5782
6207
|
program.command("init").description("Initialize fragments in a project (interactive by default)").option("--force", "Overwrite existing config").option("-y, --yes", "Non-interactive mode - auto-detect and use defaults").action(async (options) => {
|
|
5783
6208
|
try {
|
|
5784
|
-
const { init } = await import("./init-
|
|
6209
|
+
const { init } = await import("./init-2GEGVIUQ.js");
|
|
5785
6210
|
const result = await init({
|
|
5786
6211
|
projectRoot: process.cwd(),
|
|
5787
6212
|
force: options.force,
|
|
5788
6213
|
yes: options.yes
|
|
5789
6214
|
});
|
|
5790
6215
|
if (!result.success) {
|
|
5791
|
-
console.error(
|
|
6216
|
+
console.error(pc23.red("\nInit failed with errors:"));
|
|
5792
6217
|
for (const error of result.errors) {
|
|
5793
|
-
console.error(
|
|
6218
|
+
console.error(pc23.red(` - ${error}`));
|
|
5794
6219
|
}
|
|
5795
6220
|
process.exit(1);
|
|
5796
6221
|
}
|
|
5797
6222
|
} catch (error) {
|
|
5798
|
-
console.error(
|
|
6223
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5799
6224
|
process.exit(1);
|
|
5800
6225
|
}
|
|
5801
6226
|
});
|
|
5802
6227
|
program.command("tokens").description("Discover and list design tokens from CSS/SCSS files").option("-c, --config <path>", "Path to config file").option("--json", "Output as JSON").option("--categories", "Group tokens by category").option("--theme <theme>", "Filter by theme name").option("--category <category>", "Filter by category (color, spacing, typography, etc.)").option("--verbose", "Show all tokens (no truncation)").action(async (options) => {
|
|
5803
6228
|
try {
|
|
5804
|
-
const { tokens } = await import("./tokens-
|
|
6229
|
+
const { tokens } = await import("./tokens-2EXPCVP3.js");
|
|
5805
6230
|
const result = await tokens({
|
|
5806
6231
|
config: options.config,
|
|
5807
6232
|
json: options.json,
|
|
@@ -5814,13 +6239,13 @@ program.command("tokens").description("Discover and list design tokens from CSS/
|
|
|
5814
6239
|
process.exit(1);
|
|
5815
6240
|
}
|
|
5816
6241
|
} catch (error) {
|
|
5817
|
-
console.error(
|
|
6242
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5818
6243
|
process.exit(1);
|
|
5819
6244
|
}
|
|
5820
6245
|
});
|
|
5821
6246
|
program.command("generate").description("Generate fragment files from component source code").argument("[component]", "Specific component name to generate (optional)").option("--force", "Overwrite existing fragment files").option("--pattern <glob>", "Pattern for component files", "src/components/**/*.tsx").action(async (component, options) => {
|
|
5822
6247
|
try {
|
|
5823
|
-
const { generate } = await import("./generate-
|
|
6248
|
+
const { generate } = await import("./generate-LQA2R7FN.js");
|
|
5824
6249
|
const result = await generate({
|
|
5825
6250
|
projectRoot: process.cwd(),
|
|
5826
6251
|
component,
|
|
@@ -5828,11 +6253,11 @@ program.command("generate").description("Generate fragment files from component
|
|
|
5828
6253
|
componentPattern: options.pattern
|
|
5829
6254
|
});
|
|
5830
6255
|
if (!result.success) {
|
|
5831
|
-
console.error(
|
|
6256
|
+
console.error(pc23.red("\nGenerate completed with errors"));
|
|
5832
6257
|
process.exit(1);
|
|
5833
6258
|
}
|
|
5834
6259
|
} catch (error) {
|
|
5835
|
-
console.error(
|
|
6260
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5836
6261
|
process.exit(1);
|
|
5837
6262
|
}
|
|
5838
6263
|
});
|
|
@@ -5840,7 +6265,7 @@ program.command("graph").description("Query the component relationship graph").a
|
|
|
5840
6265
|
try {
|
|
5841
6266
|
await graph(component, options);
|
|
5842
6267
|
} catch (error) {
|
|
5843
|
-
console.error(
|
|
6268
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5844
6269
|
process.exit(1);
|
|
5845
6270
|
}
|
|
5846
6271
|
});
|
|
@@ -5858,14 +6283,14 @@ program.command("perf").description("Profile component bundle sizes and performa
|
|
|
5858
6283
|
process.exit(1);
|
|
5859
6284
|
}
|
|
5860
6285
|
} catch (error) {
|
|
5861
|
-
console.error(
|
|
6286
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5862
6287
|
process.exit(1);
|
|
5863
6288
|
}
|
|
5864
6289
|
});
|
|
5865
6290
|
program.command("test").description("Run interaction tests for fragments with play functions").option("-c, --config <path>", "Path to config file").option("--component <name>", "Filter by component name").option("--tags <tags>", "Filter by tags (comma-separated)").option("--grep <pattern>", "Filter by variant name pattern").option("--exclude <pattern>", "Exclude tests matching pattern").option("--parallel <count>", "Number of parallel browser contexts", parseInt, 4).option("--timeout <ms>", "Timeout per test in milliseconds", parseInt, 3e4).option("--retries <count>", "Number of retries for failed tests", parseInt, 0).option("--bail", "Stop on first failure").option("--browser <name>", "Browser to use (chromium, firefox, webkit)", "chromium").option("--headed", "Run in headed mode (show browser)").option("--a11y", "Run accessibility checks with axe-core").option("--visual", "Capture screenshots for visual regression").option("--update-snapshots", "Update visual snapshots").option("--watch", "Watch mode - re-run on file changes").option("--reporters <names>", "Reporters to use (console, junit, json)", "console").option("-o, --output <dir>", "Output directory for results", "./test-results").option("--server-url <url>", "URL of running dev server (skips starting server)").option("-p, --port <port>", "Port for dev server", parseInt, 6006).option("--ci", "CI mode - non-interactive, exit with code 1 on failure").option("--list", "List available tests without running them").action(async (options) => {
|
|
5866
6291
|
try {
|
|
5867
6292
|
const { config, configDir } = await loadConfig(options.config);
|
|
5868
|
-
const { runTestCommand, listTests } = await import("./test-
|
|
6293
|
+
const { runTestCommand, listTests } = await import("./test-TD6TJNVY.js");
|
|
5869
6294
|
if (options.list) {
|
|
5870
6295
|
await listTests(config, configDir, {
|
|
5871
6296
|
component: options.component,
|
|
@@ -5898,7 +6323,22 @@ program.command("test").description("Run interaction tests for fragments with pl
|
|
|
5898
6323
|
});
|
|
5899
6324
|
process.exit(exitCode);
|
|
5900
6325
|
} catch (error) {
|
|
5901
|
-
console.error(
|
|
6326
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
6327
|
+
process.exit(1);
|
|
6328
|
+
}
|
|
6329
|
+
});
|
|
6330
|
+
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) => {
|
|
6331
|
+
try {
|
|
6332
|
+
const result = await doctor({
|
|
6333
|
+
root: options.root,
|
|
6334
|
+
json: options.json,
|
|
6335
|
+
fix: options.fix
|
|
6336
|
+
});
|
|
6337
|
+
if (!result.success) {
|
|
6338
|
+
process.exit(1);
|
|
6339
|
+
}
|
|
6340
|
+
} catch (error) {
|
|
6341
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5902
6342
|
process.exit(1);
|
|
5903
6343
|
}
|
|
5904
6344
|
});
|