@fragments-sdk/cli 0.9.0 → 0.10.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.d.ts +1 -0
- package/dist/bin.js +502 -84
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-CJEGT3WD.js → chunk-566BNPQZ.js} +21 -6
- package/dist/chunk-566BNPQZ.js.map +1 -0
- package/dist/{chunk-WI6SLMSO.js → chunk-CAMXG5HJ.js} +5 -5
- package/dist/chunk-D2CDBRNU.js +2 -0
- package/dist/{chunk-YMPGYEWK.js → chunk-D5PYOXEI.js} +2 -2
- package/dist/{chunk-NGIMCIK2.js → chunk-OQO55NKV.js} +405 -34
- package/dist/chunk-OQO55NKV.js.map +1 -0
- package/dist/{chunk-TOIE7VXF.js → chunk-PW7QTQA6.js} +2 -2
- package/dist/{chunk-AWYCDRPG.js → chunk-WXSR2II7.js} +2 -2
- package/dist/chunk-WXSR2II7.js.map +1 -0
- package/dist/{chunk-2JIKCJX3.js → chunk-ZDA3PLQ6.js} +17 -14
- package/dist/chunk-ZDA3PLQ6.js.map +1 -0
- package/dist/core/index.d.ts +1 -2092
- package/dist/core/index.js +26 -21
- package/dist/{discovery-Z4RDDFVR.js → discovery-NEOY4MPN.js} +3 -3
- package/dist/generate-BGKTKO6E.js +459 -0
- package/dist/generate-BGKTKO6E.js.map +1 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/dist/{init-KSAAS7X3.js → init-Q53R5Q2T.js} +66 -76
- package/dist/init-Q53R5Q2T.js.map +1 -0
- package/dist/mcp-bin.js +5 -7
- package/dist/mcp-bin.js.map +1 -1
- package/dist/scan-OQU7M4GH.js +14 -0
- package/dist/scan-generate-T5QNUG7N.js +691 -0
- package/dist/scan-generate-T5QNUG7N.js.map +1 -0
- package/dist/{service-A5GIGGGK.js → service-TQYWY65E.js} +4 -5
- package/dist/{static-viewer-NSODM5VX.js → static-viewer-NUBFPKWH.js} +4 -5
- package/dist/static-viewer-NUBFPKWH.js.map +1 -0
- package/dist/{test-RPWZAYSJ.js → test-2CSOSS3B.js} +4 -5
- package/dist/{test-RPWZAYSJ.js.map → test-2CSOSS3B.js.map} +1 -1
- package/dist/{tokens-NIXSZRX7.js → tokens-DXEGYTOJ.js} +6 -7
- package/dist/{tokens-NIXSZRX7.js.map → tokens-DXEGYTOJ.js.map} +1 -1
- package/dist/{viewer-SBTJDMP7.js → viewer-DBEPYM3G.js} +245 -23
- package/dist/viewer-DBEPYM3G.js.map +1 -0
- package/package.json +2 -1
- package/src/bin.ts +33 -1
- package/src/build.ts +13 -3
- package/src/commands/__tests__/scan-generate.test.ts +308 -0
- package/src/commands/build.ts +16 -2
- package/src/commands/generate.ts +383 -68
- package/src/commands/init.ts +81 -56
- package/src/commands/perf.ts +1 -1
- package/src/commands/scan-generate.ts +1013 -0
- package/src/commands/setup.ts +499 -0
- package/src/core/auto-props.ts +1 -1
- package/src/core/bundle-measurer.ts +2 -2
- package/src/core/config.ts +16 -4
- package/src/core/discovery.ts +2 -2
- package/src/core/generators/context.ts +1 -1
- package/src/core/generators/registry.ts +3 -3
- package/src/core/generators/typescript-extractor.ts +11 -1
- package/src/core/graph-extractor.ts +1 -1
- package/src/core/index.ts +3 -190
- package/src/core/loader.ts +2 -2
- package/src/core/parser.ts +1 -1
- package/src/core/previewLoader.ts +1 -1
- package/src/index.ts +2 -2
- package/src/migrate/converter.ts +9 -1
- package/src/migrate/parser.ts +2 -0
- package/src/migrate/types.ts +2 -0
- package/src/service/snippet-validation.test.ts +1 -1
- package/src/service/snippet-validation.ts +2 -2
- package/src/setup.ts +69 -24
- package/src/viewer/__tests__/viewer-integration.test.ts +4 -10
- 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 +169 -2
- 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/DocsHeaderBar.tsx +6 -18
- package/src/viewer/vendor/shared/src/DocsPageShell.tsx +5 -0
- package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +5 -16
- 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 +114 -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/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-AWYCDRPG.js.map +0 -1
- package/dist/chunk-CJEGT3WD.js.map +0 -1
- package/dist/chunk-EKLMXTWU.js +0 -80
- package/dist/chunk-EKLMXTWU.js.map +0 -1
- package/dist/chunk-GOVI6COW.js +0 -195
- package/dist/chunk-GOVI6COW.js.map +0 -1
- package/dist/chunk-NGIMCIK2.js.map +0 -1
- package/dist/defineFragment-D0UTve-I.d.ts +0 -665
- package/dist/generate-35OIMW4Y.js +0 -252
- package/dist/generate-35OIMW4Y.js.map +0 -1
- package/dist/init-KSAAS7X3.js.map +0 -1
- package/dist/scan-65RH3QMM.js +0 -15
- package/dist/viewer-SBTJDMP7.js.map +0 -1
- package/src/core/__tests__/preview-runtime.test.tsx +0 -111
- package/src/core/composition.test.ts +0 -262
- package/src/core/composition.ts +0 -318
- package/src/core/constants.ts +0 -114
- package/src/core/context.ts +0 -2
- package/src/core/defineFragment.ts +0 -141
- package/src/core/figma.ts +0 -263
- package/src/core/fragment-types.ts +0 -214
- package/src/core/performance-presets.ts +0 -142
- package/src/core/preview-runtime.tsx +0 -144
- package/src/core/schema.ts +0 -221
- package/src/core/storyAdapter.test.ts +0 -571
- package/src/core/storyAdapter.ts +0 -761
- package/src/core/storybook-csf.ts +0 -11
- package/src/core/token-parser.ts +0 -321
- package/src/core/token-types.ts +0 -287
- package/src/core/types.ts +0 -762
- /package/dist/{chunk-WI6SLMSO.js.map → chunk-CAMXG5HJ.js.map} +0 -0
- /package/dist/{discovery-Z4RDDFVR.js.map → chunk-D2CDBRNU.js.map} +0 -0
- /package/dist/{chunk-YMPGYEWK.js.map → chunk-D5PYOXEI.js.map} +0 -0
- /package/dist/{chunk-TOIE7VXF.js.map → chunk-PW7QTQA6.js.map} +0 -0
- /package/dist/{scan-65RH3QMM.js.map → discovery-NEOY4MPN.js.map} +0 -0
- /package/dist/{service-A5GIGGGK.js.map → scan-OQU7M4GH.js.map} +0 -0
- /package/dist/{static-viewer-NSODM5VX.js.map → service-TQYWY65E.js.map} +0 -0
package/src/commands/init.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* fragments init - Smart interactive initialization
|
|
3
3
|
*
|
|
4
|
-
* Handles
|
|
5
|
-
* 1.
|
|
6
|
-
* 2.
|
|
7
|
-
* 3.
|
|
4
|
+
* Handles four scenarios:
|
|
5
|
+
* 1. --scan <path> → Scan external component library, generate fragment files
|
|
6
|
+
* 2. Stories found → Configure and load existing stories
|
|
7
|
+
* 3. Components found (no stories) → Auto-generate documentation
|
|
8
|
+
* 4. Fresh project → Guided setup with example component
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
import { readFile, writeFile, mkdir, access } from "node:fs/promises";
|
|
@@ -29,12 +30,14 @@ export interface InitOptions {
|
|
|
29
30
|
yes?: boolean;
|
|
30
31
|
/** Explicit framework override */
|
|
31
32
|
framework?: string;
|
|
33
|
+
/** Path to scan for components (enables scan mode) */
|
|
34
|
+
scan?: string;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export interface InitResult {
|
|
35
38
|
success: boolean;
|
|
36
39
|
configPath?: string;
|
|
37
|
-
scenario: "stories" | "components" | "fresh";
|
|
40
|
+
scenario: "stories" | "components" | "fresh" | "scan";
|
|
38
41
|
storiesFound: number;
|
|
39
42
|
componentsFound: number;
|
|
40
43
|
errors: string[];
|
|
@@ -396,6 +399,70 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
396
399
|
const projectRoot = resolve(options.projectRoot || process.cwd());
|
|
397
400
|
const errors: string[] = [];
|
|
398
401
|
|
|
402
|
+
// Early return for scan mode — non-interactive
|
|
403
|
+
if (options.scan) {
|
|
404
|
+
const scanPath = resolve(projectRoot, options.scan);
|
|
405
|
+
|
|
406
|
+
// Verify scan path exists
|
|
407
|
+
try {
|
|
408
|
+
await access(scanPath);
|
|
409
|
+
} catch {
|
|
410
|
+
console.error(pc.red(`\nScan path not found: ${scanPath}\n`));
|
|
411
|
+
return {
|
|
412
|
+
success: false,
|
|
413
|
+
scenario: "scan",
|
|
414
|
+
storiesFound: 0,
|
|
415
|
+
componentsFound: 0,
|
|
416
|
+
errors: [`Scan path not found: ${scanPath}`],
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Run scan-generate
|
|
421
|
+
const { scanGenerate } = await import("./scan-generate.js");
|
|
422
|
+
const scanResult = await scanGenerate({
|
|
423
|
+
scanPath,
|
|
424
|
+
force: options.force,
|
|
425
|
+
verbose: true,
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// Create config pointing at the scanned path
|
|
429
|
+
const relScanPath = relative(projectRoot, scanPath);
|
|
430
|
+
const configPath = join(projectRoot, BRAND.configFile);
|
|
431
|
+
const configContent = generateConfig({
|
|
432
|
+
includePaths: [`${relScanPath}/**/*.fragment.tsx`],
|
|
433
|
+
componentPaths: [`${relScanPath}/**/*.tsx`],
|
|
434
|
+
framework: "react",
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
try {
|
|
438
|
+
await writeFile(configPath, configContent, "utf-8");
|
|
439
|
+
console.log(pc.green(`✓ Created ${BRAND.configFile}`));
|
|
440
|
+
} catch (e) {
|
|
441
|
+
errors.push(`Failed to create config: ${e}`);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Next steps
|
|
445
|
+
if (scanResult.success) {
|
|
446
|
+
console.log(pc.cyan("Next steps:"));
|
|
447
|
+
console.log(` 1. Search generated files for ${pc.bold("TODO:")} markers and fill in human knowledge`);
|
|
448
|
+
console.log(` 2. Run ${pc.bold(`${BRAND.cliCommand} dev`)} to preview your components`);
|
|
449
|
+
console.log(` 3. Run ${pc.bold(`${BRAND.cliCommand} build`)} to compile fragments.json`);
|
|
450
|
+
console.log();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return {
|
|
454
|
+
success: scanResult.success && errors.length === 0,
|
|
455
|
+
configPath: errors.length === 0 ? configPath : undefined,
|
|
456
|
+
scenario: "scan",
|
|
457
|
+
storiesFound: 0,
|
|
458
|
+
componentsFound: scanResult.generated.length,
|
|
459
|
+
errors: [
|
|
460
|
+
...errors,
|
|
461
|
+
...scanResult.errors.map((e) => `${e.name}: ${e.error}`),
|
|
462
|
+
],
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
|
|
399
466
|
console.log(pc.cyan(`\n✨ Welcome to ${BRAND.name}!\n`));
|
|
400
467
|
|
|
401
468
|
// Step 1: Detect what exists
|
|
@@ -462,9 +529,9 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
462
529
|
|
|
463
530
|
// Step 3: Gather configuration (interactive unless --yes)
|
|
464
531
|
let componentPath = detection.suggestedComponentPath;
|
|
465
|
-
let runScan = scenario === "components";
|
|
532
|
+
let runScan = scenario === "components" || scenario === "stories";
|
|
466
533
|
let createExample = scenario === "fresh";
|
|
467
|
-
let startServer =
|
|
534
|
+
let startServer = false;
|
|
468
535
|
|
|
469
536
|
if (!options.yes) {
|
|
470
537
|
// Ask about component location
|
|
@@ -473,13 +540,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
473
540
|
default: detection.suggestedComponentPath,
|
|
474
541
|
});
|
|
475
542
|
|
|
476
|
-
if (scenario === "
|
|
477
|
-
// For component-only projects, ask about scanning
|
|
478
|
-
runScan = await confirm({
|
|
479
|
-
message: "Auto-generate documentation from TypeScript?",
|
|
480
|
-
default: true,
|
|
481
|
-
});
|
|
482
|
-
} else {
|
|
543
|
+
if (scenario === "fresh") {
|
|
483
544
|
// Fresh project - ask about example
|
|
484
545
|
createExample = await confirm({
|
|
485
546
|
message: "Create an example Button component to get started?",
|
|
@@ -502,7 +563,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
502
563
|
`${componentPath}/**/*.fragment.tsx`,
|
|
503
564
|
];
|
|
504
565
|
|
|
505
|
-
//
|
|
566
|
+
// If Storybook stories detected, also include them for direct rendering
|
|
506
567
|
if (scenario === 'stories') {
|
|
507
568
|
includePaths.push(`${componentPath}/**/*.stories.tsx`);
|
|
508
569
|
includePaths.push(`${componentPath}/**/*.stories.ts`);
|
|
@@ -557,39 +618,9 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
557
618
|
}
|
|
558
619
|
}
|
|
559
620
|
|
|
560
|
-
if (
|
|
561
|
-
//
|
|
562
|
-
|
|
563
|
-
for (const compFile of detection.componentFiles) {
|
|
564
|
-
const absPath = join(projectRoot, compFile);
|
|
565
|
-
const dir = dirname(absPath);
|
|
566
|
-
const fileName = basename(compFile, ".tsx");
|
|
567
|
-
const componentName = toPascalCase(fileName);
|
|
568
|
-
const fragmentPath = join(dir, `${fileName}.fragment.tsx`);
|
|
569
|
-
|
|
570
|
-
// Skip if fragment already exists
|
|
571
|
-
try {
|
|
572
|
-
await access(fragmentPath);
|
|
573
|
-
continue; // already exists
|
|
574
|
-
} catch {
|
|
575
|
-
// doesn't exist, create it
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
try {
|
|
579
|
-
const stub = generateFragmentStub(componentName, `./${fileName}`);
|
|
580
|
-
await writeFile(fragmentPath, stub, "utf-8");
|
|
581
|
-
stubsCreated++;
|
|
582
|
-
} catch {
|
|
583
|
-
// skip files we can't write to
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (stubsCreated > 0) {
|
|
588
|
-
console.log(pc.green(`✓ Generated ${stubsCreated} fragment stub(s)`));
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// Run scan to generate fragments.json
|
|
592
|
-
console.log(pc.dim("\nGenerating documentation from source code...\n"));
|
|
621
|
+
if (runScan) {
|
|
622
|
+
// Run scan to generate fragments.json from source code
|
|
623
|
+
console.log(pc.dim("\nScanning source code for documentation...\n"));
|
|
593
624
|
try {
|
|
594
625
|
const { scan } = await import("./scan.js");
|
|
595
626
|
await scan({
|
|
@@ -641,14 +672,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
641
672
|
console.log(pc.green("\n✓ Setup complete!\n"));
|
|
642
673
|
|
|
643
674
|
if (startServer) {
|
|
644
|
-
|
|
645
|
-
scenario === "stories"
|
|
646
|
-
? `Your ${detection.storyFiles.length} stories are loading...`
|
|
647
|
-
: scenario === "components"
|
|
648
|
-
? `Your ${detection.componentFiles.length} components are being documented...`
|
|
649
|
-
: `Your first component is ready!`;
|
|
650
|
-
|
|
651
|
-
console.log(pc.cyan(serverMessage));
|
|
675
|
+
console.log(pc.cyan("Starting viewer...\n"));
|
|
652
676
|
startDevServer(projectRoot);
|
|
653
677
|
} else {
|
|
654
678
|
console.log(pc.cyan("Next steps:"));
|
|
@@ -656,6 +680,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
|
|
|
656
680
|
if (scenario === "fresh") {
|
|
657
681
|
console.log(` 2. Edit ${pc.bold(`${componentPath}/Button/Button.fragment.tsx`)}`);
|
|
658
682
|
}
|
|
683
|
+
console.log(` 3. Run ${pc.bold(`${BRAND.cliCommand} generate`)} to create fragment files for your components`);
|
|
659
684
|
console.log();
|
|
660
685
|
}
|
|
661
686
|
}
|