@fragments-sdk/cli 0.7.0 → 0.7.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 +245 -245
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-XHUDJNN3.js → chunk-32VIEOQY.js} +18 -18
- package/dist/chunk-32VIEOQY.js.map +1 -0
- package/dist/{chunk-CVXKXVOY.js → chunk-5ITIP3ES.js} +27 -27
- package/dist/chunk-5ITIP3ES.js.map +1 -0
- package/dist/{chunk-RVRTRESS.js → chunk-DQHWLAUV.js} +29 -29
- package/dist/chunk-DQHWLAUV.js.map +1 -0
- package/dist/{chunk-TJ34N7C7.js → chunk-GCZMFLDI.js} +30 -32
- package/dist/chunk-GCZMFLDI.js.map +1 -0
- package/dist/{chunk-6JBGU74P.js → chunk-GHYYFAQN.js} +23 -23
- package/dist/chunk-GHYYFAQN.js.map +1 -0
- package/dist/{chunk-NWQ4CJOQ.js → chunk-GKX2HPZ6.js} +40 -40
- package/dist/chunk-GKX2HPZ6.js.map +1 -0
- package/dist/{chunk-7OPWMLOE.js → chunk-U6VTHBNI.js} +110 -110
- package/dist/chunk-U6VTHBNI.js.map +1 -0
- package/dist/{core-W2HYIQW6.js → core-SFHPYR5H.js} +24 -26
- package/dist/{generate-LMTISDIJ.js → generate-54GJAWUY.js} +5 -5
- package/dist/generate-54GJAWUY.js.map +1 -0
- package/dist/index.d.ts +23 -27
- package/dist/index.js +10 -10
- package/dist/{init-7CHRKQ7P.js → init-EIM5WNMP.js} +5 -5
- package/dist/{init-7CHRKQ7P.js.map → init-EIM5WNMP.js.map} +1 -1
- package/dist/mcp-bin.js +73 -73
- package/dist/mcp-bin.js.map +1 -1
- package/dist/scan-KQBKUS64.js +12 -0
- package/dist/{service-T2L7VLTE.js → service-ED2LNCTU.js} +6 -6
- package/dist/{static-viewer-GBR7YNF3.js → static-viewer-Q4F4QP5M.js} +4 -4
- package/dist/{test-OJRXNDO2.js → test-6VN2DA3S.js} +19 -19
- package/dist/test-6VN2DA3S.js.map +1 -0
- package/dist/{tokens-3BWDESVM.js → tokens-P2B7ZAM3.js} +5 -5
- package/dist/{viewer-SUFOISZM.js → viewer-GM7IQPPB.js} +199 -199
- package/dist/viewer-GM7IQPPB.js.map +1 -0
- package/package.json +2 -2
- package/src/ai.ts +5 -5
- package/src/analyze.ts +11 -11
- package/src/bin.ts +1 -1
- package/src/build.ts +33 -33
- package/src/commands/a11y.ts +6 -6
- package/src/commands/add.ts +11 -11
- package/src/commands/audit.ts +4 -4
- package/src/commands/baseline.ts +3 -3
- package/src/commands/build.ts +8 -8
- package/src/commands/compare.ts +20 -20
- package/src/commands/context.ts +16 -16
- package/src/commands/enhance.ts +36 -36
- package/src/commands/generate.ts +1 -1
- package/src/commands/graph.ts +3 -3
- package/src/commands/init.ts +1 -1
- package/src/commands/link/figma.ts +82 -82
- package/src/commands/link/index.ts +3 -3
- package/src/commands/link/storybook.ts +9 -9
- package/src/commands/list.ts +2 -2
- package/src/commands/reset.ts +15 -15
- package/src/commands/scan.ts +27 -27
- package/src/commands/storygen.ts +24 -24
- package/src/commands/validate.ts +2 -2
- package/src/commands/verify.ts +8 -8
- package/src/core/auto-props.ts +4 -4
- package/src/core/composition.test.ts +36 -36
- package/src/core/composition.ts +19 -19
- package/src/core/config.ts +6 -6
- package/src/core/{defineSegment.ts → defineFragment.ts} +16 -22
- package/src/core/discovery.ts +6 -6
- package/src/core/figma.ts +2 -2
- package/src/core/graph-extractor.test.ts +77 -77
- package/src/core/graph-extractor.ts +32 -32
- package/src/core/importAnalyzer.ts +1 -1
- package/src/core/index.ts +22 -23
- package/src/core/loader.ts +22 -22
- package/src/core/node.ts +5 -5
- package/src/core/parser.ts +31 -31
- package/src/core/previewLoader.ts +1 -1
- package/src/core/schema.ts +16 -16
- package/src/core/storyAdapter.test.ts +87 -87
- package/src/core/storyAdapter.ts +16 -16
- package/src/core/types.ts +21 -26
- package/src/diff.ts +22 -22
- package/src/index.ts +2 -2
- package/src/mcp/server.ts +80 -80
- package/src/migrate/__tests__/utils/utils.test.ts +3 -3
- package/src/migrate/bin.ts +4 -4
- package/src/migrate/converter.ts +16 -16
- package/src/migrate/index.ts +3 -3
- package/src/migrate/migrate.ts +3 -3
- package/src/migrate/parser.ts +8 -8
- package/src/migrate/report.ts +2 -2
- package/src/migrate/types.ts +4 -4
- package/src/screenshot.ts +22 -22
- package/src/service/__tests__/props-extractor.test.ts +15 -15
- package/src/service/analytics.ts +39 -39
- package/src/service/enhance/codebase-scanner.ts +1 -1
- package/src/service/enhance/index.ts +1 -1
- package/src/service/enhance/props-extractor.ts +2 -2
- package/src/service/enhance/types.ts +2 -2
- package/src/service/index.ts +2 -2
- package/src/service/metrics-store.ts +1 -1
- package/src/service/patch-generator.ts +1 -1
- package/src/setup.ts +52 -52
- package/src/shared/dev-server-client.ts +7 -7
- package/src/shared/fragment-loader.ts +59 -0
- package/src/shared/index.ts +1 -1
- package/src/shared/types.ts +4 -4
- package/src/static-viewer.ts +35 -35
- package/src/test/discovery.ts +6 -6
- package/src/test/index.ts +5 -5
- package/src/test/reporters/console.ts +1 -1
- package/src/test/reporters/junit.ts +1 -1
- package/src/test/runner.ts +7 -7
- package/src/test/types.ts +3 -3
- package/src/test/watch.ts +9 -9
- package/src/validators.ts +26 -26
- package/src/viewer/__tests__/render-utils.test.ts +28 -28
- package/src/viewer/__tests__/viewer-integration.test.ts +4 -4
- package/src/viewer/cli/health.ts +26 -26
- package/src/viewer/components/App.tsx +79 -79
- package/src/viewer/components/BottomPanel.tsx +17 -17
- package/src/viewer/components/CodePanel.tsx +3 -3
- package/src/viewer/components/CommandPalette.tsx +11 -11
- package/src/viewer/components/ComponentGraph.tsx +28 -28
- package/src/viewer/components/ComponentHeader.tsx +2 -2
- package/src/viewer/components/ContractPanel.tsx +6 -6
- package/src/viewer/components/FigmaEmbed.tsx +9 -9
- package/src/viewer/components/HealthDashboard.tsx +17 -17
- package/src/viewer/components/InteractionsPanel.tsx +2 -2
- package/src/viewer/components/IsolatedPreviewFrame.tsx +6 -6
- package/src/viewer/components/IsolatedRender.tsx +10 -10
- package/src/viewer/components/LeftSidebar.tsx +28 -28
- package/src/viewer/components/MultiViewportPreview.tsx +14 -14
- package/src/viewer/components/PreviewArea.tsx +11 -11
- package/src/viewer/components/PreviewFrameHost.tsx +51 -51
- package/src/viewer/components/RightSidebar.tsx +9 -9
- package/src/viewer/components/Sidebar.tsx +17 -17
- package/src/viewer/components/StoryRenderer.tsx +2 -2
- package/src/viewer/components/TokenStylePanel.tsx +1 -1
- package/src/viewer/components/UsageSection.tsx +2 -2
- package/src/viewer/components/VariantMatrix.tsx +11 -11
- package/src/viewer/components/VariantRenderer.tsx +3 -3
- package/src/viewer/components/VariantTabs.tsx +2 -2
- package/src/viewer/components/_future/CreatePage.tsx +6 -6
- package/src/viewer/composition-renderer.ts +11 -11
- package/src/viewer/entry.tsx +40 -40
- package/src/viewer/hooks/useFigmaIntegration.ts +1 -1
- package/src/viewer/hooks/usePreviewBridge.ts +5 -5
- package/src/viewer/hooks/useUrlState.ts +6 -6
- package/src/viewer/index.ts +2 -2
- package/src/viewer/intelligence/healthReport.ts +17 -17
- package/src/viewer/intelligence/styleDrift.ts +1 -1
- package/src/viewer/intelligence/usageScanner.ts +1 -1
- package/src/viewer/render-template.html +1 -1
- package/src/viewer/render-utils.ts +21 -21
- package/src/viewer/server.ts +18 -18
- package/src/viewer/utils/detectRelationships.ts +22 -22
- package/src/viewer/vite-plugin.ts +213 -213
- package/dist/chunk-6JBGU74P.js.map +0 -1
- package/dist/chunk-7OPWMLOE.js.map +0 -1
- package/dist/chunk-CVXKXVOY.js.map +0 -1
- package/dist/chunk-NWQ4CJOQ.js.map +0 -1
- package/dist/chunk-RVRTRESS.js.map +0 -1
- package/dist/chunk-TJ34N7C7.js.map +0 -1
- package/dist/chunk-XHUDJNN3.js.map +0 -1
- package/dist/generate-LMTISDIJ.js.map +0 -1
- package/dist/scan-WY23TJCP.js +0 -12
- package/dist/test-OJRXNDO2.js.map +0 -1
- package/dist/viewer-SUFOISZM.js.map +0 -1
- package/src/shared/segment-loader.ts +0 -59
- /package/dist/{core-W2HYIQW6.js.map → core-SFHPYR5H.js.map} +0 -0
- /package/dist/{scan-WY23TJCP.js.map → scan-KQBKUS64.js.map} +0 -0
- /package/dist/{service-T2L7VLTE.js.map → service-ED2LNCTU.js.map} +0 -0
- /package/dist/{static-viewer-GBR7YNF3.js.map → static-viewer-Q4F4QP5M.js.map} +0 -0
- /package/dist/{tokens-3BWDESVM.js.map → tokens-P2B7ZAM3.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
convertToFragmentProps,
|
|
4
4
|
extractPropsFromFile,
|
|
5
5
|
filterBoilerplate,
|
|
6
6
|
generateComponentContext,
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
inferAllRelations,
|
|
9
9
|
parseAllStories,
|
|
10
10
|
scanCodebase
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GKX2HPZ6.js";
|
|
12
12
|
import {
|
|
13
13
|
discoverAllComponents,
|
|
14
14
|
loadConfig
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5ITIP3ES.js";
|
|
16
16
|
import {
|
|
17
17
|
BRAND
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-GHYYFAQN.js";
|
|
19
19
|
|
|
20
20
|
// src/commands/scan.ts
|
|
21
21
|
import { writeFile, mkdir } from "fs/promises";
|
|
@@ -31,17 +31,17 @@ async function scan(options = {}) {
|
|
|
31
31
|
try {
|
|
32
32
|
const loaded = await loadConfig(options.config);
|
|
33
33
|
configDir = loaded.configDir;
|
|
34
|
-
outputFile = options.output || loaded.config.outFile || "
|
|
34
|
+
outputFile = options.output || loaded.config.outFile || "fragments.json";
|
|
35
35
|
componentPatterns = options.componentPatterns || loaded.config.components;
|
|
36
36
|
} catch {
|
|
37
37
|
configDir = process.cwd();
|
|
38
|
-
outputFile = options.output || "
|
|
38
|
+
outputFile = options.output || "fragments.json";
|
|
39
39
|
componentPatterns = options.componentPatterns;
|
|
40
40
|
}
|
|
41
41
|
console.log(pc.cyan(`
|
|
42
42
|
${BRAND.name} Scan
|
|
43
43
|
`));
|
|
44
|
-
console.log(pc.dim("Zero-config
|
|
44
|
+
console.log(pc.dim("Zero-config fragments.json generation from source code\n"));
|
|
45
45
|
console.log(pc.dim("Phase 1: Discovering components..."));
|
|
46
46
|
const components = await discoverAllComponents(configDir, {
|
|
47
47
|
patterns: componentPatterns,
|
|
@@ -82,7 +82,7 @@ ${BRAND.name} Scan
|
|
|
82
82
|
});
|
|
83
83
|
propsResults.set(comp.name, extraction);
|
|
84
84
|
if (extraction.success && extraction.props.length > 0) {
|
|
85
|
-
propsMap.set(comp.name,
|
|
85
|
+
propsMap.set(comp.name, convertToFragmentProps(extraction.props));
|
|
86
86
|
propsExtracted++;
|
|
87
87
|
}
|
|
88
88
|
} catch (e) {
|
|
@@ -156,11 +156,11 @@ ${BRAND.name} Scan
|
|
|
156
156
|
} else {
|
|
157
157
|
console.log(pc.dim("\nPhase 4: Skipping Storybook parsing"));
|
|
158
158
|
}
|
|
159
|
-
console.log(pc.dim("\nPhase 5: Generating
|
|
160
|
-
const
|
|
159
|
+
console.log(pc.dim("\nPhase 5: Generating fragments..."));
|
|
160
|
+
const fragments = {};
|
|
161
161
|
for (const comp of components) {
|
|
162
162
|
try {
|
|
163
|
-
const
|
|
163
|
+
const fragment = generateFragmentFromData(
|
|
164
164
|
comp,
|
|
165
165
|
configDir,
|
|
166
166
|
propsMap.get(comp.name),
|
|
@@ -168,7 +168,7 @@ ${BRAND.name} Scan
|
|
|
168
168
|
allRelations.get(comp.name),
|
|
169
169
|
storiesMap.get(comp.name)
|
|
170
170
|
);
|
|
171
|
-
|
|
171
|
+
fragments[comp.name] = fragment;
|
|
172
172
|
} catch (e) {
|
|
173
173
|
errors.push({
|
|
174
174
|
component: comp.name,
|
|
@@ -181,15 +181,15 @@ ${BRAND.name} Scan
|
|
|
181
181
|
const output = {
|
|
182
182
|
version: "1.0.0",
|
|
183
183
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
184
|
-
|
|
184
|
+
fragments
|
|
185
185
|
};
|
|
186
186
|
await writeFile(outputPath, JSON.stringify(output, null, 2));
|
|
187
187
|
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
188
188
|
console.log(pc.dim("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
189
189
|
console.log(pc.green(`
|
|
190
|
-
\u2713 Generated
|
|
190
|
+
\u2713 Generated fragments.json in ${elapsed}s`));
|
|
191
191
|
console.log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));
|
|
192
|
-
console.log(pc.dim(` Components: ${Object.keys(
|
|
192
|
+
console.log(pc.dim(` Components: ${Object.keys(fragments).length}`));
|
|
193
193
|
console.log(pc.dim(` Props extracted: ${propsExtracted}`));
|
|
194
194
|
console.log(pc.dim(` Usages found: ${usagesFound}`));
|
|
195
195
|
console.log(pc.dim(` Relations inferred: ${allRelations.size}`));
|
|
@@ -214,7 +214,7 @@ ${BRAND.name} Scan
|
|
|
214
214
|
return {
|
|
215
215
|
success: errors.length === 0,
|
|
216
216
|
outputPath,
|
|
217
|
-
componentCount: Object.keys(
|
|
217
|
+
componentCount: Object.keys(fragments).length,
|
|
218
218
|
propsExtracted,
|
|
219
219
|
usagesFound,
|
|
220
220
|
relationsInferred: allRelations.size,
|
|
@@ -223,7 +223,7 @@ ${BRAND.name} Scan
|
|
|
223
223
|
warnings
|
|
224
224
|
};
|
|
225
225
|
}
|
|
226
|
-
function
|
|
226
|
+
function generateFragmentFromData(comp, configDir, props, usageAnalysis, relations, storyFile) {
|
|
227
227
|
const context = generateComponentContext(
|
|
228
228
|
comp.name,
|
|
229
229
|
usageAnalysis,
|
|
@@ -366,4 +366,4 @@ function calculateConfidence(props, usageAnalysis, storyFile) {
|
|
|
366
366
|
export {
|
|
367
367
|
scan
|
|
368
368
|
};
|
|
369
|
-
//# sourceMappingURL=chunk-
|
|
369
|
+
//# sourceMappingURL=chunk-32VIEOQY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/scan.ts"],"sourcesContent":["/**\n * fragments scan - Zero-config fragments.json generation from source code\n *\n * Automatically extracts component documentation by:\n * 1. Discovering components from source files and barrel exports\n * 2. Extracting props from TypeScript interfaces\n * 3. Scanning codebase for usage patterns\n * 4. Parsing Storybook stories for examples\n * 5. Inferring component relationships from usage data\n * 6. Generating complete fragments.json without manual documentation\n */\n\nimport { writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join, dirname, relative } from \"node:path\";\nimport pc from \"picocolors\";\nimport {\n BRAND,\n type CompiledFragmentsFile,\n type CompiledFragment,\n type PropDefinition,\n} from \"../core/index.js\";\nimport {\n loadConfig,\n discoverAllComponents,\n type DiscoveredComponent,\n} from \"../core/node.js\";\nimport {\n scanCodebase,\n extractPropsFromFile,\n parseAllStories,\n inferAllRelations,\n generateComponentContext,\n generateEnhancementSuggestions,\n filterBoilerplate,\n convertToFragmentProps,\n type UsageAnalysis,\n type ComponentRelation,\n type PropsExtractionResult,\n type ParsedStoryFile,\n} from \"../service/index.js\";\n\nexport interface ScanOptions {\n /** Path to config file */\n config?: string;\n /** Output file path (default: fragments.json) */\n output?: string;\n /** Component patterns to scan */\n componentPatterns?: string[];\n /** Barrel export files to parse */\n barrelFiles?: string[];\n /** Directory to scan for usage patterns */\n usageDir?: string;\n /** Skip usage analysis */\n skipUsage?: boolean;\n /** Skip Storybook parsing */\n skipStorybook?: boolean;\n /** Verbose output */\n verbose?: boolean;\n}\n\nexport interface ScanResult {\n success: boolean;\n outputPath: string;\n componentCount: number;\n propsExtracted: number;\n usagesFound: number;\n relationsInferred: number;\n storiesParsed: number;\n errors: Array<{ component: string; error: string }>;\n warnings: Array<{ component: string; warning: string }>;\n}\n\n/**\n * Scan codebase and generate fragments.json directly from source\n */\nexport async function scan(options: ScanOptions = {}): Promise<ScanResult> {\n const startTime = Date.now();\n const errors: Array<{ component: string; error: string }> = [];\n const warnings: Array<{ component: string; warning: string }> = [];\n\n // Load config or use defaults\n let configDir: string;\n let outputFile: string;\n let componentPatterns: string[] | undefined;\n\n try {\n const loaded = await loadConfig(options.config);\n configDir = loaded.configDir;\n outputFile = options.output || loaded.config.outFile || \"fragments.json\";\n componentPatterns = options.componentPatterns || loaded.config.components;\n } catch {\n // No config file, use defaults\n configDir = process.cwd();\n outputFile = options.output || \"fragments.json\";\n componentPatterns = options.componentPatterns;\n }\n\n console.log(pc.cyan(`\\n${BRAND.name} Scan\\n`));\n console.log(pc.dim(\"Zero-config fragments.json generation from source code\\n\"));\n\n // Phase 1: Discover components\n console.log(pc.dim(\"Phase 1: Discovering components...\"));\n const components = await discoverAllComponents(configDir, {\n patterns: componentPatterns,\n exclude: [\"**/*.test.*\", \"**/*.spec.*\", \"**/__tests__/**\"],\n barrelFiles: options.barrelFiles,\n });\n\n if (components.length === 0) {\n console.log(pc.yellow(\"No components found. Check your patterns or config.\"));\n return {\n success: false,\n outputPath: resolve(configDir, outputFile),\n componentCount: 0,\n propsExtracted: 0,\n usagesFound: 0,\n relationsInferred: 0,\n storiesParsed: 0,\n errors: [{ component: \"*\", error: \"No components found\" }],\n warnings: [],\n };\n }\n\n console.log(pc.green(` Found ${components.length} components`));\n if (options.verbose) {\n for (const comp of components.slice(0, 10)) {\n console.log(pc.dim(` - ${comp.name}: ${comp.relativePath}`));\n }\n if (components.length > 10) {\n console.log(pc.dim(` ... and ${components.length - 10} more`));\n }\n }\n\n // Phase 2: Extract props from TypeScript\n console.log(pc.dim(\"\\nPhase 2: Extracting props from TypeScript...\"));\n const propsMap = new Map<string, ReturnType<typeof convertToFragmentProps>>();\n const propsResults = new Map<string, PropsExtractionResult>();\n let propsExtracted = 0;\n\n for (const comp of components) {\n try {\n const extraction = await extractPropsFromFile(comp.sourcePath, {\n propsTypeName: `${comp.name}Props`,\n });\n\n propsResults.set(comp.name, extraction);\n\n if (extraction.success && extraction.props.length > 0) {\n propsMap.set(comp.name, convertToFragmentProps(extraction.props));\n propsExtracted++;\n }\n } catch (e) {\n if (options.verbose) {\n warnings.push({\n component: comp.name,\n warning: `Props extraction failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n }\n }\n }\n\n console.log(pc.green(` Extracted props for ${propsExtracted} components`));\n\n // Phase 3: Scan for usage patterns\n let usageAnalysis: UsageAnalysis | undefined;\n let usagesFound = 0;\n let allRelations = new Map<string, ComponentRelation[]>();\n\n if (!options.skipUsage) {\n console.log(pc.dim(\"\\nPhase 3: Scanning for usage patterns...\"));\n const usageDir = options.usageDir || configDir;\n\n try {\n // Get component names for filtering\n const componentNames = components.map((c) => c.name);\n\n usageAnalysis = await scanCodebase({\n rootDir: usageDir,\n include: [\"**/*.tsx\", \"**/*.ts\", \"**/*.jsx\", \"**/*.js\"],\n exclude: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/*.stories.*\",\n \"**/*.test.*\",\n \"**/*.spec.*\",\n ],\n componentNames,\n useCache: true,\n });\n\n // Count total usages across all components\n usagesFound = Object.values(usageAnalysis.components).reduce(\n (sum, comp) => sum + comp.totalUsages,\n 0\n );\n\n // Infer relations\n allRelations = inferAllRelations(usageAnalysis);\n console.log(pc.green(` Found ${usagesFound} usages across ${usageAnalysis.totalFiles} files`));\n console.log(pc.green(` Inferred relations for ${allRelations.size} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Usage scanning failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n console.log(pc.yellow(` Usage scanning failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n console.log(pc.dim(\"\\nPhase 3: Skipping usage analysis\"));\n }\n\n // Phase 4: Parse Storybook stories\n const storiesMap = new Map<string, ParsedStoryFile>();\n let storiesParsed = 0;\n\n if (!options.skipStorybook) {\n console.log(pc.dim(\"\\nPhase 4: Parsing Storybook stories...\"));\n\n try {\n const allStories = await parseAllStories(configDir);\n\n for (const [name, stories] of Object.entries(allStories)) {\n if (stories && stories.stories.length > 0) {\n storiesMap.set(name, stories);\n storiesParsed++;\n }\n }\n\n console.log(pc.green(` Parsed stories for ${storiesParsed} components`));\n } catch (e) {\n warnings.push({\n component: \"*\",\n warning: `Storybook parsing failed: ${e instanceof Error ? e.message : String(e)}`,\n });\n console.log(pc.yellow(` Storybook parsing failed: ${e instanceof Error ? e.message : \"unknown error\"}`));\n }\n } else {\n console.log(pc.dim(\"\\nPhase 4: Skipping Storybook parsing\"));\n }\n\n // Phase 5: Generate fragments\n console.log(pc.dim(\"\\nPhase 5: Generating fragments...\"));\n const fragments: Record<string, CompiledFragment> = {};\n\n for (const comp of components) {\n try {\n const fragment = generateFragmentFromData(\n comp,\n configDir,\n propsMap.get(comp.name),\n usageAnalysis?.components[comp.name],\n allRelations.get(comp.name),\n storiesMap.get(comp.name)\n );\n\n fragments[comp.name] = fragment;\n } catch (e) {\n errors.push({\n component: comp.name,\n error: e instanceof Error ? e.message : String(e),\n });\n }\n }\n\n // Write output\n const outputPath = resolve(configDir, outputFile);\n await mkdir(dirname(outputPath), { recursive: true });\n\n const output: CompiledFragmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n fragments,\n };\n\n await writeFile(outputPath, JSON.stringify(output, null, 2));\n\n const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);\n\n // Summary\n console.log(pc.dim(\"\\n────────────────────────────────────────\"));\n console.log(pc.green(`\\n✓ Generated fragments.json in ${elapsed}s`));\n console.log(pc.dim(` Output: ${relative(process.cwd(), outputPath)}`));\n console.log(pc.dim(` Components: ${Object.keys(fragments).length}`));\n console.log(pc.dim(` Props extracted: ${propsExtracted}`));\n console.log(pc.dim(` Usages found: ${usagesFound}`));\n console.log(pc.dim(` Relations inferred: ${allRelations.size}`));\n console.log(pc.dim(` Stories parsed: ${storiesParsed}`));\n\n if (warnings.length > 0) {\n console.log(pc.yellow(`\\n ${warnings.length} warning(s)`));\n if (options.verbose) {\n for (const w of warnings) {\n console.log(pc.dim(` ${w.component}: ${w.warning}`));\n }\n }\n }\n\n if (errors.length > 0) {\n console.log(pc.red(`\\n ${errors.length} error(s)`));\n for (const e of errors) {\n console.log(pc.dim(` ${e.component}: ${e.error}`));\n }\n }\n\n console.log();\n\n return {\n success: errors.length === 0,\n outputPath,\n componentCount: Object.keys(fragments).length,\n propsExtracted,\n usagesFound,\n relationsInferred: allRelations.size,\n storiesParsed,\n errors,\n warnings,\n };\n}\n\n/**\n * Generate a CompiledFragment from extracted data\n */\nfunction generateFragmentFromData(\n comp: DiscoveredComponent,\n configDir: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n relations: ComponentRelation[] | undefined,\n storyFile: ParsedStoryFile | undefined\n): CompiledFragment {\n // Generate context for AI suggestions\n const context = generateComponentContext(\n comp.name,\n usageAnalysis,\n undefined, // No extracted docs yet\n storyFile,\n undefined, // No props extraction result (we have the converted props already)\n relations\n );\n\n // Generate enhancement suggestions from context\n const suggestions = generateEnhancementSuggestions(context);\n\n // Filter boilerplate from suggestions\n const when = filterBoilerplate(suggestions.suggestions.when);\n const whenNot = filterBoilerplate(suggestions.suggestions.whenNot);\n\n // Infer category from path\n const category = inferCategory(comp.relativePath);\n\n // Infer status from path\n const status = inferStatus(comp.relativePath);\n\n // Build variants from stories\n const variants: CompiledFragment[\"variants\"] = [];\n if (storyFile?.stories) {\n for (const story of storyFile.stories) {\n variants.push({\n name: story.name,\n description: story.description || `${story.displayName} variant`,\n code: story.code,\n });\n }\n }\n\n // Build relations\n const compiledRelations: CompiledFragment[\"relations\"] = [];\n if (relations && relations.length > 0) {\n for (const rel of relations.slice(0, 10)) {\n compiledRelations.push({\n component: rel.component,\n relationship: rel.relationship,\n note: `Appears together ${rel.frequency} times`,\n });\n }\n }\n\n // Generate description\n const description = generateDescription(comp.name, props, usageAnalysis);\n\n return {\n filePath: comp.relativePath,\n meta: {\n name: comp.name,\n description,\n category,\n status,\n },\n usage: {\n when: when.length > 0 ? when : [`Use ${comp.name} for its intended purpose`],\n whenNot: whenNot,\n },\n props: props || {},\n relations: compiledRelations.length > 0 ? compiledRelations : undefined,\n variants,\n _generated: {\n source: \"ai\",\n sourceFile: comp.relativePath,\n confidence: calculateConfidence(props, usageAnalysis, storyFile),\n timestamp: new Date().toISOString(),\n },\n };\n}\n\n/**\n * Infer category from file path\n */\nfunction inferCategory(relativePath: string): string {\n const parts = relativePath.toLowerCase().split(\"/\");\n\n // Common category patterns\n const categoryPatterns: Record<string, string[]> = {\n \"Actions\": [\"button\", \"action\", \"cta\"],\n \"Forms\": [\"form\", \"input\", \"select\", \"checkbox\", \"radio\", \"textarea\", \"field\"],\n \"Layout\": [\"layout\", \"container\", \"grid\", \"flex\", \"stack\", \"box\", \"divider\", \"spacer\"],\n \"Navigation\": [\"nav\", \"menu\", \"breadcrumb\", \"tab\", \"link\", \"pagination\"],\n \"Feedback\": [\"alert\", \"toast\", \"notification\", \"message\", \"badge\", \"indicator\", \"progress\", \"spinner\", \"loading\"],\n \"Data Display\": [\"table\", \"list\", \"card\", \"avatar\", \"stat\", \"timeline\", \"tree\"],\n \"Overlays\": [\"modal\", \"dialog\", \"drawer\", \"popover\", \"tooltip\", \"dropdown\"],\n \"Typography\": [\"text\", \"heading\", \"title\", \"label\", \"paragraph\"],\n \"Media\": [\"image\", \"video\", \"icon\", \"avatar\"],\n };\n\n for (const [category, patterns] of Object.entries(categoryPatterns)) {\n for (const pattern of patterns) {\n if (parts.some((part) => part.includes(pattern))) {\n return category;\n }\n }\n }\n\n // Check path structure for category\n const componentIdx = parts.findIndex((p) => p === \"components\");\n if (componentIdx !== -1 && parts.length > componentIdx + 1) {\n const categoryPart = parts[componentIdx + 1];\n return categoryPart.charAt(0).toUpperCase() + categoryPart.slice(1);\n }\n\n return \"Components\";\n}\n\n/**\n * Infer status from file path\n */\nfunction inferStatus(\n relativePath: string\n): \"stable\" | \"beta\" | \"experimental\" | \"deprecated\" {\n const lowerPath = relativePath.toLowerCase();\n\n if (lowerPath.includes(\"/experimental/\") || lowerPath.includes(\"/labs/\")) {\n return \"experimental\";\n }\n if (lowerPath.includes(\"/beta/\")) {\n return \"beta\";\n }\n if (lowerPath.includes(\"/deprecated/\") || lowerPath.includes(\"/legacy/\")) {\n return \"deprecated\";\n }\n\n return \"stable\";\n}\n\n/**\n * Generate component description\n */\nfunction generateDescription(\n name: string,\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined\n): string {\n // Convert name to readable form\n const words = name\n .replace(/([A-Z])/g, \" $1\")\n .trim()\n .toLowerCase();\n\n // Check props for hints\n const hasOnClick = props && (\"onClick\" in props || \"onPress\" in props);\n const hasValue = props && (\"value\" in props || \"defaultValue\" in props);\n const hasChildren = props && \"children\" in props;\n const hasHref = props && \"href\" in props;\n\n // Check usage contexts\n const topContext = usageAnalysis?.contexts[0]?.type;\n\n if (hasHref) {\n return `Navigational ${words} for linking to other pages or resources`;\n }\n\n if (hasOnClick && !hasValue) {\n return `Interactive ${words} for triggering actions`;\n }\n\n if (hasValue) {\n return `Form ${words} for user input`;\n }\n\n if (topContext && topContext !== \"unknown\") {\n return `${words.charAt(0).toUpperCase() + words.slice(1)} commonly used in ${topContext} contexts`;\n }\n\n if (hasChildren) {\n return `Container ${words} for composing UI`;\n }\n\n return `${words.charAt(0).toUpperCase() + words.slice(1)} component`;\n}\n\n/**\n * Calculate confidence score based on available data\n */\nfunction calculateConfidence(\n props: Record<string, PropDefinition> | undefined,\n usageAnalysis: UsageAnalysis[\"components\"][string] | undefined,\n storyFile: ParsedStoryFile | undefined\n): number {\n let confidence = 0;\n\n // Props give +30 confidence\n if (props && Object.keys(props).length > 0) {\n confidence += 30;\n }\n\n // Usage data gives up to +40 confidence\n if (usageAnalysis) {\n if (usageAnalysis.totalUsages > 10) confidence += 40;\n else if (usageAnalysis.totalUsages > 5) confidence += 30;\n else if (usageAnalysis.totalUsages > 0) confidence += 20;\n }\n\n // Stories give +30 confidence\n if (storyFile && storyFile.stories.length > 0) {\n confidence += 30;\n }\n\n return Math.min(confidence, 100);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createRequire as __banner_createRequire } from 'module'; const require = __banner_createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
BRAND,
|
|
4
|
-
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
fragmentsConfigSchema
|
|
5
|
+
} from "./chunk-GHYYFAQN.js";
|
|
6
6
|
|
|
7
7
|
// src/core/config.ts
|
|
8
8
|
import { existsSync } from "fs";
|
|
@@ -11,7 +11,7 @@ import { createJiti } from "jiti";
|
|
|
11
11
|
var DEFAULT_CONFIG = {
|
|
12
12
|
include: [
|
|
13
13
|
`src/**/*${BRAND.fileExtension}`,
|
|
14
|
-
// *.
|
|
14
|
+
// *.fragment.tsx files
|
|
15
15
|
"src/**/*.stories.tsx"
|
|
16
16
|
// Storybook stories (auto-converted)
|
|
17
17
|
],
|
|
@@ -47,7 +47,7 @@ async function loadConfig(configPath) {
|
|
|
47
47
|
interopDefault: true
|
|
48
48
|
});
|
|
49
49
|
const rawConfig = await jiti.import(resolvedPath);
|
|
50
|
-
const result =
|
|
50
|
+
const result = fragmentsConfigSchema.safeParse(rawConfig);
|
|
51
51
|
if (!result.success) {
|
|
52
52
|
const errors = result.error.errors.map((e) => ` - ${e.path.join(".")}: ${e.message}`).join("\n");
|
|
53
53
|
throw new Error(`Invalid config in ${resolvedPath}:
|
|
@@ -85,7 +85,7 @@ async function discoverBlockFiles(configDir, exclude) {
|
|
|
85
85
|
absolutePath: resolve2(configDir, relativePath)
|
|
86
86
|
}));
|
|
87
87
|
}
|
|
88
|
-
async function
|
|
88
|
+
async function discoverFragmentFiles(config, configDir) {
|
|
89
89
|
const files = await fg(config.include, {
|
|
90
90
|
cwd: configDir,
|
|
91
91
|
ignore: config.exclude ?? [],
|
|
@@ -104,7 +104,7 @@ async function discoverComponentFiles(config, configDir) {
|
|
|
104
104
|
cwd: configDir,
|
|
105
105
|
ignore: [
|
|
106
106
|
...config.exclude ?? [],
|
|
107
|
-
// Exclude
|
|
107
|
+
// Exclude fragment files themselves
|
|
108
108
|
...config.include,
|
|
109
109
|
// Exclude test files
|
|
110
110
|
"**/*.test.*",
|
|
@@ -1028,8 +1028,8 @@ import { unlink } from "fs/promises";
|
|
|
1028
1028
|
import { dirname as dirname4, basename as basename3, join as join2 } from "path";
|
|
1029
1029
|
import { pathToFileURL } from "url";
|
|
1030
1030
|
import { build } from "esbuild";
|
|
1031
|
-
var
|
|
1032
|
-
export function
|
|
1031
|
+
var DEFINE_FRAGMENT_SHIM = `
|
|
1032
|
+
export function defineFragment(def) {
|
|
1033
1033
|
return def;
|
|
1034
1034
|
}
|
|
1035
1035
|
export function defineFragment(def) {
|
|
@@ -1042,7 +1042,7 @@ export function defineRecipe(def) {
|
|
|
1042
1042
|
return def;
|
|
1043
1043
|
}
|
|
1044
1044
|
`;
|
|
1045
|
-
function
|
|
1045
|
+
function createFragmentsCoreShimPlugin() {
|
|
1046
1046
|
return {
|
|
1047
1047
|
name: BRAND.vitePluginNamespace,
|
|
1048
1048
|
setup(build2) {
|
|
@@ -1054,14 +1054,14 @@ function createSegmentsCoreShimPlugin() {
|
|
|
1054
1054
|
});
|
|
1055
1055
|
build2.onLoad({ filter: /.*/, namespace: BRAND.vitePluginNamespace }, () => {
|
|
1056
1056
|
return {
|
|
1057
|
-
contents:
|
|
1057
|
+
contents: DEFINE_FRAGMENT_SHIM,
|
|
1058
1058
|
loader: "js"
|
|
1059
1059
|
};
|
|
1060
1060
|
});
|
|
1061
1061
|
}
|
|
1062
1062
|
};
|
|
1063
1063
|
}
|
|
1064
|
-
async function
|
|
1064
|
+
async function loadFragmentFile(absolutePath) {
|
|
1065
1065
|
const ext = absolutePath.split(".").pop()?.toLowerCase();
|
|
1066
1066
|
const needsTransform = ext === "tsx" || ext === "ts" || ext === "jsx";
|
|
1067
1067
|
if (!needsTransform) {
|
|
@@ -1071,7 +1071,7 @@ async function loadSegmentFile(absolutePath) {
|
|
|
1071
1071
|
}
|
|
1072
1072
|
const sourceDir = dirname4(absolutePath);
|
|
1073
1073
|
const baseName = basename3(absolutePath, `.${ext}`);
|
|
1074
|
-
const tempFile = join2(sourceDir, `.${baseName}.
|
|
1074
|
+
const tempFile = join2(sourceDir, `.${baseName}.fragments-temp-${Date.now()}.cjs`);
|
|
1075
1075
|
try {
|
|
1076
1076
|
await build({
|
|
1077
1077
|
entryPoints: [absolutePath],
|
|
@@ -1082,8 +1082,8 @@ async function loadSegmentFile(absolutePath) {
|
|
|
1082
1082
|
target: "es2022",
|
|
1083
1083
|
jsx: "automatic",
|
|
1084
1084
|
platform: "node",
|
|
1085
|
-
plugins: [
|
|
1086
|
-
// Externalize all node_modules - we only need
|
|
1085
|
+
plugins: [createFragmentsCoreShimPlugin()],
|
|
1086
|
+
// Externalize all node_modules - we only need fragment metadata, not component code
|
|
1087
1087
|
packages: "external",
|
|
1088
1088
|
// Also explicitly list patterns for nested imports
|
|
1089
1089
|
external: [
|
|
@@ -1125,19 +1125,19 @@ async function loadSegmentFile(absolutePath) {
|
|
|
1125
1125
|
|
|
1126
1126
|
// src/core/parser.ts
|
|
1127
1127
|
import ts2 from "typescript";
|
|
1128
|
-
function
|
|
1128
|
+
function parseFragmentFile(fileContent, filePath) {
|
|
1129
1129
|
const warnings = [];
|
|
1130
1130
|
const sourceFile = ts2.createSourceFile(
|
|
1131
|
-
filePath ?? "
|
|
1131
|
+
filePath ?? "fragment.tsx",
|
|
1132
1132
|
fileContent,
|
|
1133
1133
|
ts2.ScriptTarget.Latest,
|
|
1134
1134
|
true,
|
|
1135
1135
|
ts2.ScriptKind.TSX
|
|
1136
1136
|
);
|
|
1137
1137
|
const imports = extractImports(sourceFile);
|
|
1138
|
-
const
|
|
1139
|
-
if (!
|
|
1140
|
-
warnings.push("No
|
|
1138
|
+
const defineFragmentCall = findDefineFragmentCall(sourceFile);
|
|
1139
|
+
if (!defineFragmentCall) {
|
|
1140
|
+
warnings.push("No defineFragment() call found");
|
|
1141
1141
|
return {
|
|
1142
1142
|
componentImport: null,
|
|
1143
1143
|
componentName: null,
|
|
@@ -1149,9 +1149,9 @@ function parseSegmentFile(fileContent, filePath) {
|
|
|
1149
1149
|
warnings
|
|
1150
1150
|
};
|
|
1151
1151
|
}
|
|
1152
|
-
const arg =
|
|
1152
|
+
const arg = defineFragmentCall.arguments[0];
|
|
1153
1153
|
if (!arg || !ts2.isObjectLiteralExpression(arg)) {
|
|
1154
|
-
warnings.push("
|
|
1154
|
+
warnings.push("defineFragment() argument is not an object literal");
|
|
1155
1155
|
return {
|
|
1156
1156
|
componentImport: null,
|
|
1157
1157
|
componentName: null,
|
|
@@ -1212,12 +1212,12 @@ function extractImports(sourceFile) {
|
|
|
1212
1212
|
});
|
|
1213
1213
|
return imports;
|
|
1214
1214
|
}
|
|
1215
|
-
function
|
|
1215
|
+
function findDefineFragmentCall(sourceFile) {
|
|
1216
1216
|
let result = null;
|
|
1217
1217
|
function visit(node) {
|
|
1218
1218
|
if (ts2.isCallExpression(node)) {
|
|
1219
1219
|
const expression = node.expression;
|
|
1220
|
-
if (ts2.isIdentifier(expression) && expression.text === "
|
|
1220
|
+
if (ts2.isIdentifier(expression) && expression.text === "defineFragment") {
|
|
1221
1221
|
result = node;
|
|
1222
1222
|
return;
|
|
1223
1223
|
}
|
|
@@ -1581,14 +1581,14 @@ export {
|
|
|
1581
1581
|
findConfigFile,
|
|
1582
1582
|
loadConfig,
|
|
1583
1583
|
discoverBlockFiles,
|
|
1584
|
-
|
|
1584
|
+
discoverFragmentFiles,
|
|
1585
1585
|
discoverComponentFiles,
|
|
1586
1586
|
extractComponentName,
|
|
1587
1587
|
discoverTokenFiles,
|
|
1588
1588
|
discoverInstalledFragments,
|
|
1589
1589
|
discoverAllComponents,
|
|
1590
|
-
|
|
1591
|
-
|
|
1590
|
+
loadFragmentFile,
|
|
1591
|
+
parseFragmentFile,
|
|
1592
1592
|
findPreviewConfigPath,
|
|
1593
1593
|
findStorybookDir,
|
|
1594
1594
|
generatePreviewModule,
|
|
@@ -1596,4 +1596,4 @@ export {
|
|
|
1596
1596
|
generateRegistry,
|
|
1597
1597
|
generateContextMd
|
|
1598
1598
|
};
|
|
1599
|
-
//# sourceMappingURL=chunk-
|
|
1599
|
+
//# sourceMappingURL=chunk-5ITIP3ES.js.map
|