@fragments-sdk/cli 0.8.1 → 0.9.0
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 +436 -46
- package/dist/bin.js.map +1 -1
- package/dist/{init-KFYN37ZY.js → init-KSAAS7X3.js} +2 -2
- package/dist/{init-KFYN37ZY.js.map → init-KSAAS7X3.js.map} +1 -1
- package/dist/{viewer-HZK4BSDK.js → viewer-SBTJDMP7.js} +7 -5
- package/dist/viewer-SBTJDMP7.js.map +1 -0
- package/package.json +2 -2
- package/src/bin.ts +26 -0
- package/src/commands/doctor.ts +498 -0
- package/src/commands/init-framework.ts +1 -1
- package/src/viewer/server.ts +15 -4
- package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +18 -6
- package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +16 -5
- 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/dist/viewer-HZK4BSDK.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -53,10 +53,10 @@ import "./chunk-Z7EY4VHE.js";
|
|
|
53
53
|
|
|
54
54
|
// src/bin.ts
|
|
55
55
|
import { Command } from "commander";
|
|
56
|
-
import
|
|
56
|
+
import pc23 from "picocolors";
|
|
57
57
|
import { readFileSync } from "fs";
|
|
58
58
|
import { fileURLToPath } from "url";
|
|
59
|
-
import { dirname as dirname4, join as
|
|
59
|
+
import { dirname as dirname4, join as join11 } from "path";
|
|
60
60
|
|
|
61
61
|
// src/commands/validate.ts
|
|
62
62
|
import pc from "picocolors";
|
|
@@ -1811,7 +1811,7 @@ ${BRAND.name} Dev Server
|
|
|
1811
1811
|
}
|
|
1812
1812
|
}
|
|
1813
1813
|
}
|
|
1814
|
-
const { createDevServer } = await import("./viewer-
|
|
1814
|
+
const { createDevServer } = await import("./viewer-SBTJDMP7.js");
|
|
1815
1815
|
console.log(pc7.dim("\nStarting dev server..."));
|
|
1816
1816
|
const parsedPort = typeof port === "string" ? parseInt(port, 10) : port;
|
|
1817
1817
|
try {
|
|
@@ -5363,9 +5363,384 @@ ${pc21.bold("Summary")}`);
|
|
|
5363
5363
|
};
|
|
5364
5364
|
}
|
|
5365
5365
|
|
|
5366
|
+
// src/commands/doctor.ts
|
|
5367
|
+
import { readFile as readFile8, access as access3 } from "fs/promises";
|
|
5368
|
+
import { join as join10, resolve as resolve8 } from "path";
|
|
5369
|
+
import pc22 from "picocolors";
|
|
5370
|
+
var VALID_NEUTRALS = ["stone", "ice", "earth", "sand", "fire"];
|
|
5371
|
+
var VALID_DENSITIES = ["compact", "default", "relaxed"];
|
|
5372
|
+
var VALID_RADII = ["sharp", "subtle", "default", "rounded", "pill"];
|
|
5373
|
+
async function checkPackageInstalled(root) {
|
|
5374
|
+
try {
|
|
5375
|
+
const pkgPath = join10(root, "package.json");
|
|
5376
|
+
const content = await readFile8(pkgPath, "utf-8");
|
|
5377
|
+
const pkg2 = JSON.parse(content);
|
|
5378
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
5379
|
+
if (allDeps["@fragments-sdk/ui"]) {
|
|
5380
|
+
return {
|
|
5381
|
+
name: "Package installed",
|
|
5382
|
+
status: "pass",
|
|
5383
|
+
message: `@fragments-sdk/ui ${allDeps["@fragments-sdk/ui"]} found in dependencies`
|
|
5384
|
+
};
|
|
5385
|
+
}
|
|
5386
|
+
return {
|
|
5387
|
+
name: "Package installed",
|
|
5388
|
+
status: "fail",
|
|
5389
|
+
message: "@fragments-sdk/ui not found in package.json",
|
|
5390
|
+
fix: "npm install @fragments-sdk/ui"
|
|
5391
|
+
};
|
|
5392
|
+
} catch {
|
|
5393
|
+
return {
|
|
5394
|
+
name: "Package installed",
|
|
5395
|
+
status: "fail",
|
|
5396
|
+
message: "No package.json found"
|
|
5397
|
+
};
|
|
5398
|
+
}
|
|
5399
|
+
}
|
|
5400
|
+
async function checkStylesImport(root) {
|
|
5401
|
+
const entryPatterns = [
|
|
5402
|
+
"src/main.tsx",
|
|
5403
|
+
"src/main.ts",
|
|
5404
|
+
"src/index.tsx",
|
|
5405
|
+
"src/index.ts",
|
|
5406
|
+
"src/App.tsx",
|
|
5407
|
+
"src/App.ts",
|
|
5408
|
+
"app/layout.tsx",
|
|
5409
|
+
"app/layout.ts",
|
|
5410
|
+
"src/app/layout.tsx",
|
|
5411
|
+
"src/app/layout.ts",
|
|
5412
|
+
"app/root.tsx",
|
|
5413
|
+
"pages/_app.tsx",
|
|
5414
|
+
"pages/_app.ts"
|
|
5415
|
+
];
|
|
5416
|
+
for (const pattern of entryPatterns) {
|
|
5417
|
+
try {
|
|
5418
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5419
|
+
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
5420
|
+
return {
|
|
5421
|
+
name: "Styles import",
|
|
5422
|
+
status: "pass",
|
|
5423
|
+
message: `Found styles import in ${pattern}`
|
|
5424
|
+
};
|
|
5425
|
+
}
|
|
5426
|
+
if (content.includes("@fragments-sdk/ui/globals")) {
|
|
5427
|
+
return {
|
|
5428
|
+
name: "Styles import",
|
|
5429
|
+
status: "warn",
|
|
5430
|
+
message: `${pattern} uses deprecated '@fragments-sdk/ui/globals'. Use '@fragments-sdk/ui/styles' instead`,
|
|
5431
|
+
fix: `Replace '@fragments-sdk/ui/globals' with '@fragments-sdk/ui/styles' in ${pattern}`
|
|
5432
|
+
};
|
|
5433
|
+
}
|
|
5434
|
+
} catch {
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
5437
|
+
const scssPatterns = [
|
|
5438
|
+
"src/styles/globals.scss",
|
|
5439
|
+
"src/globals.scss",
|
|
5440
|
+
"styles/globals.scss",
|
|
5441
|
+
"app/globals.scss",
|
|
5442
|
+
"src/app/globals.scss",
|
|
5443
|
+
"app/styles/globals.scss"
|
|
5444
|
+
];
|
|
5445
|
+
for (const pattern of scssPatterns) {
|
|
5446
|
+
try {
|
|
5447
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5448
|
+
if (content.includes("@fragments-sdk/ui/styles")) {
|
|
5449
|
+
return {
|
|
5450
|
+
name: "Styles import",
|
|
5451
|
+
status: "pass",
|
|
5452
|
+
message: `Found SCSS @use import in ${pattern}`
|
|
5453
|
+
};
|
|
5454
|
+
}
|
|
5455
|
+
} catch {
|
|
5456
|
+
}
|
|
5457
|
+
}
|
|
5458
|
+
return {
|
|
5459
|
+
name: "Styles import",
|
|
5460
|
+
status: "fail",
|
|
5461
|
+
message: "No @fragments-sdk/ui/styles import found in entry files",
|
|
5462
|
+
fix: "Add `import '@fragments-sdk/ui/styles'` to your app's entry file"
|
|
5463
|
+
};
|
|
5464
|
+
}
|
|
5465
|
+
async function checkThemeProvider(root) {
|
|
5466
|
+
const providerPatterns = [
|
|
5467
|
+
"src/main.tsx",
|
|
5468
|
+
"src/App.tsx",
|
|
5469
|
+
"src/providers.tsx",
|
|
5470
|
+
"app/layout.tsx",
|
|
5471
|
+
"app/providers.tsx",
|
|
5472
|
+
"src/app/layout.tsx",
|
|
5473
|
+
"src/app/providers.tsx",
|
|
5474
|
+
"app/root.tsx",
|
|
5475
|
+
"pages/_app.tsx"
|
|
5476
|
+
];
|
|
5477
|
+
for (const pattern of providerPatterns) {
|
|
5478
|
+
try {
|
|
5479
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5480
|
+
if (content.includes("ThemeProvider")) {
|
|
5481
|
+
if (content.includes("defaultTheme=") || content.includes("defaultTheme =")) {
|
|
5482
|
+
return {
|
|
5483
|
+
name: "ThemeProvider",
|
|
5484
|
+
status: "warn",
|
|
5485
|
+
message: `${pattern} uses deprecated 'defaultTheme' prop. Use 'defaultMode' instead`,
|
|
5486
|
+
fix: `Replace 'defaultTheme' with 'defaultMode' in ${pattern}`
|
|
5487
|
+
};
|
|
5488
|
+
}
|
|
5489
|
+
return {
|
|
5490
|
+
name: "ThemeProvider",
|
|
5491
|
+
status: "pass",
|
|
5492
|
+
message: `ThemeProvider found in ${pattern}`
|
|
5493
|
+
};
|
|
5494
|
+
}
|
|
5495
|
+
} catch {
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
return {
|
|
5499
|
+
name: "ThemeProvider",
|
|
5500
|
+
status: "warn",
|
|
5501
|
+
message: "ThemeProvider not found in common entry files (optional but recommended)",
|
|
5502
|
+
fix: 'Wrap your app with <ThemeProvider defaultMode="system">'
|
|
5503
|
+
};
|
|
5504
|
+
}
|
|
5505
|
+
async function checkScssSeeds(root) {
|
|
5506
|
+
const checks = [];
|
|
5507
|
+
const scssPatterns = [
|
|
5508
|
+
"src/styles/globals.scss",
|
|
5509
|
+
"src/globals.scss",
|
|
5510
|
+
"styles/globals.scss",
|
|
5511
|
+
"app/globals.scss",
|
|
5512
|
+
"src/app/globals.scss",
|
|
5513
|
+
"app/styles/globals.scss"
|
|
5514
|
+
];
|
|
5515
|
+
for (const pattern of scssPatterns) {
|
|
5516
|
+
try {
|
|
5517
|
+
const content = await readFile8(join10(root, pattern), "utf-8");
|
|
5518
|
+
if (!content.includes("@fragments-sdk/ui/styles")) continue;
|
|
5519
|
+
const standalonePattern = /^\$fui-\w+:\s*.+;$/m;
|
|
5520
|
+
if (standalonePattern.test(content) && !content.includes("@use")) {
|
|
5521
|
+
checks.push({
|
|
5522
|
+
name: "SCSS syntax",
|
|
5523
|
+
status: "fail",
|
|
5524
|
+
message: `${pattern} uses standalone $fui- variables. Must use @use...with() syntax`,
|
|
5525
|
+
fix: "@use '@fragments-sdk/ui/styles' with ($fui-brand: #0066ff);"
|
|
5526
|
+
});
|
|
5527
|
+
}
|
|
5528
|
+
const neutralMatch = content.match(/\$fui-neutral:\s*"([^"]+)"/);
|
|
5529
|
+
if (neutralMatch && !VALID_NEUTRALS.includes(neutralMatch[1])) {
|
|
5530
|
+
checks.push({
|
|
5531
|
+
name: "SCSS seed: neutral",
|
|
5532
|
+
status: "fail",
|
|
5533
|
+
message: `Invalid $fui-neutral: "${neutralMatch[1]}" in ${pattern}`,
|
|
5534
|
+
fix: `Valid neutrals: ${VALID_NEUTRALS.join(", ")}`
|
|
5535
|
+
});
|
|
5536
|
+
}
|
|
5537
|
+
const densityMatch = content.match(/\$fui-density:\s*"([^"]+)"/);
|
|
5538
|
+
if (densityMatch && !VALID_DENSITIES.includes(densityMatch[1])) {
|
|
5539
|
+
checks.push({
|
|
5540
|
+
name: "SCSS seed: density",
|
|
5541
|
+
status: "fail",
|
|
5542
|
+
message: `Invalid $fui-density: "${densityMatch[1]}" in ${pattern}`,
|
|
5543
|
+
fix: `Valid densities: ${VALID_DENSITIES.join(", ")}`
|
|
5544
|
+
});
|
|
5545
|
+
}
|
|
5546
|
+
const radiusMatch = content.match(/\$fui-radius-style:\s*"([^"]+)"/);
|
|
5547
|
+
if (radiusMatch && !VALID_RADII.includes(radiusMatch[1])) {
|
|
5548
|
+
checks.push({
|
|
5549
|
+
name: "SCSS seed: radius-style",
|
|
5550
|
+
status: "fail",
|
|
5551
|
+
message: `Invalid $fui-radius-style: "${radiusMatch[1]}" in ${pattern}`,
|
|
5552
|
+
fix: `Valid radius styles: ${VALID_RADII.join(", ")}`
|
|
5553
|
+
});
|
|
5554
|
+
}
|
|
5555
|
+
const brandMatch = content.match(/\$fui-brand:\s*(#[0-9a-fA-F]+)/);
|
|
5556
|
+
if (brandMatch) {
|
|
5557
|
+
const hex = brandMatch[1];
|
|
5558
|
+
if (!/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(hex)) {
|
|
5559
|
+
checks.push({
|
|
5560
|
+
name: "SCSS seed: brand",
|
|
5561
|
+
status: "fail",
|
|
5562
|
+
message: `Invalid $fui-brand color: "${hex}" in ${pattern}`,
|
|
5563
|
+
fix: "Must be a valid hex color (e.g., #0066ff)"
|
|
5564
|
+
});
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5567
|
+
if (checks.length === 0) {
|
|
5568
|
+
checks.push({
|
|
5569
|
+
name: "SCSS seeds",
|
|
5570
|
+
status: "pass",
|
|
5571
|
+
message: `Seed values in ${pattern} are valid`
|
|
5572
|
+
});
|
|
5573
|
+
}
|
|
5574
|
+
return checks;
|
|
5575
|
+
} catch {
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
checks.push({
|
|
5579
|
+
name: "SCSS seeds",
|
|
5580
|
+
status: "pass",
|
|
5581
|
+
message: "No custom SCSS seeds configured (using defaults)"
|
|
5582
|
+
});
|
|
5583
|
+
return checks;
|
|
5584
|
+
}
|
|
5585
|
+
async function checkPeerDeps(root) {
|
|
5586
|
+
const checks = [];
|
|
5587
|
+
try {
|
|
5588
|
+
const pkgPath = join10(root, "package.json");
|
|
5589
|
+
const content = await readFile8(pkgPath, "utf-8");
|
|
5590
|
+
const pkg2 = JSON.parse(content);
|
|
5591
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
5592
|
+
if (!allDeps["react"]) {
|
|
5593
|
+
checks.push({
|
|
5594
|
+
name: "Peer dep: react",
|
|
5595
|
+
status: "fail",
|
|
5596
|
+
message: "react not found in dependencies (required)",
|
|
5597
|
+
fix: "npm install react react-dom"
|
|
5598
|
+
});
|
|
5599
|
+
} else {
|
|
5600
|
+
checks.push({
|
|
5601
|
+
name: "Peer dep: react",
|
|
5602
|
+
status: "pass",
|
|
5603
|
+
message: `react ${allDeps["react"]} installed`
|
|
5604
|
+
});
|
|
5605
|
+
}
|
|
5606
|
+
if (!allDeps["sass"]) {
|
|
5607
|
+
checks.push({
|
|
5608
|
+
name: "Peer dep: sass",
|
|
5609
|
+
status: "warn",
|
|
5610
|
+
message: "sass not installed (needed for custom SCSS theming)",
|
|
5611
|
+
fix: "npm install -D sass"
|
|
5612
|
+
});
|
|
5613
|
+
}
|
|
5614
|
+
const optionalPeers = [
|
|
5615
|
+
{ pkg: "recharts", components: "Chart" },
|
|
5616
|
+
{ pkg: "shiki", components: "CodeBlock" },
|
|
5617
|
+
{ pkg: "react-day-picker", components: "DatePicker" },
|
|
5618
|
+
{ pkg: "@tanstack/react-table", components: "DataTable" }
|
|
5619
|
+
];
|
|
5620
|
+
for (const peer of optionalPeers) {
|
|
5621
|
+
if (allDeps[peer.pkg]) {
|
|
5622
|
+
checks.push({
|
|
5623
|
+
name: `Optional dep: ${peer.pkg}`,
|
|
5624
|
+
status: "pass",
|
|
5625
|
+
message: `${peer.pkg} installed (enables ${peer.components})`
|
|
5626
|
+
});
|
|
5627
|
+
}
|
|
5628
|
+
}
|
|
5629
|
+
} catch {
|
|
5630
|
+
checks.push({
|
|
5631
|
+
name: "Peer dependencies",
|
|
5632
|
+
status: "fail",
|
|
5633
|
+
message: "Could not read package.json"
|
|
5634
|
+
});
|
|
5635
|
+
}
|
|
5636
|
+
return checks;
|
|
5637
|
+
}
|
|
5638
|
+
async function checkMcpConfig(root) {
|
|
5639
|
+
const mcpConfigPaths = [
|
|
5640
|
+
".mcp.json",
|
|
5641
|
+
".cursor/mcp.json",
|
|
5642
|
+
".vscode/mcp.json"
|
|
5643
|
+
];
|
|
5644
|
+
for (const configPath of mcpConfigPaths) {
|
|
5645
|
+
try {
|
|
5646
|
+
const fullPath = join10(root, configPath);
|
|
5647
|
+
const content = await readFile8(fullPath, "utf-8");
|
|
5648
|
+
const config = JSON.parse(content);
|
|
5649
|
+
const servers = config.mcpServers || config.servers || {};
|
|
5650
|
+
const hasFragments = Object.values(servers).some((server) => {
|
|
5651
|
+
const s = server;
|
|
5652
|
+
return s.args?.some((arg) => arg.includes("@fragments-sdk/mcp")) || s.command?.includes("fragments");
|
|
5653
|
+
});
|
|
5654
|
+
if (hasFragments) {
|
|
5655
|
+
return {
|
|
5656
|
+
name: "MCP configuration",
|
|
5657
|
+
status: "pass",
|
|
5658
|
+
message: `Fragments MCP server configured in ${configPath}`
|
|
5659
|
+
};
|
|
5660
|
+
}
|
|
5661
|
+
} catch {
|
|
5662
|
+
}
|
|
5663
|
+
}
|
|
5664
|
+
return {
|
|
5665
|
+
name: "MCP configuration",
|
|
5666
|
+
status: "warn",
|
|
5667
|
+
message: "No Fragments MCP server configuration found (optional)",
|
|
5668
|
+
fix: "Run `fragments init` or add @fragments-sdk/mcp to your MCP config"
|
|
5669
|
+
};
|
|
5670
|
+
}
|
|
5671
|
+
async function checkTypeScript(root) {
|
|
5672
|
+
try {
|
|
5673
|
+
const tsconfigPath = join10(root, "tsconfig.json");
|
|
5674
|
+
await access3(tsconfigPath);
|
|
5675
|
+
return {
|
|
5676
|
+
name: "TypeScript",
|
|
5677
|
+
status: "pass",
|
|
5678
|
+
message: "tsconfig.json found"
|
|
5679
|
+
};
|
|
5680
|
+
} catch {
|
|
5681
|
+
return {
|
|
5682
|
+
name: "TypeScript",
|
|
5683
|
+
status: "warn",
|
|
5684
|
+
message: "No tsconfig.json found (TypeScript recommended but not required)"
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5687
|
+
}
|
|
5688
|
+
async function doctor(options = {}) {
|
|
5689
|
+
const root = resolve8(options.root ?? process.cwd());
|
|
5690
|
+
const checks = [];
|
|
5691
|
+
if (!options.json) {
|
|
5692
|
+
console.log(pc22.cyan(`
|
|
5693
|
+
${BRAND.name} Doctor
|
|
5694
|
+
`));
|
|
5695
|
+
console.log(pc22.dim(`Checking project at ${root}
|
|
5696
|
+
`));
|
|
5697
|
+
}
|
|
5698
|
+
checks.push(await checkPackageInstalled(root));
|
|
5699
|
+
checks.push(await checkStylesImport(root));
|
|
5700
|
+
checks.push(await checkThemeProvider(root));
|
|
5701
|
+
checks.push(...await checkScssSeeds(root));
|
|
5702
|
+
checks.push(...await checkPeerDeps(root));
|
|
5703
|
+
checks.push(await checkMcpConfig(root));
|
|
5704
|
+
checks.push(await checkTypeScript(root));
|
|
5705
|
+
const passed = checks.filter((c) => c.status === "pass").length;
|
|
5706
|
+
const warned = checks.filter((c) => c.status === "warn").length;
|
|
5707
|
+
const failed = checks.filter((c) => c.status === "fail").length;
|
|
5708
|
+
const result = {
|
|
5709
|
+
success: failed === 0,
|
|
5710
|
+
checks,
|
|
5711
|
+
passed,
|
|
5712
|
+
warned,
|
|
5713
|
+
failed
|
|
5714
|
+
};
|
|
5715
|
+
if (options.json) {
|
|
5716
|
+
console.log(JSON.stringify(result, null, 2));
|
|
5717
|
+
} else {
|
|
5718
|
+
for (const check of checks) {
|
|
5719
|
+
const icon = check.status === "pass" ? pc22.green("\u2713") : check.status === "warn" ? pc22.yellow("!") : pc22.red("\u2717");
|
|
5720
|
+
const msg = check.status === "pass" ? check.message : check.status === "warn" ? pc22.yellow(check.message) : pc22.red(check.message);
|
|
5721
|
+
console.log(` ${icon} ${pc22.bold(check.name)}: ${msg}`);
|
|
5722
|
+
if (check.fix && check.status !== "pass") {
|
|
5723
|
+
console.log(pc22.dim(` \u2192 ${check.fix}`));
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
console.log();
|
|
5727
|
+
if (failed === 0 && warned === 0) {
|
|
5728
|
+
console.log(pc22.green(`\u2713 All ${passed} checks passed \u2014 your setup looks great!`));
|
|
5729
|
+
} else if (failed === 0) {
|
|
5730
|
+
console.log(pc22.green(`\u2713 ${passed} passed`) + pc22.yellow(`, ${warned} warning(s)`));
|
|
5731
|
+
} else {
|
|
5732
|
+
console.log(
|
|
5733
|
+
pc22.red(`\u2717 ${failed} failed`) + (warned > 0 ? pc22.yellow(`, ${warned} warning(s)`) : "") + pc22.dim(`, ${passed} passed`)
|
|
5734
|
+
);
|
|
5735
|
+
}
|
|
5736
|
+
console.log();
|
|
5737
|
+
}
|
|
5738
|
+
return result;
|
|
5739
|
+
}
|
|
5740
|
+
|
|
5366
5741
|
// src/bin.ts
|
|
5367
5742
|
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
5368
|
-
var pkg = JSON.parse(readFileSync(
|
|
5743
|
+
var pkg = JSON.parse(readFileSync(join11(__dirname, "../package.json"), "utf-8"));
|
|
5369
5744
|
var program = new Command();
|
|
5370
5745
|
program.name(BRAND.cliCommand).description(`${BRAND.name} - Design system documentation and compliance tool`).version(pkg.version);
|
|
5371
5746
|
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 +5750,7 @@ program.command("validate").description("Validate fragment files").option("-c, -
|
|
|
5375
5750
|
process.exit(1);
|
|
5376
5751
|
}
|
|
5377
5752
|
} catch (error) {
|
|
5378
|
-
console.error(
|
|
5753
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5379
5754
|
process.exit(1);
|
|
5380
5755
|
}
|
|
5381
5756
|
});
|
|
@@ -5395,7 +5770,7 @@ program.command("build").description(`Build compiled ${BRAND.outFile} and ${BRAN
|
|
|
5395
5770
|
process.exit(1);
|
|
5396
5771
|
}
|
|
5397
5772
|
} catch (error) {
|
|
5398
|
-
console.error(
|
|
5773
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5399
5774
|
process.exit(1);
|
|
5400
5775
|
}
|
|
5401
5776
|
});
|
|
@@ -5414,7 +5789,7 @@ program.command("context").description("Generate AI-ready context for your desig
|
|
|
5414
5789
|
process.exit(1);
|
|
5415
5790
|
}
|
|
5416
5791
|
} catch (error) {
|
|
5417
|
-
console.error(
|
|
5792
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5418
5793
|
process.exit(1);
|
|
5419
5794
|
}
|
|
5420
5795
|
});
|
|
@@ -5441,7 +5816,7 @@ program.command("ai").description("Generate context optimized for AI assistants
|
|
|
5441
5816
|
}
|
|
5442
5817
|
}
|
|
5443
5818
|
} catch (error) {
|
|
5444
|
-
console.error(
|
|
5819
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5445
5820
|
process.exit(1);
|
|
5446
5821
|
}
|
|
5447
5822
|
});
|
|
@@ -5449,7 +5824,7 @@ program.command("list").description("List all discovered fragment files").option
|
|
|
5449
5824
|
try {
|
|
5450
5825
|
await list(options);
|
|
5451
5826
|
} catch (error) {
|
|
5452
|
-
console.error(
|
|
5827
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5453
5828
|
process.exit(1);
|
|
5454
5829
|
}
|
|
5455
5830
|
});
|
|
@@ -5457,7 +5832,7 @@ program.command("reset").description("Reset to initial state (delete all generat
|
|
|
5457
5832
|
try {
|
|
5458
5833
|
await reset(options);
|
|
5459
5834
|
} catch (error) {
|
|
5460
|
-
console.error(
|
|
5835
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5461
5836
|
process.exit(1);
|
|
5462
5837
|
}
|
|
5463
5838
|
});
|
|
@@ -5471,7 +5846,7 @@ linkCommand.command("figma").argument("[figma-url]", "Figma file URL to link com
|
|
|
5471
5846
|
variants: options.variants
|
|
5472
5847
|
});
|
|
5473
5848
|
} catch (error) {
|
|
5474
|
-
console.error(
|
|
5849
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5475
5850
|
process.exit(1);
|
|
5476
5851
|
}
|
|
5477
5852
|
});
|
|
@@ -5486,7 +5861,7 @@ linkCommand.command("storybook").description("Bootstrap fragments from existing
|
|
|
5486
5861
|
exclude: options.exclude
|
|
5487
5862
|
});
|
|
5488
5863
|
} catch (error) {
|
|
5489
|
-
console.error(
|
|
5864
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5490
5865
|
process.exit(1);
|
|
5491
5866
|
}
|
|
5492
5867
|
});
|
|
@@ -5501,9 +5876,9 @@ program.command("dev").description("Start the development server with live compo
|
|
|
5501
5876
|
skipBuild: options.skipBuild
|
|
5502
5877
|
});
|
|
5503
5878
|
} catch (error) {
|
|
5504
|
-
console.error(
|
|
5879
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5505
5880
|
if (error instanceof Error && error.stack) {
|
|
5506
|
-
console.error(
|
|
5881
|
+
console.error(pc23.dim(error.stack));
|
|
5507
5882
|
}
|
|
5508
5883
|
process.exit(1);
|
|
5509
5884
|
}
|
|
@@ -5524,7 +5899,7 @@ program.command("screenshot").description("Capture screenshots of component vari
|
|
|
5524
5899
|
process.exit(1);
|
|
5525
5900
|
}
|
|
5526
5901
|
} catch (error) {
|
|
5527
|
-
console.error(
|
|
5902
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5528
5903
|
process.exit(1);
|
|
5529
5904
|
}
|
|
5530
5905
|
});
|
|
@@ -5543,7 +5918,7 @@ program.command("diff").argument("[component]", "Component name to diff (optiona
|
|
|
5543
5918
|
process.exit(1);
|
|
5544
5919
|
}
|
|
5545
5920
|
} catch (error) {
|
|
5546
|
-
console.error(
|
|
5921
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5547
5922
|
process.exit(1);
|
|
5548
5923
|
}
|
|
5549
5924
|
});
|
|
@@ -5562,8 +5937,8 @@ program.command("compare").argument("[component]", "Component name to compare").
|
|
|
5562
5937
|
process.exit(1);
|
|
5563
5938
|
}
|
|
5564
5939
|
} catch (error) {
|
|
5565
|
-
console.error(
|
|
5566
|
-
console.log(
|
|
5940
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5941
|
+
console.log(pc23.dim(`
|
|
5567
5942
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
5568
5943
|
process.exit(1);
|
|
5569
5944
|
}
|
|
@@ -5582,7 +5957,7 @@ program.command("analyze").description("Analyze design system and generate repor
|
|
|
5582
5957
|
process.exit(1);
|
|
5583
5958
|
}
|
|
5584
5959
|
} catch (error) {
|
|
5585
|
-
console.error(
|
|
5960
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5586
5961
|
process.exit(1);
|
|
5587
5962
|
}
|
|
5588
5963
|
});
|
|
@@ -5601,7 +5976,7 @@ program.command("verify").argument("[component]", "Component name to verify (opt
|
|
|
5601
5976
|
if (options.ci) {
|
|
5602
5977
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Verification failed" }));
|
|
5603
5978
|
} else {
|
|
5604
|
-
console.error(
|
|
5979
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5605
5980
|
}
|
|
5606
5981
|
process.exit(1);
|
|
5607
5982
|
}
|
|
@@ -5618,7 +5993,7 @@ program.command("audit").description("Scan all fragments and show compliance met
|
|
|
5618
5993
|
if (options.json) {
|
|
5619
5994
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "Audit failed" }));
|
|
5620
5995
|
} else {
|
|
5621
|
-
console.error(
|
|
5996
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5622
5997
|
}
|
|
5623
5998
|
process.exit(1);
|
|
5624
5999
|
}
|
|
@@ -5640,7 +6015,7 @@ program.command("a11y").description("Run accessibility checks on all component v
|
|
|
5640
6015
|
if (options.json) {
|
|
5641
6016
|
console.log(JSON.stringify({ error: error instanceof Error ? error.message : "A11y check failed" }));
|
|
5642
6017
|
} else {
|
|
5643
|
-
console.error(
|
|
6018
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5644
6019
|
}
|
|
5645
6020
|
process.exit(1);
|
|
5646
6021
|
}
|
|
@@ -5663,7 +6038,7 @@ program.command("enhance").description("AI-powered documentation generation from
|
|
|
5663
6038
|
if (options.format === "json") {
|
|
5664
6039
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : "Enhance failed" }));
|
|
5665
6040
|
} else {
|
|
5666
|
-
console.error(
|
|
6041
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5667
6042
|
}
|
|
5668
6043
|
process.exit(1);
|
|
5669
6044
|
}
|
|
@@ -5684,7 +6059,7 @@ program.command("scan").description(`Zero-config ${BRAND.outFile} generation fro
|
|
|
5684
6059
|
process.exit(1);
|
|
5685
6060
|
}
|
|
5686
6061
|
} catch (error) {
|
|
5687
|
-
console.error(
|
|
6062
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5688
6063
|
process.exit(1);
|
|
5689
6064
|
}
|
|
5690
6065
|
});
|
|
@@ -5697,7 +6072,7 @@ program.command("storygen").description("Generate Storybook stories from fragmen
|
|
|
5697
6072
|
format: options.format
|
|
5698
6073
|
});
|
|
5699
6074
|
} catch (error) {
|
|
5700
|
-
console.error(
|
|
6075
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5701
6076
|
process.exit(1);
|
|
5702
6077
|
}
|
|
5703
6078
|
});
|
|
@@ -5709,7 +6084,7 @@ program.command("metrics").argument("[component]", "Component name (optional, sh
|
|
|
5709
6084
|
json: options.json
|
|
5710
6085
|
});
|
|
5711
6086
|
} catch (error) {
|
|
5712
|
-
console.error(
|
|
6087
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5713
6088
|
process.exit(1);
|
|
5714
6089
|
}
|
|
5715
6090
|
});
|
|
@@ -5723,9 +6098,9 @@ program.command("baseline").description("Manage visual regression baselines").ar
|
|
|
5723
6098
|
port: options.port
|
|
5724
6099
|
});
|
|
5725
6100
|
} catch (error) {
|
|
5726
|
-
console.error(
|
|
6101
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5727
6102
|
if (action === "update") {
|
|
5728
|
-
console.log(
|
|
6103
|
+
console.log(pc23.dim(`
|
|
5729
6104
|
Make sure the dev server is running: ${BRAND.cliCommand} dev`));
|
|
5730
6105
|
}
|
|
5731
6106
|
process.exit(1);
|
|
@@ -5738,22 +6113,22 @@ program.command("view").description(`Generate a static HTML viewer for ${BRAND.o
|
|
|
5738
6113
|
const path = await import("path");
|
|
5739
6114
|
const inputPath = path.resolve(process.cwd(), options.input);
|
|
5740
6115
|
const outputPath = path.resolve(process.cwd(), options.output);
|
|
5741
|
-
console.log(
|
|
6116
|
+
console.log(pc23.cyan(`
|
|
5742
6117
|
${BRAND.name} Viewer Generator
|
|
5743
6118
|
`));
|
|
5744
6119
|
try {
|
|
5745
6120
|
await fs2.access(inputPath);
|
|
5746
6121
|
} catch {
|
|
5747
|
-
console.log(
|
|
5748
|
-
console.log(
|
|
5749
|
-
Run ${
|
|
6122
|
+
console.log(pc23.red(`Error: ${options.input} not found.`));
|
|
6123
|
+
console.log(pc23.dim(`
|
|
6124
|
+
Run ${pc23.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
5750
6125
|
`));
|
|
5751
6126
|
process.exit(1);
|
|
5752
6127
|
}
|
|
5753
|
-
console.log(
|
|
6128
|
+
console.log(pc23.dim(`Reading: ${options.input}`));
|
|
5754
6129
|
const html = await generateViewerFromJson(inputPath);
|
|
5755
6130
|
await fs2.writeFile(outputPath, html);
|
|
5756
|
-
console.log(
|
|
6131
|
+
console.log(pc23.green(`
|
|
5757
6132
|
\u2713 Generated: ${options.output}
|
|
5758
6133
|
`));
|
|
5759
6134
|
if (options.open) {
|
|
@@ -5762,7 +6137,7 @@ Run ${pc22.cyan(`${BRAND.cliCommand} build`)} first to generate ${BRAND.outFile}
|
|
|
5762
6137
|
exec(`${openCmd} "${outputPath}"`);
|
|
5763
6138
|
}
|
|
5764
6139
|
} catch (error) {
|
|
5765
|
-
console.error(
|
|
6140
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5766
6141
|
process.exit(1);
|
|
5767
6142
|
}
|
|
5768
6143
|
});
|
|
@@ -5775,27 +6150,27 @@ program.command("add").argument("[name]", 'Component name (e.g., "Button", "Text
|
|
|
5775
6150
|
component: options.component
|
|
5776
6151
|
});
|
|
5777
6152
|
} catch (error) {
|
|
5778
|
-
console.error(
|
|
6153
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5779
6154
|
process.exit(1);
|
|
5780
6155
|
}
|
|
5781
6156
|
});
|
|
5782
6157
|
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
6158
|
try {
|
|
5784
|
-
const { init } = await import("./init-
|
|
6159
|
+
const { init } = await import("./init-KSAAS7X3.js");
|
|
5785
6160
|
const result = await init({
|
|
5786
6161
|
projectRoot: process.cwd(),
|
|
5787
6162
|
force: options.force,
|
|
5788
6163
|
yes: options.yes
|
|
5789
6164
|
});
|
|
5790
6165
|
if (!result.success) {
|
|
5791
|
-
console.error(
|
|
6166
|
+
console.error(pc23.red("\nInit failed with errors:"));
|
|
5792
6167
|
for (const error of result.errors) {
|
|
5793
|
-
console.error(
|
|
6168
|
+
console.error(pc23.red(` - ${error}`));
|
|
5794
6169
|
}
|
|
5795
6170
|
process.exit(1);
|
|
5796
6171
|
}
|
|
5797
6172
|
} catch (error) {
|
|
5798
|
-
console.error(
|
|
6173
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5799
6174
|
process.exit(1);
|
|
5800
6175
|
}
|
|
5801
6176
|
});
|
|
@@ -5814,7 +6189,7 @@ program.command("tokens").description("Discover and list design tokens from CSS/
|
|
|
5814
6189
|
process.exit(1);
|
|
5815
6190
|
}
|
|
5816
6191
|
} catch (error) {
|
|
5817
|
-
console.error(
|
|
6192
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5818
6193
|
process.exit(1);
|
|
5819
6194
|
}
|
|
5820
6195
|
});
|
|
@@ -5828,11 +6203,11 @@ program.command("generate").description("Generate fragment files from component
|
|
|
5828
6203
|
componentPattern: options.pattern
|
|
5829
6204
|
});
|
|
5830
6205
|
if (!result.success) {
|
|
5831
|
-
console.error(
|
|
6206
|
+
console.error(pc23.red("\nGenerate completed with errors"));
|
|
5832
6207
|
process.exit(1);
|
|
5833
6208
|
}
|
|
5834
6209
|
} catch (error) {
|
|
5835
|
-
console.error(
|
|
6210
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5836
6211
|
process.exit(1);
|
|
5837
6212
|
}
|
|
5838
6213
|
});
|
|
@@ -5840,7 +6215,7 @@ program.command("graph").description("Query the component relationship graph").a
|
|
|
5840
6215
|
try {
|
|
5841
6216
|
await graph(component, options);
|
|
5842
6217
|
} catch (error) {
|
|
5843
|
-
console.error(
|
|
6218
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5844
6219
|
process.exit(1);
|
|
5845
6220
|
}
|
|
5846
6221
|
});
|
|
@@ -5858,7 +6233,7 @@ program.command("perf").description("Profile component bundle sizes and performa
|
|
|
5858
6233
|
process.exit(1);
|
|
5859
6234
|
}
|
|
5860
6235
|
} catch (error) {
|
|
5861
|
-
console.error(
|
|
6236
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5862
6237
|
process.exit(1);
|
|
5863
6238
|
}
|
|
5864
6239
|
});
|
|
@@ -5898,7 +6273,22 @@ program.command("test").description("Run interaction tests for fragments with pl
|
|
|
5898
6273
|
});
|
|
5899
6274
|
process.exit(exitCode);
|
|
5900
6275
|
} catch (error) {
|
|
5901
|
-
console.error(
|
|
6276
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
6277
|
+
process.exit(1);
|
|
6278
|
+
}
|
|
6279
|
+
});
|
|
6280
|
+
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) => {
|
|
6281
|
+
try {
|
|
6282
|
+
const result = await doctor({
|
|
6283
|
+
root: options.root,
|
|
6284
|
+
json: options.json,
|
|
6285
|
+
fix: options.fix
|
|
6286
|
+
});
|
|
6287
|
+
if (!result.success) {
|
|
6288
|
+
process.exit(1);
|
|
6289
|
+
}
|
|
6290
|
+
} catch (error) {
|
|
6291
|
+
console.error(pc23.red("Error:"), error instanceof Error ? error.message : error);
|
|
5902
6292
|
process.exit(1);
|
|
5903
6293
|
}
|
|
5904
6294
|
});
|