@fragments-sdk/cli 0.3.3 → 0.4.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 +18 -13
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-PMGI7ATF.js → chunk-5CKYLCJH.js} +58 -2
- package/dist/chunk-5CKYLCJH.js.map +1 -0
- package/dist/{chunk-MUZ6CM66.js → chunk-5ZYEOHYK.js} +13 -11
- package/dist/chunk-5ZYEOHYK.js.map +1 -0
- package/dist/{chunk-XHNKNI6J.js → chunk-AW7MWOUH.js} +9 -1
- package/dist/chunk-AW7MWOUH.js.map +1 -0
- package/dist/{chunk-LY2CFFPY.js → chunk-G3M3MPQ6.js} +14 -3
- package/dist/chunk-G3M3MPQ6.js.map +1 -0
- package/dist/{chunk-3OTEW66K.js → chunk-J4SI5RIH.js} +4 -4
- package/dist/{chunk-BSCG3IP7.js → chunk-NOTYONHY.js} +2 -2
- package/dist/{chunk-D6VXWI45.js → chunk-ZFKGX3QK.js} +8 -6
- package/dist/chunk-ZFKGX3QK.js.map +1 -0
- package/dist/{core-DWKLGY4N.js → core-LNXDLXDP.js} +5 -3
- package/dist/{generate-3LBZANQ3.js → generate-OIXXHOWR.js} +4 -4
- package/dist/index.d.ts +16 -0
- package/dist/index.js +6 -6
- package/dist/{init-NKIUCYTG.js → init-EVPXIDW4.js} +4 -4
- package/dist/mcp-bin.js +3 -3
- package/dist/mcp-bin.js.map +1 -1
- package/dist/scan-YVYD64GD.js +12 -0
- package/dist/{service-QSZMZJBJ.js → service-K52ORLCJ.js} +4 -4
- package/dist/{static-viewer-MIPGZ4Z7.js → static-viewer-JNQIHA4B.js} +4 -4
- package/dist/{test-ZCTR4LBB.js → test-USARUEFW.js} +9 -5
- package/dist/test-USARUEFW.js.map +1 -0
- package/dist/{tokens-5JQ5IOR2.js → tokens-C6YHBOQE.js} +5 -5
- package/dist/{viewer-D7QC4GM2.js → viewer-H7TVFT4E.js} +15 -15
- package/dist/{viewer-D7QC4GM2.js.map → viewer-H7TVFT4E.js.map} +1 -1
- package/package.json +2 -1
- package/src/bin.ts +7 -1
- package/src/build.ts +2 -0
- package/src/core/index.ts +4 -0
- package/src/core/parser.ts +102 -1
- package/src/core/schema.ts +11 -0
- package/src/core/storyAdapter.ts +1 -1
- package/src/core/storybook-csf.ts +11 -0
- package/src/core/types.ts +25 -1
- package/src/mcp/server.ts +1 -1
- package/src/migrate/bin.ts +7 -1
- package/src/migrate/report.ts +1 -1
- package/src/service/enhance/doc-extractor.ts +2 -2
- package/src/service/enhance/props-extractor.ts +1 -1
- package/src/service/enhance/storybook-parser.ts +1 -1
- package/src/service/figma.ts +2 -2
- package/src/service/metrics-store.ts +2 -1
- package/src/service/patch-generator.ts +2 -1
- package/src/service/report.ts +1 -1
- package/src/test/reporters/junit.ts +7 -3
- package/src/test/runner.ts +4 -4
- package/src/test/watch.ts +2 -2
- package/src/theme/__tests__/generator.test.ts +412 -0
- package/src/theme/__tests__/presets.test.ts +169 -0
- package/src/theme/__tests__/schema.test.ts +463 -0
- package/src/theme/__tests__/serializer.test.ts +326 -0
- package/src/theme/generator.ts +355 -0
- package/src/theme/index.ts +61 -0
- package/src/theme/presets.ts +189 -0
- package/src/theme/schema.ts +193 -0
- package/src/theme/serializer.ts +123 -0
- package/src/theme/types.ts +210 -0
- package/src/viewer/components/CodePanel.tsx +1 -1
- package/src/viewer/components/FigmaEmbed.tsx +1 -1
- package/src/viewer/jsx-parser.ts +2 -1
- package/src/viewer/styles/globals.css +1 -1
- package/src/viewer/utils/colorSchemes.ts +3 -3
- package/dist/chunk-D6VXWI45.js.map +0 -1
- package/dist/chunk-LY2CFFPY.js.map +0 -1
- package/dist/chunk-MUZ6CM66.js.map +0 -1
- package/dist/chunk-PMGI7ATF.js.map +0 -1
- package/dist/chunk-XHNKNI6J.js.map +0 -1
- package/dist/scan-3ZAOVO4U.js +0 -12
- package/dist/test-ZCTR4LBB.js.map +0 -1
- /package/dist/{chunk-3OTEW66K.js.map → chunk-J4SI5RIH.js.map} +0 -0
- /package/dist/{chunk-BSCG3IP7.js.map → chunk-NOTYONHY.js.map} +0 -0
- /package/dist/{core-DWKLGY4N.js.map → core-LNXDLXDP.js.map} +0 -0
- /package/dist/{generate-3LBZANQ3.js.map → generate-OIXXHOWR.js.map} +0 -0
- /package/dist/{init-NKIUCYTG.js.map → init-EVPXIDW4.js.map} +0 -0
- /package/dist/{scan-3ZAOVO4U.js.map → scan-YVYD64GD.js.map} +0 -0
- /package/dist/{service-QSZMZJBJ.js.map → service-K52ORLCJ.js.map} +0 -0
- /package/dist/{static-viewer-MIPGZ4Z7.js.map → static-viewer-JNQIHA4B.js.map} +0 -0
- /package/dist/{tokens-5JQ5IOR2.js.map → tokens-C6YHBOQE.js.map} +0 -0
|
@@ -180,6 +180,12 @@ var segmentGeneratedSchema = z.object({
|
|
|
180
180
|
confidence: z.number().min(0).max(1).optional(),
|
|
181
181
|
timestamp: z.string().datetime().optional()
|
|
182
182
|
});
|
|
183
|
+
var aiMetadataSchema = z.object({
|
|
184
|
+
compositionPattern: z.enum(["compound", "simple", "controlled"]).optional(),
|
|
185
|
+
subComponents: z.array(z.string()).optional(),
|
|
186
|
+
requiredChildren: z.array(z.string()).optional(),
|
|
187
|
+
commonPatterns: z.array(z.string()).optional()
|
|
188
|
+
});
|
|
183
189
|
var recipeDefinitionSchema = z.object({
|
|
184
190
|
name: z.string().min(1),
|
|
185
191
|
description: z.string().min(1),
|
|
@@ -198,6 +204,7 @@ var segmentDefinitionSchema = z.object({
|
|
|
198
204
|
variants: z.array(segmentVariantSchema),
|
|
199
205
|
// Allow empty variants array
|
|
200
206
|
contract: segmentContractSchema.optional(),
|
|
207
|
+
ai: aiMetadataSchema.optional(),
|
|
201
208
|
_generated: segmentGeneratedSchema.optional()
|
|
202
209
|
});
|
|
203
210
|
var segmentsConfigSchema = z.object({
|
|
@@ -228,8 +235,9 @@ export {
|
|
|
228
235
|
segmentBanSchema,
|
|
229
236
|
segmentContractSchema,
|
|
230
237
|
segmentGeneratedSchema,
|
|
238
|
+
aiMetadataSchema,
|
|
231
239
|
recipeDefinitionSchema,
|
|
232
240
|
segmentDefinitionSchema,
|
|
233
241
|
segmentsConfigSchema
|
|
234
242
|
};
|
|
235
|
-
//# sourceMappingURL=chunk-
|
|
243
|
+
//# sourceMappingURL=chunk-AW7MWOUH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/constants.ts","../src/core/schema.ts"],"sourcesContent":["/**\n * Brand constants for easy rebranding if domain availability requires it.\n * All naming throughout the codebase should reference these constants.\n */\nexport const BRAND = {\n /** Display name (e.g., \"Fragments\") */\n name: \"Fragments\",\n\n /** Lowercase name for file paths and CLI (e.g., \"fragments\") */\n nameLower: \"fragments\",\n\n /** File extension for fragment definition files (e.g., \".fragment.tsx\") */\n fileExtension: \".fragment.tsx\",\n\n /** Legacy file extension for segments (still supported for migration) */\n legacyFileExtension: \".segment.tsx\",\n\n /** JSON file extension for compiled output */\n jsonExtension: \".fragment.json\",\n\n /** Default output file name (e.g., \"fragments.json\") */\n outFile: \"fragments.json\",\n\n /** Config file name (e.g., \"fragments.config.ts\") */\n configFile: \"fragments.config.ts\",\n\n /** Legacy config file name (still supported for migration) */\n legacyConfigFile: \"segments.config.ts\",\n\n /** CLI command name (e.g., \"fragments\") */\n cliCommand: \"fragments\",\n\n /** Package scope (e.g., \"@fragments\") */\n packageScope: \"@fragments\",\n\n /** Directory for storing fragments, registry, and cache */\n dataDir: \".fragments\",\n\n /** Components subdirectory within .fragments/ */\n componentsDir: \"components\",\n\n /** Registry file name */\n registryFile: \"registry.json\",\n\n /** Context file name (AI-ready markdown) */\n contextFile: \"context.md\",\n\n /** Screenshots subdirectory */\n screenshotsDir: \"screenshots\",\n\n /** Cache subdirectory (gitignored) */\n cacheDir: \"cache\",\n\n /** Diff output subdirectory (gitignored) */\n diffDir: \"diff\",\n\n /** Manifest filename */\n manifestFile: \"manifest.json\",\n\n /** Prefix for localStorage keys (e.g., \"fragments-\") */\n storagePrefix: \"fragments-\",\n\n /** Static viewer HTML file name */\n viewerHtmlFile: \"fragments-viewer.html\",\n\n /** MCP tool name prefix (e.g., \"fragments_\") */\n mcpToolPrefix: \"fragments_\",\n\n /** File extension for recipe definition files */\n recipeFileExtension: \".recipe.ts\",\n\n /** Vite plugin namespace */\n vitePluginNamespace: \"fragments-core-shim\",\n} as const;\n\nexport type Brand = typeof BRAND;\n\n/**\n * Default configuration values for the service.\n * These can be overridden in fragments.config.ts\n */\nexport const DEFAULTS = {\n /** Default viewport dimensions */\n viewport: {\n width: 1280,\n height: 800,\n },\n\n /** Default diff threshold (percentage) */\n diffThreshold: 5,\n\n /** Browser pool size */\n poolSize: 3,\n\n /** Idle timeout before browser shutdown (ms) - 5 minutes */\n idleTimeoutMs: 5 * 60 * 1000,\n\n /** Delay after render before capture (ms) */\n captureDelayMs: 100,\n\n /** Font loading timeout (ms) */\n fontTimeoutMs: 3000,\n\n /** Default theme */\n theme: \"light\" as const,\n\n /** Dev server port */\n port: 6006,\n} as const;\n\nexport type Defaults = typeof DEFAULTS;\n","import { z } from 'zod';\n\n/**\n * Zod schemas for runtime validation of segment definitions\n */\n\n// Figma property mapping schemas\nconst figmaStringMappingSchema = z.object({\n __type: z.literal('figma-string'),\n figmaProperty: z.string().min(1),\n});\n\nconst figmaBooleanMappingSchema = z.object({\n __type: z.literal('figma-boolean'),\n figmaProperty: z.string().min(1),\n valueMapping: z.object({ true: z.unknown(), false: z.unknown() }).optional(),\n});\n\nconst figmaEnumMappingSchema = z.object({\n __type: z.literal('figma-enum'),\n figmaProperty: z.string().min(1),\n valueMapping: z.record(z.unknown()),\n});\n\nconst figmaInstanceMappingSchema = z.object({\n __type: z.literal('figma-instance'),\n figmaProperty: z.string().min(1),\n});\n\nconst figmaChildrenMappingSchema = z.object({\n __type: z.literal('figma-children'),\n layers: z.array(z.string().min(1)),\n});\n\nconst figmaTextContentMappingSchema = z.object({\n __type: z.literal('figma-text-content'),\n layer: z.string().min(1),\n});\n\nexport const figmaPropMappingSchema = z.discriminatedUnion('__type', [\n figmaStringMappingSchema,\n figmaBooleanMappingSchema,\n figmaEnumMappingSchema,\n figmaInstanceMappingSchema,\n figmaChildrenMappingSchema,\n figmaTextContentMappingSchema,\n]);\n\nexport const segmentMetaSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n category: z.string().min(1),\n tags: z.array(z.string()).optional(),\n status: z.enum(['stable', 'beta', 'deprecated', 'experimental']).optional(),\n since: z.string().optional(),\n figma: z.string().url().optional(),\n figmaProps: z.record(figmaPropMappingSchema).optional(),\n});\n\nexport const segmentUsageSchema = z.object({\n when: z.array(z.string()).min(1),\n whenNot: z.array(z.string()).min(1),\n guidelines: z.array(z.string()).optional(),\n accessibility: z.array(z.string()).optional(),\n});\n\nexport const propTypeSchema: z.ZodType<string> = z.enum([\n 'string',\n 'number',\n 'boolean',\n 'enum',\n 'function',\n 'node',\n 'element',\n 'object',\n 'array',\n 'union',\n 'custom',\n]);\n\nexport const propDefinitionSchema = z.object({\n type: propTypeSchema,\n values: z.array(z.string()).readonly().optional(),\n default: z.unknown().optional(),\n description: z.string().optional(),\n required: z.boolean().optional(),\n constraints: z.array(z.string()).optional(),\n typeDetails: z.record(z.unknown()).optional(),\n});\n\nexport const relationshipTypeSchema = z.enum([\n 'alternative',\n 'sibling',\n 'parent',\n 'child',\n 'composition',\n]);\n\nexport const componentRelationSchema = z.object({\n component: z.string().min(1),\n relationship: relationshipTypeSchema,\n note: z.string().min(1),\n});\n\nexport const segmentVariantSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n render: z.function().returns(z.unknown()),\n code: z.string().optional(),\n figma: z.string().url().optional(),\n});\n\n/**\n * Schema for banned patterns in codebase\n */\nexport const segmentBanSchema = z.object({\n pattern: z.string().min(1),\n message: z.string().min(1),\n});\n\n/**\n * Schema for agent-optimized contract metadata\n */\nexport const segmentContractSchema = z.object({\n propsSummary: z.array(z.string()).optional(),\n a11yRules: z.array(z.string()).optional(),\n bans: z.array(segmentBanSchema).optional(),\n scenarioTags: z.array(z.string()).optional(),\n});\n\n/**\n * Schema for provenance tracking of generated segments\n */\nexport const segmentGeneratedSchema = z.object({\n source: z.enum(['storybook', 'manual', 'ai']),\n sourceFile: z.string().optional(),\n confidence: z.number().min(0).max(1).optional(),\n timestamp: z.string().datetime().optional(),\n});\n\n/**\n * Schema for AI-specific metadata for playground context generation\n */\nexport const aiMetadataSchema = z.object({\n compositionPattern: z.enum(['compound', 'simple', 'controlled']).optional(),\n subComponents: z.array(z.string()).optional(),\n requiredChildren: z.array(z.string()).optional(),\n commonPatterns: z.array(z.string()).optional(),\n});\n\n/**\n * Schema for recipe definitions\n */\nexport const recipeDefinitionSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n category: z.string().min(1),\n components: z.array(z.string().min(1)).min(1),\n code: z.string().min(1),\n tags: z.array(z.string()).optional(),\n});\n\nexport const segmentDefinitionSchema = z.object({\n component: z.any(), // Allow any component type (function, class, forwardRef, etc.)\n meta: segmentMetaSchema,\n usage: segmentUsageSchema,\n props: z.record(propDefinitionSchema),\n relations: z.array(componentRelationSchema).optional(),\n variants: z.array(segmentVariantSchema), // Allow empty variants array\n contract: segmentContractSchema.optional(),\n ai: aiMetadataSchema.optional(),\n _generated: segmentGeneratedSchema.optional(),\n});\n\n/**\n * Config schema - validates required fields, passes through optional config objects.\n * Type definitions are in types.ts - schema just ensures basic structure.\n */\nexport const segmentsConfigSchema = z.object({\n include: z.array(z.string()).min(1),\n exclude: z.array(z.string()).optional(),\n components: z.array(z.string()).optional(),\n outFile: z.string().optional(),\n framework: z.enum(['react', 'vue', 'svelte']).optional(),\n figmaFile: z.string().url().optional(),\n figmaToken: z.string().optional(),\n screenshots: z.object({}).passthrough().optional(),\n service: z.object({}).passthrough().optional(),\n registry: z.object({}).passthrough().optional(),\n tokens: z.object({\n include: z.array(z.string()).min(1),\n }).passthrough().optional(),\n});\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@ import { createRequire } from 'module'; const require = createRequire(import.met
|
|
|
2
2
|
import {
|
|
3
3
|
recipeDefinitionSchema,
|
|
4
4
|
segmentDefinitionSchema
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-AW7MWOUH.js";
|
|
6
6
|
|
|
7
7
|
// src/core/defineSegment.ts
|
|
8
8
|
function defineSegment(definition) {
|
|
@@ -63,7 +63,18 @@ function compileRecipe(definition, filePath) {
|
|
|
63
63
|
|
|
64
64
|
// src/core/storyAdapter.ts
|
|
65
65
|
import { createElement } from "react";
|
|
66
|
-
|
|
66
|
+
|
|
67
|
+
// src/core/storybook-csf.ts
|
|
68
|
+
import {
|
|
69
|
+
toId as storybookToId,
|
|
70
|
+
storyNameFromExport as storybookStoryNameFromExport,
|
|
71
|
+
isExportStory as storybookIsExportStory
|
|
72
|
+
} from "@storybook/csf";
|
|
73
|
+
var toId = (...args) => storybookToId(...args);
|
|
74
|
+
var storyNameFromExport = (...args) => storybookStoryNameFromExport(...args);
|
|
75
|
+
var isExportStory = (...args) => storybookIsExportStory(...args);
|
|
76
|
+
|
|
77
|
+
// src/core/storyAdapter.ts
|
|
67
78
|
var globalPreviewConfig = {};
|
|
68
79
|
function setPreviewConfig(config) {
|
|
69
80
|
globalPreviewConfig = config;
|
|
@@ -895,4 +906,4 @@ export {
|
|
|
895
906
|
resolveFigmaMapping,
|
|
896
907
|
analyzeComposition
|
|
897
908
|
};
|
|
898
|
-
//# sourceMappingURL=chunk-
|
|
909
|
+
//# sourceMappingURL=chunk-G3M3MPQ6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/defineSegment.ts","../src/core/storyAdapter.ts","../src/core/storybook-csf.ts","../src/core/context.ts","../src/core/figma.ts","../src/core/composition.ts"],"sourcesContent":["import type { SegmentDefinition, CompiledSegment, SegmentComponent, RecipeDefinition, CompiledRecipe } from './types.js';\nimport { segmentDefinitionSchema, recipeDefinitionSchema } from './schema.js';\n\n/**\n * Define a segment for a component.\n *\n * This is the main API for creating segment documentation.\n * It provides runtime validation and type safety.\n *\n * @example\n * ```tsx\n * import { defineSegment } from '@fragments/core';\n * import { Button } from './Button';\n *\n * export default defineSegment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * },\n * usage: {\n * when: ['User needs to trigger an action'],\n * whenNot: ['Navigation without side effects'],\n * },\n * props: {\n * variant: {\n * type: 'enum',\n * values: ['primary', 'secondary'],\n * default: 'primary',\n * description: 'Visual style',\n * },\n * },\n * variants: [\n * {\n * name: 'Default',\n * description: 'Default button',\n * render: () => <Button>Click me</Button>,\n * },\n * ],\n * });\n * ```\n */\nexport function defineSegment<TProps>(\n definition: SegmentDefinition<TProps>\n): SegmentDefinition<TProps> {\n // Validate at runtime in development\n if (process.env.NODE_ENV !== 'production') {\n const result = segmentDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid segment definition for \"${definition.meta?.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * Alias for defineSegment - use this for new projects.\n * @see defineSegment\n */\nexport const defineFragment = defineSegment;\n\n/**\n * Compile a segment definition to JSON-serializable format.\n * Used for generating fragments.json for AI consumption.\n */\nexport function compileSegment(\n definition: SegmentDefinition,\n filePath: string\n): CompiledSegment {\n return {\n filePath,\n meta: definition.meta,\n usage: definition.usage,\n props: definition.props,\n relations: definition.relations,\n variants: definition.variants.map((v) => ({\n name: v.name,\n description: v.description,\n code: v.code,\n figma: v.figma,\n })),\n contract: definition.contract,\n _generated: definition._generated,\n };\n}\n\n/**\n * Define a composition recipe.\n *\n * Recipes are pure data describing how design system components\n * wire together for common use cases.\n */\nexport function defineRecipe(definition: RecipeDefinition): RecipeDefinition {\n if (process.env.NODE_ENV !== 'production') {\n const result = recipeDefinitionSchema.safeParse(definition);\n if (!result.success) {\n const errors = result.error.errors\n .map((e) => ` - ${e.path.join('.')}: ${e.message}`)\n .join('\\n');\n throw new Error(\n `Invalid recipe definition for \"${definition.name || 'unknown'}\":\\n${errors}`\n );\n }\n }\n\n return definition;\n}\n\n/**\n * Compile a recipe definition to JSON-serializable format.\n */\nexport function compileRecipe(\n definition: RecipeDefinition,\n filePath: string\n): CompiledRecipe {\n return {\n filePath,\n name: definition.name,\n description: definition.description,\n category: definition.category,\n components: definition.components,\n code: definition.code,\n tags: definition.tags,\n };\n}\n\n/**\n * Type helper for extracting props type from a component\n */\nexport type InferProps<T> = T extends SegmentComponent<infer P> ? P : never;\n","/**\n * Runtime adapter for converting Storybook CSF modules to Segment definitions.\n *\n * This operates on IMPORTED modules at runtime, not source code parsing.\n * By leveraging Vite's module system, we get 100% accurate render functions\n * without any regex or AST parsing complexity.\n *\n * Supports Storybook 8.x with both CSF2 (Template.bind) and CSF3 (object stories).\n */\n\nimport { createElement, type ComponentType, type ReactNode } from \"react\";\nimport { toId, storyNameFromExport, isExportStory } from \"./storybook-csf.js\";\nimport type {\n SegmentDefinition,\n SegmentMeta,\n SegmentUsage,\n PropDefinition,\n SegmentVariant,\n ControlType,\n VariantLoader,\n PlayFunction,\n PlayFunctionContext,\n VariantRenderOptions,\n} from \"./types.js\";\n\n// Re-export @storybook/csf utilities for use in other modules\nexport { toId, storyNameFromExport, isExportStory };\n\n/**\n * Storybook decorator function signature\n */\nexport type Decorator = (\n Story: () => ReactNode,\n context: StoryContext\n) => ReactNode;\n\n/**\n * Storybook loader function signature\n */\nexport type Loader = (context: StoryContext) => Promise<Record<string, unknown>>;\n\n/**\n * Storybook play function signature (internal, extends StoryContext)\n */\ntype StorybookPlayFunction = (context: StorybookPlayFunctionContext) => Promise<void>;\n\n/**\n * Context passed to Storybook play functions (extends StoryContext for compatibility)\n */\ninterface StorybookPlayFunctionContext extends StoryContext {\n canvasElement: HTMLElement;\n step: (name: string, fn: () => Promise<void>) => Promise<void>;\n}\n\n/**\n * Context passed to decorators and render functions\n */\nexport interface StoryContext {\n args: Record<string, unknown>;\n argTypes: Record<string, StoryArgType>;\n globals: Record<string, unknown>;\n parameters: Record<string, unknown>;\n id: string;\n kind: string;\n name: string;\n story: string;\n viewMode: \"story\" | \"docs\";\n loaded: Record<string, unknown>;\n abortSignal: AbortSignal;\n componentId: string;\n title: string;\n}\n\n/**\n * Storybook Meta (default export)\n */\nexport interface StoryMeta {\n title?: string;\n component?: ComponentType<unknown>;\n subcomponents?: Record<string, ComponentType<unknown>>;\n tags?: string[];\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n component?: string;\n };\n };\n };\n argTypes?: Record<string, StoryArgType>;\n args?: Record<string, unknown>;\n decorators?: Decorator[];\n loaders?: Loader[];\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n // Story filtering\n includeStories?: string[] | RegExp;\n excludeStories?: string[] | RegExp;\n}\n\n/**\n * Storybook argType definition\n */\nexport interface StoryArgType {\n control?:\n | string\n | false\n | { type: string; min?: number; max?: number; step?: number; presetColors?: string[] };\n options?: string[];\n description?: string;\n table?: {\n defaultValue?: { summary: string };\n type?: { summary: string };\n category?: string;\n subcategory?: string;\n disable?: boolean;\n };\n type?: { name: string; required?: boolean };\n name?: string;\n defaultValue?: unknown;\n if?: { arg?: string; exists?: boolean };\n mapping?: Record<string, unknown>;\n action?: string;\n}\n\n/**\n * Storybook Story export (CSF3)\n */\nexport interface Story {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n render?: (args: Record<string, unknown>, context?: StoryContext) => ReactNode;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown> & {\n docs?: {\n description?: {\n story?: string;\n };\n };\n };\n name?: string;\n storyName?: string; // Legacy CSF2\n tags?: string[];\n}\n\n/**\n * CSF2 story function (from Template.bind({})) with args attached\n */\nexport type CSF2Story = ((args: Record<string, unknown>) => ReactNode) & {\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n decorators?: Decorator[];\n loaders?: Loader[];\n play?: StorybookPlayFunction;\n parameters?: Record<string, unknown>;\n storyName?: string;\n};\n\n/**\n * A complete Storybook module with default meta and named story exports\n */\nexport interface StoryModule {\n default: StoryMeta;\n [exportName: string]: Story | CSF2Story | StoryMeta | unknown;\n}\n\n/**\n * Global configuration from preview.tsx\n */\nexport interface PreviewConfig {\n decorators?: Decorator[];\n parameters?: Record<string, unknown>;\n globalTypes?: Record<string, unknown>;\n args?: Record<string, unknown>;\n argTypes?: Record<string, StoryArgType>;\n loaders?: Loader[];\n}\n\n// Store for global preview config (set by previewLoader)\nlet globalPreviewConfig: PreviewConfig = {};\n\n/**\n * Set the global preview configuration loaded from .storybook/preview.tsx\n */\nexport function setPreviewConfig(config: PreviewConfig): void {\n globalPreviewConfig = config;\n}\n\n/**\n * Get the current global preview configuration\n */\nexport function getPreviewConfig(): PreviewConfig {\n return globalPreviewConfig;\n}\n\n/**\n * Convert a Storybook module to a Segment definition at runtime.\n *\n * @param storyModule - The imported Storybook module\n * @param filePath - File path for metadata extraction\n * @returns A complete SegmentDefinition ready for the viewer\n */\nexport function storyModuleToSegment(\n storyModule: StoryModule,\n filePath: string\n): SegmentDefinition | null {\n const meta = storyModule.default;\n const component = meta.component;\n\n // Stories without a component (e.g., documentation pages, icon galleries) are skipped\n if (!component) {\n return null;\n }\n\n const componentName = extractComponentName(meta, filePath);\n const category = extractCategory(meta.title);\n const props = convertArgTypes(meta.argTypes ?? {}, globalPreviewConfig.argTypes);\n const variants = extractVariants(storyModule, component, meta);\n\n // Extract Figma URL from parameters.design.url (storybook-addon-designs) or parameters.figma\n const figmaUrl = extractFigmaUrl(meta.parameters);\n\n const segmentMeta: SegmentMeta = {\n name: componentName,\n description:\n meta.parameters?.docs?.description?.component ??\n `${componentName} component`,\n category,\n tags: meta.tags?.filter((t) => t !== \"autodocs\"),\n status: \"stable\",\n figma: figmaUrl,\n };\n\n const usage: SegmentUsage = {\n when: [`Use ${componentName} for its intended purpose`],\n whenNot: [\"When a more specific component is available\"],\n };\n\n return {\n component,\n meta: segmentMeta,\n usage,\n props,\n variants,\n };\n}\n\n/**\n * Extract component name from meta or file path\n */\nfunction extractComponentName(meta: StoryMeta, filePath: string): string {\n // Try title (last segment of path like \"Components/Forms/Button\" -> \"Button\")\n if (meta.title) {\n const parts = meta.title.split(\"/\");\n return parts[parts.length - 1];\n }\n\n // Try component displayName\n if (meta.component?.displayName) {\n return meta.component.displayName;\n }\n\n // Try component name\n if (meta.component?.name && meta.component.name !== \"Component\") {\n return meta.component.name;\n }\n\n // Fallback: extract from file path\n const match = filePath.match(/([^/\\\\]+)\\.stories\\.(tsx?|jsx?)$/);\n return match?.[1] ?? \"Unknown\";\n}\n\n/**\n * Extract category from Storybook title path\n */\nfunction extractCategory(title?: string): string {\n if (!title) return \"general\";\n\n const parts = title.split(\"/\");\n // \"Components/Forms/Button\" -> \"forms\" (need at least 3 parts for a subcategory)\n if (parts.length >= 3) {\n return parts[parts.length - 2].toLowerCase();\n }\n // \"Components/Button\" -> \"general\" (no subcategory specified)\n return \"general\";\n}\n\n/**\n * Extract Figma URL from Storybook parameters\n * Supports storybook-addon-designs format and custom figma parameter\n */\nfunction extractFigmaUrl(parameters?: Record<string, unknown>): string | undefined {\n if (!parameters) return undefined;\n\n // Try storybook-addon-designs format: parameters.design.url\n const design = parameters.design as { url?: string; type?: string } | undefined;\n if (design?.url && typeof design.url === \"string\") {\n return design.url;\n }\n\n // Try custom figma parameter: parameters.figma\n if (typeof parameters.figma === \"string\") {\n return parameters.figma;\n }\n\n return undefined;\n}\n\n/**\n * Convert Storybook argTypes to Segment props\n * Merges global argTypes from preview config with meta argTypes\n */\nfunction convertArgTypes(\n argTypes: Record<string, StoryArgType>,\n globalArgTypes?: Record<string, StoryArgType>\n): Record<string, PropDefinition> {\n const props: Record<string, PropDefinition> = {};\n\n // Merge global and meta argTypes (meta takes precedence)\n const mergedArgTypes = { ...globalArgTypes, ...argTypes };\n\n for (const [name, argType] of Object.entries(mergedArgTypes)) {\n // Skip disabled argTypes\n if (argType.table?.disable) continue;\n // Skip action-only argTypes (no control)\n if (argType.control === false && argType.action) continue;\n\n // Extract control type and options\n const { controlType, controlOptions } = extractControlInfo(argType);\n\n props[name] = {\n type: inferPropType(argType),\n description: argType.description ?? `${name} prop`,\n ...(argType.options && { values: argType.options }),\n ...(argType.table?.defaultValue && {\n default: argType.table.defaultValue.summary,\n }),\n ...(argType.defaultValue !== undefined && {\n default: argType.defaultValue,\n }),\n ...(argType.type?.required && { required: true }),\n ...(controlType && { controlType }),\n ...(controlOptions && Object.keys(controlOptions).length > 0 && { controlOptions }),\n };\n }\n\n return props;\n}\n\n/**\n * Extract control type and options from a Storybook argType\n */\nfunction extractControlInfo(argType: StoryArgType): {\n controlType?: ControlType;\n controlOptions?: PropDefinition[\"controlOptions\"];\n} {\n // Handle no control or explicitly disabled control\n if (argType.control === undefined || argType.control === false) {\n return {};\n }\n\n const control = typeof argType.control === \"string\"\n ? { type: argType.control }\n : argType.control;\n\n // Map control type string to ControlType\n const validControlTypes: ControlType[] = [\n \"text\", \"number\", \"range\", \"boolean\", \"select\", \"multi-select\",\n \"radio\", \"inline-radio\", \"check\", \"inline-check\", \"object\", \"file\", \"color\", \"date\"\n ];\n\n const controlType = validControlTypes.includes(control.type as ControlType)\n ? (control.type as ControlType)\n : undefined;\n\n // Extract control options for controls that need them\n const controlOptions: PropDefinition[\"controlOptions\"] = {};\n\n if (control.min !== undefined) controlOptions.min = control.min;\n if (control.max !== undefined) controlOptions.max = control.max;\n if (control.step !== undefined) controlOptions.step = control.step;\n if (control.presetColors) controlOptions.presetColors = control.presetColors;\n\n return {\n controlType,\n controlOptions: Object.keys(controlOptions).length > 0 ? controlOptions : undefined,\n };\n}\n\n/**\n * Infer prop type from Storybook control/type\n * Handles all Storybook 8.x control types\n */\nfunction inferPropType(argType: StoryArgType): PropDefinition[\"type\"] {\n // Action argType → function\n if (argType.action) return \"function\";\n\n // If has options, it's an enum\n if (argType.options?.length) return \"enum\";\n\n // Check explicit type\n if (argType.type?.name) {\n const typeMap: Record<string, PropDefinition[\"type\"]> = {\n string: \"string\",\n number: \"number\",\n boolean: \"boolean\",\n object: \"object\",\n array: \"array\",\n function: \"function\",\n };\n const mapped = typeMap[argType.type.name];\n if (mapped) return mapped;\n }\n\n // Check control type\n const control =\n typeof argType.control === \"string\"\n ? argType.control\n : argType.control\n ? argType.control.type\n : undefined;\n\n if (control) {\n const controlMap: Record<string, PropDefinition[\"type\"]> = {\n // Text controls\n text: \"string\",\n\n // Number controls\n number: \"number\",\n range: \"number\",\n\n // Boolean controls\n boolean: \"boolean\",\n check: \"boolean\",\n \"inline-check\": \"boolean\",\n\n // Enum/selection controls\n select: \"enum\",\n \"multi-select\": \"enum\",\n radio: \"enum\",\n \"inline-radio\": \"enum\",\n\n // Object controls\n object: \"object\",\n file: \"object\",\n\n // Special string controls\n color: \"string\",\n date: \"string\",\n };\n const mapped = controlMap[control];\n if (mapped) return mapped;\n }\n\n return \"string\";\n}\n\n/**\n * Check if a value looks like a Storybook story\n * Handles both CSF 3 (objects) and CSF 2 (functions from Template.bind({}))\n */\nfunction isStory(value: unknown): value is Story | CSF2Story {\n // CSF 3: Story is an object with args/render/play\n if (typeof value === \"object\" && value !== null) {\n const obj = value as Record<string, unknown>;\n if (\"args\" in obj || \"render\" in obj || \"play\" in obj) return true;\n }\n\n // CSF 2: Story is a function (from Template.bind({})) with args attached\n if (typeof value === \"function\") {\n const fn = value as ((...args: unknown[]) => unknown) & { args?: unknown };\n if (\"args\" in fn) return true;\n }\n\n return false;\n}\n\n/**\n * Extract variants from story exports using @storybook/csf utilities\n */\nfunction extractVariants(\n storyModule: StoryModule,\n component: ComponentType<unknown>,\n meta: StoryMeta\n): SegmentVariant[] {\n const variants: SegmentVariant[] = [];\n\n for (const [exportName, exportValue] of Object.entries(storyModule)) {\n // Skip default export\n if (exportName === \"default\") continue;\n\n // Use isExportStory to filter based on includeStories/excludeStories\n if (!isExportStory(exportName, meta)) continue;\n\n // Check if it's a story\n if (!isStory(exportValue)) continue;\n\n const story = exportValue as Story | CSF2Story;\n\n // Get story name using storyNameFromExport\n const storyName =\n (typeof story === \"object\" && story.name) ||\n (typeof story === \"object\" && story.storyName) ||\n (typeof story === \"function\" && story.storyName) ||\n storyNameFromExport(exportName);\n\n // Generate story ID matching Storybook format\n const storyId = toId(meta.title || \"Unknown\", exportName);\n\n // Extract description based on story format\n let description = `${storyName} variant`;\n if (typeof story === \"object\" && story.parameters?.docs?.description?.story) {\n description = story.parameters.docs.description.story;\n }\n\n // Check for play function and capture it\n const storyPlayFn = typeof story === \"object\" ? story.play : story.play;\n const hasPlayFunction = !!storyPlayFn;\n\n // Create wrapped play function that adapts Storybook context to our PlayFunctionContext\n const wrappedPlay: PlayFunction | undefined = storyPlayFn\n ? async (context: PlayFunctionContext): Promise<void> => {\n // Build full Storybook context for compatibility\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n const fullContext = buildStoryContext(meta, story, args, storyId, storyName);\n\n // Merge our context with Storybook context\n const playContext = {\n ...fullContext,\n canvasElement: context.canvasElement,\n args: context.args,\n step: context.step,\n };\n\n await storyPlayFn(playContext as unknown as StorybookPlayFunctionContext);\n }\n : undefined;\n\n // Get story tags\n const storyTags = typeof story === \"object\" ? story.tags : undefined;\n\n // Collect loaders from global, meta, and story (in order)\n const loaders = collectLoaders(meta, story);\n\n // Compute the merged args for this variant (for code generation)\n const variantArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n };\n\n // Only include args if there are any defined\n const hasArgs = Object.keys(variantArgs).length > 0;\n\n variants.push({\n name: storyName,\n description,\n render: createRenderFunction(story, component, meta, storyId, storyName),\n // Store Storybook-specific metadata\n ...(hasPlayFunction && { hasPlayFunction: true }),\n ...(wrappedPlay && { play: wrappedPlay }),\n ...(storyId && { storyId }),\n ...(storyTags && { tags: storyTags }),\n ...(loaders.length > 0 && { loaders }),\n ...(hasArgs && { args: variantArgs }),\n });\n }\n\n return variants;\n}\n\n/**\n * Collect loaders from global, meta, and story levels\n * Returns wrapped loader functions that execute with context\n */\nfunction collectLoaders(\n meta: StoryMeta,\n story: Story | CSF2Story\n): VariantLoader[] {\n const allLoaders: Loader[] = [\n ...(globalPreviewConfig.loaders ?? []),\n ...(meta.loaders ?? []),\n ...(typeof story === \"function\" ? story.loaders ?? [] : story.loaders ?? []),\n ];\n\n if (allLoaders.length === 0) {\n return [];\n }\n\n // Wrap each loader to execute without requiring context at call time\n // The actual context will be built when the loader is executed\n return allLoaders.map((loader) => {\n return async (): Promise<Record<string, unknown>> => {\n // Create a minimal context for loader execution\n const minimalContext: StoryContext = {\n args: {},\n argTypes: {},\n globals: {},\n parameters: {},\n id: \"\",\n kind: meta.title || \"Unknown\",\n name: \"\",\n story: \"\",\n viewMode: \"story\",\n loaded: {},\n abortSignal: new AbortController().signal,\n componentId: \"\",\n title: meta.title || \"Unknown\",\n };\n return loader(minimalContext);\n };\n });\n}\n\n/**\n * Build a StoryContext for decorators and render functions\n */\nfunction buildStoryContext(\n meta: StoryMeta,\n story: Story | CSF2Story,\n args: Record<string, unknown>,\n storyId: string,\n storyName: string,\n loadedData?: Record<string, unknown>\n): StoryContext {\n const mergedArgs = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"object\" ? story.args : story.args),\n ...args,\n };\n\n const mergedArgTypes = {\n ...globalPreviewConfig.argTypes,\n ...meta.argTypes,\n ...(typeof story === \"object\" ? story.argTypes : story.argTypes),\n };\n\n const mergedParameters = {\n ...globalPreviewConfig.parameters,\n ...meta.parameters,\n ...(typeof story === \"object\" ? story.parameters : story.parameters),\n };\n\n return {\n args: mergedArgs,\n argTypes: mergedArgTypes ?? {},\n globals: {},\n parameters: mergedParameters ?? {},\n id: storyId,\n kind: meta.title || \"Unknown\",\n name: storyName,\n story: storyName,\n viewMode: \"story\",\n loaded: loadedData ?? {},\n abortSignal: new AbortController().signal,\n componentId: toId(meta.title || \"Unknown\", \"\"),\n title: meta.title || \"Unknown\",\n };\n}\n\n/**\n * Create a render function for a story\n * Handles both CSF 3 (objects) and CSF 2 (functions)\n * Applies decorators in correct order: story → meta → global (innermost first)\n * Accepts optional args overrides and loaded data from loaders\n */\nfunction createRenderFunction(\n story: Story | CSF2Story,\n component: ComponentType<unknown>,\n meta: StoryMeta,\n storyId: string,\n storyName: string\n): (options?: VariantRenderOptions) => ReactNode {\n return (options?: VariantRenderOptions) => {\n // Merge args: global → meta → story → runtime overrides\n const args = {\n ...globalPreviewConfig.args,\n ...meta.args,\n ...(typeof story === \"function\" ? story.args : story.args),\n ...options?.args, // Runtime overrides from viewer props panel\n };\n\n const loadedData = options?.loadedData;\n\n // Build the story context with loaded data\n const context = buildStoryContext(meta, story, args, storyId, storyName, loadedData);\n\n // Create the base render function\n let renderFn: () => ReactNode;\n\n if (typeof story === \"function\") {\n // CSF 2: Story is a function (from Template.bind({}))\n renderFn = () => story(args);\n } else if (story.render) {\n // CSF 3: Story has custom render function\n // Support both render(args) and render(args, context) signatures\n renderFn = () =>\n story.render!.length >= 2\n ? story.render!(args, context)\n : story.render!(args);\n } else if (meta.render) {\n // CSF 3: Meta has default render function\n renderFn = () =>\n meta.render!.length >= 2\n ? meta.render!(args, context)\n : meta.render!(args);\n } else {\n // Default: render component with args\n renderFn = () => createElement(component, args);\n }\n\n // Collect decorators in Storybook order\n // story → meta → global, then reverse to apply innermost first\n const allDecorators = [\n ...(globalPreviewConfig.decorators ?? []),\n ...(meta.decorators ?? []),\n ...(typeof story === \"function\" ? story.decorators ?? [] : story.decorators ?? []),\n ].reverse();\n\n // Apply decorators if any\n if (allDecorators.length > 0) {\n return applyDecorators(renderFn, allDecorators, context);\n }\n\n return renderFn();\n };\n}\n\n/**\n * Apply decorators in the correct order\n * Decorators wrap from innermost to outermost\n */\nfunction applyDecorators(\n renderFn: () => ReactNode,\n decorators: Decorator[],\n context: StoryContext\n): ReactNode {\n // Start with the base render function\n let storyFn: () => ReactNode = renderFn;\n\n // Each decorator wraps the previous one\n for (const decorator of decorators) {\n const wrappedFn = storyFn;\n storyFn = () => decorator(wrappedFn, context);\n }\n\n return storyFn();\n}\n\n/**\n * Convert PascalCase to Title Case\n * @deprecated Use storyNameFromExport from @storybook/csf instead\n */\nfunction pascalToTitle(name: string): string {\n return name.replace(/([A-Z])/g, \" $1\").trim();\n}\n","import {\n toId as storybookToId,\n storyNameFromExport as storybookStoryNameFromExport,\n isExportStory as storybookIsExportStory,\n} from \"@storybook/csf\";\n\nexport const toId: typeof storybookToId = (...args) => storybookToId(...args);\nexport const storyNameFromExport: typeof storybookStoryNameFromExport = (...args) =>\n storybookStoryNameFromExport(...args);\nexport const isExportStory: typeof storybookIsExportStory = (...args) =>\n storybookIsExportStory(...args);\n","import type { CompiledSegment, CompiledRecipe, PropDefinition } from \"./types.js\";\n\n/**\n * Placeholder patterns to filter out from usage text.\n * These are generated by the migrate tool and provide no value.\n */\nconst PLACEHOLDER_PATTERNS = [\n /^\\w+ component is needed$/i,\n /^Alternative component is more appropriate$/i,\n /^Use \\w+ when you need/i,\n];\n\n/**\n * Filter out placeholder text from usage arrays\n */\nfunction filterPlaceholders(items: string[]): string[] {\n return items.filter(item =>\n !PLACEHOLDER_PATTERNS.some(pattern => pattern.test(item.trim()))\n );\n}\n\n/**\n * Options for context generation\n */\nexport interface ContextOptions {\n /** Output format */\n format?: \"markdown\" | \"json\";\n\n /** What to include in the output */\n include?: {\n /** Include prop details (default: true) */\n props?: boolean;\n /** Include variant list (default: true) */\n variants?: boolean;\n /** Include usage guidelines (default: true) */\n usage?: boolean;\n /** Include related components (default: false) */\n relations?: boolean;\n /** Include code examples (default: false) */\n code?: boolean;\n };\n\n /** Compact mode - minimal output for token efficiency */\n compact?: boolean;\n}\n\n/**\n * Result of context generation\n */\nexport interface ContextResult {\n /** The generated context content */\n content: string;\n /** Estimated token count */\n tokenEstimate: number;\n}\n\n/**\n * Generate AI-ready context from compiled segments and optional recipes\n */\nexport function generateContext(\n segments: CompiledSegment[],\n options: ContextOptions = {},\n recipes?: CompiledRecipe[]\n): ContextResult {\n const format = options.format ?? \"markdown\";\n const compact = options.compact ?? false;\n\n const include = {\n props: options.include?.props ?? true,\n variants: options.include?.variants ?? true,\n usage: options.include?.usage ?? true,\n relations: options.include?.relations ?? false,\n code: options.include?.code ?? false,\n };\n\n // Sort segments by category, then name\n const sorted = [...segments].sort((a, b) => {\n const catCompare = a.meta.category.localeCompare(b.meta.category);\n if (catCompare !== 0) return catCompare;\n return a.meta.name.localeCompare(b.meta.name);\n });\n\n if (format === \"json\") {\n return generateJsonContext(sorted, include, compact, recipes);\n }\n\n return generateMarkdownContext(sorted, include, compact, recipes);\n}\n\n/**\n * Generate markdown context\n */\nfunction generateMarkdownContext(\n segments: CompiledSegment[],\n include: Required<NonNullable<ContextOptions[\"include\"]>>,\n compact: boolean,\n recipes?: CompiledRecipe[]\n): ContextResult {\n const lines: string[] = [];\n\n lines.push(\"# Design System Reference\");\n lines.push(\"\");\n\n // Quick reference table\n lines.push(\"## Quick Reference\");\n lines.push(\"\");\n lines.push(\"| Component | Category | Use For |\");\n lines.push(\"|-----------|----------|---------|\");\n\n for (const segment of segments) {\n const filteredWhen = filterPlaceholders(segment.usage.when);\n const useFor = filteredWhen.slice(0, 2).join(\", \") || segment.meta.description;\n lines.push(`| ${segment.meta.name} | ${segment.meta.category} | ${truncate(useFor, 50)} |`);\n }\n\n lines.push(\"\");\n\n // If compact mode, stop here\n if (compact) {\n const content = lines.join(\"\\n\");\n return {\n content,\n tokenEstimate: estimateTokens(content),\n };\n }\n\n // Full component documentation\n lines.push(\"## Components\");\n lines.push(\"\");\n\n for (const segment of segments) {\n lines.push(`### ${segment.meta.name}`);\n lines.push(\"\");\n\n // Status line\n const statusParts = [`**Category:** ${segment.meta.category}`];\n if (segment.meta.status) {\n statusParts.push(`**Status:** ${segment.meta.status}`);\n }\n lines.push(statusParts.join(\" | \"));\n lines.push(\"\");\n\n if (segment.meta.description) {\n lines.push(segment.meta.description);\n lines.push(\"\");\n }\n\n // Usage guidelines (filter out placeholder text)\n const whenFiltered = filterPlaceholders(segment.usage.when);\n const whenNotFiltered = filterPlaceholders(segment.usage.whenNot);\n\n if (include.usage && (whenFiltered.length > 0 || whenNotFiltered.length > 0)) {\n if (whenFiltered.length > 0) {\n lines.push(\"**When to use:**\");\n for (const when of whenFiltered) {\n lines.push(`- ${when}`);\n }\n lines.push(\"\");\n }\n\n if (whenNotFiltered.length > 0) {\n lines.push(\"**When NOT to use:**\");\n for (const whenNot of whenNotFiltered) {\n lines.push(`- ${whenNot}`);\n }\n lines.push(\"\");\n }\n }\n\n // Props\n if (include.props && Object.keys(segment.props).length > 0) {\n lines.push(\"**Props:**\");\n for (const [name, prop] of Object.entries(segment.props)) {\n lines.push(`- \\`${name}\\`: ${formatPropType(prop)}${prop.required ? \" (required)\" : \"\"}`);\n }\n lines.push(\"\");\n }\n\n // Variants\n if (include.variants && segment.variants.length > 0) {\n const variantNames = segment.variants.map((v) => v.name).join(\", \");\n lines.push(`**Variants:** ${variantNames}`);\n lines.push(\"\");\n\n // Code examples\n if (include.code) {\n for (const variant of segment.variants) {\n if (variant.code) {\n lines.push(`*${variant.name}:*`);\n lines.push(\"```tsx\");\n lines.push(variant.code);\n lines.push(\"```\");\n lines.push(\"\");\n }\n }\n }\n }\n\n // Relations\n if (include.relations && segment.relations && segment.relations.length > 0) {\n lines.push(\"**Related:**\");\n for (const relation of segment.relations) {\n lines.push(`- ${relation.component} (${relation.relationship}): ${relation.note}`);\n }\n lines.push(\"\");\n }\n\n lines.push(\"---\");\n lines.push(\"\");\n }\n\n // Recipes section\n if (recipes && recipes.length > 0) {\n lines.push(\"## Recipes\");\n lines.push(\"\");\n lines.push(\"Composition patterns showing how components wire together.\");\n lines.push(\"\");\n\n for (const recipe of recipes) {\n lines.push(`### ${recipe.name}`);\n lines.push(\"\");\n lines.push(recipe.description);\n lines.push(\"\");\n lines.push(`**Category:** ${recipe.category}`);\n lines.push(`**Components:** ${recipe.components.join(\", \")}`);\n if (recipe.tags && recipe.tags.length > 0) {\n lines.push(`**Tags:** ${recipe.tags.join(\", \")}`);\n }\n lines.push(\"\");\n lines.push(\"```tsx\");\n lines.push(recipe.code);\n lines.push(\"```\");\n lines.push(\"\");\n lines.push(\"---\");\n lines.push(\"\");\n }\n }\n\n const content = lines.join(\"\\n\");\n return {\n content,\n tokenEstimate: estimateTokens(content),\n };\n}\n\n/**\n * Generate JSON context\n */\nfunction generateJsonContext(\n segments: CompiledSegment[],\n include: Required<NonNullable<ContextOptions[\"include\"]>>,\n compact: boolean,\n recipes?: CompiledRecipe[]\n): ContextResult {\n const categories = [...new Set(segments.map((s) => s.meta.category))].sort();\n\n interface JsonComponent {\n category: string;\n description: string;\n status?: string;\n whenToUse?: string[];\n whenNotToUse?: string[];\n props?: Record<string, { type: string; required?: boolean; default?: unknown; description: string }>;\n variants?: string[];\n relations?: Array<{ component: string; relationship: string; note: string }>;\n }\n\n const components: Record<string, JsonComponent> = {};\n\n for (const segment of segments) {\n const component: JsonComponent = {\n category: segment.meta.category,\n description: segment.meta.description,\n };\n\n if (segment.meta.status) {\n component.status = segment.meta.status;\n }\n\n if (!compact) {\n if (include.usage) {\n const whenFiltered = filterPlaceholders(segment.usage.when);\n const whenNotFiltered = filterPlaceholders(segment.usage.whenNot);\n if (whenFiltered.length > 0) {\n component.whenToUse = whenFiltered;\n }\n if (whenNotFiltered.length > 0) {\n component.whenNotToUse = whenNotFiltered;\n }\n }\n\n if (include.props && Object.keys(segment.props).length > 0) {\n component.props = {};\n for (const [name, prop] of Object.entries(segment.props)) {\n component.props[name] = {\n type: formatPropType(prop),\n description: prop.description,\n };\n if (prop.required) {\n component.props[name].required = true;\n }\n if (prop.default !== undefined) {\n component.props[name].default = prop.default;\n }\n }\n }\n\n if (include.variants && segment.variants.length > 0) {\n component.variants = segment.variants.map((v) => v.name);\n }\n\n if (include.relations && segment.relations && segment.relations.length > 0) {\n component.relations = segment.relations.map((r) => ({\n component: r.component,\n relationship: r.relationship,\n note: r.note,\n }));\n }\n }\n\n components[segment.meta.name] = component;\n }\n\n // Build recipes map\n const recipesMap = recipes && recipes.length > 0\n ? Object.fromEntries(recipes.map(r => [r.name, {\n description: r.description,\n category: r.category,\n components: r.components,\n code: r.code,\n tags: r.tags,\n }]))\n : undefined;\n\n const output = {\n version: \"1.0\",\n generatedAt: new Date().toISOString(),\n summary: {\n totalComponents: segments.length,\n categories,\n ...(recipesMap && { totalRecipes: recipes!.length }),\n },\n components,\n ...(recipesMap && { recipes: recipesMap }),\n };\n\n const content = JSON.stringify(output, null, 2);\n return {\n content,\n tokenEstimate: estimateTokens(content),\n };\n}\n\n/**\n * Format a prop type for display\n */\nfunction formatPropType(prop: PropDefinition): string {\n if (prop.type === \"enum\" && prop.values) {\n return prop.values.map((v) => `\"${v}\"`).join(\" | \");\n }\n if (prop.default !== undefined) {\n return `${prop.type} (default: ${JSON.stringify(prop.default)})`;\n }\n return prop.type;\n}\n\n/**\n * Truncate string to max length\n */\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + \"...\";\n}\n\n/**\n * Estimate token count (rough approximation: ~4 chars per token)\n */\nfunction estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","/**\n * Figma property mapping DSL\n *\n * Provides helpers for mapping Figma component properties to code props.\n * Inspired by Figma Code Connect's API.\n *\n * @example\n * ```tsx\n * import { defineSegment, figma } from '@fragments/core';\n *\n * export default defineSegment({\n * component: Button,\n * meta: {\n * name: 'Button',\n * description: 'Primary action trigger',\n * category: 'actions',\n * figma: 'https://figma.com/file/abc/Design?node-id=1-2',\n * figmaProps: {\n * children: figma.string('Label'),\n * disabled: figma.boolean('Disabled'),\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * }),\n * },\n * },\n * // ...\n * });\n * ```\n */\n\nimport type {\n FigmaStringMapping,\n FigmaBooleanMapping,\n FigmaEnumMapping,\n FigmaInstanceMapping,\n FigmaChildrenMapping,\n FigmaTextContentMapping,\n} from './types.js';\n\n/**\n * Map a Figma text property to a string prop.\n *\n * @param figmaProperty - The name of the text property in Figma\n * @returns A string mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * label: figma.string('Button Text'),\n * placeholder: figma.string('Placeholder'),\n * }\n * ```\n */\nfunction string(figmaProperty: string): FigmaStringMapping {\n return {\n __type: 'figma-string',\n figmaProperty,\n };\n}\n\n/**\n * Map a Figma boolean property to a boolean prop.\n * Optionally map true/false to different values.\n *\n * @param figmaProperty - The name of the boolean property in Figma\n * @param valueMapping - Optional mapping of true/false to other values\n * @returns A boolean mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * disabled: figma.boolean('Disabled'),\n * // Map boolean to string values\n * size: figma.boolean('Large', { true: 'lg', false: 'md' }),\n * }\n * ```\n */\nfunction boolean(\n figmaProperty: string,\n valueMapping?: { true: unknown; false: unknown }\n): FigmaBooleanMapping {\n return {\n __type: 'figma-boolean',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Map a Figma variant property to an enum prop.\n *\n * @param figmaProperty - The name of the variant property in Figma\n * @param valueMapping - Mapping of Figma values to code values\n * @returns An enum mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * variant: figma.enum('Type', {\n * 'Primary': 'primary',\n * 'Secondary': 'secondary',\n * 'Outline': 'outline',\n * }),\n * size: figma.enum('Size', {\n * 'Small': 'sm',\n * 'Medium': 'md',\n * 'Large': 'lg',\n * }),\n * }\n * ```\n */\nfunction enumValue<T extends Record<string, unknown>>(\n figmaProperty: string,\n valueMapping: T\n): FigmaEnumMapping {\n return {\n __type: 'figma-enum',\n figmaProperty,\n valueMapping,\n };\n}\n\n/**\n * Reference a nested Figma component instance.\n * Use this when a prop accepts a component that's represented\n * as an instance swap in Figma.\n *\n * @param figmaProperty - The name of the instance property in Figma\n * @returns An instance mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * icon: figma.instance('Icon'),\n * avatar: figma.instance('Avatar'),\n * }\n * ```\n */\nfunction instance(figmaProperty: string): FigmaInstanceMapping {\n return {\n __type: 'figma-instance',\n figmaProperty,\n };\n}\n\n/**\n * Render children from specific Figma layers.\n * Use this when children are represented as named layers in Figma.\n *\n * @param layers - Array of layer names to include as children\n * @returns A children mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * children: figma.children(['Title', 'Description', 'Actions']),\n * }\n * ```\n */\nfunction children(layers: string[]): FigmaChildrenMapping {\n return {\n __type: 'figma-children',\n layers,\n };\n}\n\n/**\n * Extract text content from a Figma text layer.\n * Use this when a prop should be the actual text from a layer.\n *\n * @param layer - The name of the text layer in Figma\n * @returns A text content mapping descriptor\n *\n * @example\n * ```tsx\n * figmaProps: {\n * title: figma.textContent('Header Text'),\n * description: figma.textContent('Body Text'),\n * }\n * ```\n */\nfunction textContent(layer: string): FigmaTextContentMapping {\n return {\n __type: 'figma-text-content',\n layer,\n };\n}\n\n/**\n * Figma property mapping helpers.\n *\n * Use these to define how Figma properties map to your component props.\n * The mappings are used for:\n * - Generating accurate code snippets in Figma Dev Mode\n * - AI agents understanding the design-to-code relationship\n * - Automated design verification\n */\nexport const figma = {\n string,\n boolean,\n enum: enumValue,\n instance,\n children,\n textContent,\n} as const;\n\n/**\n * Helper type to check if a value is a Figma prop mapping\n */\nexport function isFigmaPropMapping(\n value: unknown\n): value is FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping {\n if (typeof value !== 'object' || value === null || !('__type' in value)) {\n return false;\n }\n const typeValue = (value as Record<string, unknown>).__type;\n return typeof typeValue === 'string' && typeValue.startsWith('figma-');\n}\n\n/**\n * Resolve a Figma prop mapping to an actual value given Figma property values.\n *\n * @param mapping - The Figma prop mapping\n * @param figmaValues - Object containing Figma property values\n * @returns The resolved value for the code prop\n */\nexport function resolveFigmaMapping(\n mapping: FigmaStringMapping | FigmaBooleanMapping | FigmaEnumMapping | FigmaInstanceMapping | FigmaChildrenMapping | FigmaTextContentMapping,\n figmaValues: Record<string, unknown>\n): unknown {\n switch (mapping.__type) {\n case 'figma-string':\n return figmaValues[mapping.figmaProperty] ?? '';\n\n case 'figma-boolean': {\n const boolValue = figmaValues[mapping.figmaProperty] as boolean;\n if (mapping.valueMapping) {\n return boolValue ? mapping.valueMapping.true : mapping.valueMapping.false;\n }\n return boolValue;\n }\n\n case 'figma-enum': {\n const enumKey = figmaValues[mapping.figmaProperty] as string;\n return mapping.valueMapping[enumKey] ?? enumKey;\n }\n\n case 'figma-instance':\n // Instance mappings return the instance reference\n return figmaValues[mapping.figmaProperty];\n\n case 'figma-children':\n // Children mappings return array of layer contents\n return mapping.layers.map((layer) => figmaValues[layer]);\n\n case 'figma-text-content':\n return figmaValues[mapping.layer] ?? '';\n\n default:\n return undefined;\n }\n}\n","import type { CompiledSegment, RelationshipType } from \"./types.js\";\n\n// --- Public types ---\n\nexport interface CompositionWarning {\n type:\n | \"missing_parent\"\n | \"missing_child\"\n | \"missing_composition\"\n | \"redundant_alternative\"\n | \"deprecated\"\n | \"experimental\";\n component: string;\n message: string;\n relatedComponent?: string;\n}\n\nexport interface CompositionSuggestion {\n component: string;\n reason: string;\n relationship: RelationshipType | \"category_gap\";\n sourceComponent: string;\n}\n\nexport interface CompositionGuideline {\n component: string;\n guideline: string;\n}\n\nexport interface CompositionAnalysis {\n /** The validated component names (filtered to those that exist) */\n components: string[];\n\n /** Components requested but not found in the registry */\n unknown: string[];\n\n /** Issues with the current selection */\n warnings: CompositionWarning[];\n\n /** Components to consider adding */\n suggestions: CompositionSuggestion[];\n\n /** Relevant usage guidelines for the selected components */\n guidelines: CompositionGuideline[];\n}\n\n// --- Category affinities ---\n\nconst CATEGORY_AFFINITIES: Record<string, string[]> = {\n forms: [\"feedback\"],\n actions: [\"feedback\"],\n};\n\n// --- Main function ---\n\n/**\n * Analyzes a set of components as a composition group.\n * Returns warnings about missing relations, usage conflicts,\n * and suggestions for additional components.\n *\n * Browser-safe: no Node.js APIs used.\n */\nexport function analyzeComposition(\n segments: Record<string, CompiledSegment>,\n componentNames: string[],\n _context?: string\n): CompositionAnalysis {\n const allNames = new Set(Object.keys(segments));\n\n // 1. Validate names\n const components: string[] = [];\n const unknown: string[] = [];\n for (const name of componentNames) {\n if (allNames.has(name)) {\n components.push(name);\n } else {\n unknown.push(name);\n }\n }\n\n const selectedSet = new Set(components);\n const warnings: CompositionWarning[] = [];\n const suggestions: CompositionSuggestion[] = [];\n const guidelines: CompositionGuideline[] = [];\n\n // Track suggestions to avoid duplicates\n const suggestedSet = new Set<string>();\n\n for (const name of components) {\n const segment = segments[name];\n\n // 2. Relation checks\n if (segment.relations) {\n for (const rel of segment.relations) {\n switch (rel.relationship) {\n case \"parent\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_parent\",\n component: name,\n message: `\"${name}\" expects to be wrapped by \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"child\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${name}\" typically contains \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"child\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"composition\":\n if (!selectedSet.has(rel.component)) {\n warnings.push({\n type: \"missing_composition\",\n component: name,\n message: `\"${name}\" is typically used together with \"${rel.component}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n\n case \"sibling\":\n if (!selectedSet.has(rel.component) && !suggestedSet.has(rel.component)) {\n suggestions.push({\n component: rel.component,\n reason: `\"${rel.component}\" is a sibling of \"${name}\"${rel.note ? `: ${rel.note}` : \"\"}`,\n relationship: \"sibling\",\n sourceComponent: name,\n });\n suggestedSet.add(rel.component);\n }\n break;\n\n case \"alternative\":\n if (selectedSet.has(rel.component)) {\n warnings.push({\n type: \"redundant_alternative\",\n component: name,\n message: `\"${name}\" and \"${rel.component}\" are alternatives — using both may be redundant${rel.note ? `: ${rel.note}` : \"\"}`,\n relatedComponent: rel.component,\n });\n }\n break;\n }\n }\n }\n\n // 3. Usage conflict checks (whenNot)\n if (segment.usage?.whenNot) {\n for (const whenNotEntry of segment.usage.whenNot) {\n const lower = whenNotEntry.toLowerCase();\n for (const other of components) {\n if (other !== name && lower.includes(other.toLowerCase())) {\n guidelines.push({\n component: name,\n guideline: `Potential conflict with \"${other}\": ${whenNotEntry}`,\n });\n }\n }\n }\n }\n\n // 4. Status warnings\n if (segment.meta.status === \"deprecated\") {\n warnings.push({\n type: \"deprecated\",\n component: name,\n message: segment.meta.description\n ? `\"${name}\" is deprecated: ${segment.meta.description}`\n : `\"${name}\" is deprecated`,\n });\n } else if (segment.meta.status === \"experimental\") {\n warnings.push({\n type: \"experimental\",\n component: name,\n message: `\"${name}\" is experimental and may change without notice`,\n });\n }\n }\n\n // 5. Category gap analysis\n const selectedCategories = new Set(\n components.map((name) => segments[name].meta.category)\n );\n\n for (const [category, affinities] of Object.entries(CATEGORY_AFFINITIES)) {\n if (!selectedCategories.has(category)) continue;\n\n for (const neededCategory of affinities) {\n if (selectedCategories.has(neededCategory)) continue;\n\n // Find the best component from the needed category\n const candidate = findBestCategoryCandidate(\n segments,\n neededCategory,\n selectedSet,\n suggestedSet\n );\n if (candidate) {\n suggestions.push({\n component: candidate,\n reason: `Compositions using \"${category}\" components often benefit from a \"${neededCategory}\" component`,\n relationship: \"category_gap\",\n sourceComponent: components.find(\n (n) => segments[n].meta.category === category\n )!,\n });\n suggestedSet.add(candidate);\n }\n }\n }\n\n return { components, unknown, warnings, suggestions, guidelines };\n}\n\n/**\n * Find the best candidate component from a given category.\n * Prefers stable components and avoids already-selected or already-suggested ones.\n */\nfunction findBestCategoryCandidate(\n segments: Record<string, CompiledSegment>,\n category: string,\n selectedSet: Set<string>,\n suggestedSet: Set<string>\n): string | null {\n let best: string | null = null;\n let bestScore = -1;\n\n for (const [name, segment] of Object.entries(segments)) {\n if (segment.meta.category !== category) continue;\n if (selectedSet.has(name) || suggestedSet.has(name)) continue;\n\n const status = segment.meta.status ?? \"stable\";\n let score = 0;\n if (status === \"stable\") score = 3;\n else if (status === \"beta\") score = 2;\n else if (status === \"experimental\") score = 1;\n // deprecated gets 0\n\n if (score > bestScore) {\n bestScore = score;\n best = name;\n }\n }\n\n return best;\n}\n"],"mappings":"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","names":["content"]}
|
|
@@ -8,14 +8,14 @@ import {
|
|
|
8
8
|
inferAllRelations,
|
|
9
9
|
parseAllStories,
|
|
10
10
|
scanCodebase
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5ZYEOHYK.js";
|
|
12
12
|
import {
|
|
13
13
|
discoverAllComponents,
|
|
14
14
|
loadConfig
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5CKYLCJH.js";
|
|
16
16
|
import {
|
|
17
17
|
BRAND
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-AW7MWOUH.js";
|
|
19
19
|
|
|
20
20
|
// src/commands/scan.ts
|
|
21
21
|
import { writeFile, mkdir } from "fs/promises";
|
|
@@ -366,4 +366,4 @@ function calculateConfidence(props, usageAnalysis, storyFile) {
|
|
|
366
366
|
export {
|
|
367
367
|
scan
|
|
368
368
|
};
|
|
369
|
-
//# sourceMappingURL=chunk-
|
|
369
|
+
//# sourceMappingURL=chunk-J4SI5RIH.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
BRAND
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AW7MWOUH.js";
|
|
5
5
|
|
|
6
6
|
// src/static-viewer.ts
|
|
7
7
|
import { readFile } from "fs/promises";
|
|
@@ -616,4 +616,4 @@ export {
|
|
|
616
616
|
generateStaticViewer,
|
|
617
617
|
generateViewerFromJson
|
|
618
618
|
};
|
|
619
|
-
//# sourceMappingURL=chunk-
|
|
619
|
+
//# sourceMappingURL=chunk-NOTYONHY.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
formatMs,
|
|
9
9
|
generateHtmlReport,
|
|
10
10
|
getGrade
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-5ZYEOHYK.js";
|
|
12
12
|
import {
|
|
13
13
|
discoverComponentFiles,
|
|
14
14
|
discoverRecipeFiles,
|
|
@@ -18,15 +18,15 @@ import {
|
|
|
18
18
|
generateRegistry,
|
|
19
19
|
loadSegmentFile,
|
|
20
20
|
parseSegmentFile
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-5CKYLCJH.js";
|
|
22
22
|
import {
|
|
23
23
|
compileRecipe
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-G3M3MPQ6.js";
|
|
25
25
|
import {
|
|
26
26
|
BRAND,
|
|
27
27
|
DEFAULTS,
|
|
28
28
|
segmentDefinitionSchema
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-AW7MWOUH.js";
|
|
30
30
|
|
|
31
31
|
// src/validators.ts
|
|
32
32
|
async function validateSchema(config, configDir) {
|
|
@@ -180,7 +180,9 @@ async function buildSegments(config, configDir) {
|
|
|
180
180
|
...v.code && { code: v.code },
|
|
181
181
|
...v.figma && { figma: v.figma },
|
|
182
182
|
...v.args && { args: v.args }
|
|
183
|
-
}))
|
|
183
|
+
})),
|
|
184
|
+
// Include AI metadata if present
|
|
185
|
+
...parsed.ai && { ai: parsed.ai }
|
|
184
186
|
};
|
|
185
187
|
segments[parsed.meta.name] = compiled;
|
|
186
188
|
} catch (error) {
|
|
@@ -794,4 +796,4 @@ export {
|
|
|
794
796
|
runDiffCommand,
|
|
795
797
|
runAnalyzeCommand
|
|
796
798
|
};
|
|
797
|
-
//# sourceMappingURL=chunk-
|
|
799
|
+
//# sourceMappingURL=chunk-ZFKGX3QK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/validators.ts","../src/build.ts","../src/screenshot.ts","../src/diff.ts","../src/analyze.ts"],"sourcesContent":["import { segmentDefinitionSchema, BRAND, type SegmentsConfig } from './core/index.js';\nimport {\n discoverSegmentFiles,\n discoverComponentFiles,\n extractComponentName,\n loadSegmentFile,\n type DiscoveredFile,\n} from './core/node.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\nexport interface ValidationError {\n file: string;\n message: string;\n details?: string;\n}\n\nexport interface ValidationWarning {\n file: string;\n message: string;\n}\n\n/**\n * Validate segment file schema\n */\nexport async function validateSchema(\n config: SegmentsConfig,\n configDir: string\n): Promise<ValidationResult> {\n const files = await discoverSegmentFiles(config, configDir);\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n for (const file of files) {\n try {\n const segment = await loadSegmentFile(file.absolutePath);\n\n if (!segment) {\n errors.push({\n file: file.relativePath,\n message: 'No default export found',\n details: `Segment files must have a default export from defineSegment()`,\n });\n continue;\n }\n\n const result = segmentDefinitionSchema.safeParse(segment);\n\n if (!result.success) {\n const details = result.error.errors\n .map((e) => `${e.path.join('.')}: ${e.message}`)\n .join('; ');\n\n errors.push({\n file: file.relativePath,\n message: 'Invalid segment schema',\n details,\n });\n }\n } catch (error) {\n errors.push({\n file: file.relativePath,\n message: 'Failed to load segment file',\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Validate coverage - ensure all components have segments\n */\nexport async function validateCoverage(\n config: SegmentsConfig,\n configDir: string\n): Promise<ValidationResult> {\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n const componentFiles = await discoverComponentFiles(config, configDir);\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n // Build set of documented component names\n const documentedComponents = new Set<string>();\n\n for (const file of segmentFiles) {\n try {\n const segment = await loadSegmentFile(file.absolutePath);\n\n if (segment?.meta?.name) {\n documentedComponents.add(segment.meta.name);\n }\n } catch {\n // Skip files that fail to load - schema validation will catch these\n }\n }\n\n // Check each component file\n for (const file of componentFiles) {\n const componentName = extractComponentName(file.relativePath);\n\n // Check if there's a corresponding segment file\n const segmentPath = file.relativePath.replace(\n /\\.(tsx?|jsx?)$/,\n BRAND.fileExtension\n );\n const hasSegmentFile = segmentFiles.some(\n (s) => s.relativePath === segmentPath\n );\n\n if (!hasSegmentFile && !documentedComponents.has(componentName)) {\n warnings.push({\n file: file.relativePath,\n message: `Component \"${componentName}\" has no segment documentation`,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Run all validations\n */\nexport async function validateAll(\n config: SegmentsConfig,\n configDir: string\n): Promise<ValidationResult> {\n const [schemaResult, coverageResult] = await Promise.all([\n validateSchema(config, configDir),\n validateCoverage(config, configDir),\n ]);\n\n return {\n valid: schemaResult.valid && coverageResult.valid,\n errors: [...schemaResult.errors, ...coverageResult.errors],\n warnings: [...schemaResult.warnings, ...coverageResult.warnings],\n };\n}\n","import { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { resolve, join } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport type {\n SegmentsConfig,\n CompiledSegmentsFile,\n CompiledSegment,\n CompiledRecipe,\n} from \"./core/index.js\";\nimport { BRAND, compileRecipe } from \"./core/index.js\";\nimport type { RecipeDefinition } from \"./core/index.js\";\nimport {\n discoverSegmentFiles,\n discoverRecipeFiles,\n parseSegmentFile,\n loadSegmentFile,\n generateRegistry,\n generateContextMd,\n} from \"./core/node.js\";\n\nexport interface BuildResult {\n success: boolean;\n outputPath: string;\n segmentCount: number;\n errors: Array<{ file: string; error: string }>;\n warnings: Array<{ file: string; warning: string }>;\n}\n\n/**\n * Build compiled fragments.json file for AI consumption.\n *\n * Uses AST parsing to extract metadata WITHOUT executing fragment files.\n * This means the build works without any project dependencies installed.\n */\nexport async function buildSegments(\n config: SegmentsConfig,\n configDir: string\n): Promise<BuildResult> {\n const files = await discoverSegmentFiles(config, configDir);\n const errors: Array<{ file: string; error: string }> = [];\n const warnings: Array<{ file: string; warning: string }> = [];\n const segments: CompiledSegmentsFile[\"segments\"] = {};\n\n for (const file of files) {\n try {\n // Read file content as text\n const content = await readFile(file.absolutePath, \"utf-8\");\n\n // Parse using AST (no execution)\n const parsed = parseSegmentFile(content, file.relativePath);\n\n // Collect warnings\n for (const warning of parsed.warnings) {\n warnings.push({ file: file.relativePath, warning });\n }\n\n // Check for required fields\n if (!parsed.meta.name) {\n errors.push({\n file: file.relativePath,\n error: \"Missing meta.name in fragment definition\",\n });\n continue;\n }\n\n // Build compiled fragment from parsed metadata\n const compiled: CompiledSegment = {\n filePath: file.relativePath,\n meta: {\n name: parsed.meta.name,\n description: parsed.meta.description ?? \"\",\n category: parsed.meta.category ?? \"Uncategorized\",\n status: parsed.meta.status,\n tags: parsed.meta.tags,\n since: parsed.meta.since,\n figma: parsed.meta.figma,\n },\n usage: {\n when: parsed.usage.when ?? [],\n whenNot: parsed.usage.whenNot ?? [],\n guidelines: parsed.usage.guidelines,\n accessibility: parsed.usage.accessibility,\n },\n props: Object.fromEntries(\n Object.entries(parsed.props).map(([name, prop]) => [\n name,\n {\n type: prop.type ?? \"custom\",\n description: prop.description ?? \"\",\n default: prop.default,\n required: prop.required,\n values: prop.values,\n constraints: prop.constraints,\n },\n ])\n ),\n relations: parsed.relations.map((rel) => ({\n component: rel.component,\n relationship: rel.relationship as\n | \"alternative\"\n | \"sibling\"\n | \"parent\"\n | \"child\"\n | \"composition\",\n note: rel.note,\n })),\n variants: parsed.variants.map((v) => ({\n name: v.name,\n description: v.description,\n ...(v.code && { code: v.code }),\n ...(v.figma && { figma: v.figma }),\n ...(v.args && { args: v.args }),\n })),\n // Include AI metadata if present\n ...(parsed.ai && { ai: parsed.ai }),\n };\n\n segments[parsed.meta.name] = compiled;\n } catch (error) {\n errors.push({\n file: file.relativePath,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Discover and compile recipe files\n const recipes: Record<string, CompiledRecipe> = {};\n try {\n const recipeFiles = await discoverRecipeFiles(configDir, config.exclude);\n for (const file of recipeFiles) {\n try {\n // loadSegmentFile uses esbuild to bundle+evaluate, returns default export\n // CJS/ESM interop may double-wrap the default export\n let raw = await loadSegmentFile(file.absolutePath) as unknown as Record<string, unknown> | null;\n // Unwrap double-default from CJS interop\n if (raw && 'default' in raw && typeof raw.default === 'object') {\n raw = raw.default as Record<string, unknown>;\n }\n const def = raw;\n if (def && typeof def === 'object' && 'name' in def && 'code' in def && 'components' in def) {\n const compiled = compileRecipe(def as unknown as RecipeDefinition, file.relativePath);\n recipes[compiled.name] = compiled;\n }\n } catch (error) {\n warnings.push({\n file: file.relativePath,\n warning: `Failed to load recipe: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n }\n } catch {\n // Recipe discovery failure is non-fatal\n }\n\n // Read package name for import statements\n let packageName: string | undefined;\n const pkgJsonPath = resolve(configDir, \"package.json\");\n if (existsSync(pkgJsonPath)) {\n try {\n const pkg = JSON.parse(await readFile(pkgJsonPath, \"utf-8\"));\n if (pkg.name) packageName = pkg.name;\n } catch {\n // Non-fatal\n }\n }\n\n const output: CompiledSegmentsFile = {\n version: \"1.0.0\",\n generatedAt: new Date().toISOString(),\n ...(packageName && { packageName }),\n segments,\n ...(Object.keys(recipes).length > 0 && { recipes }),\n };\n\n const outputPath = resolve(configDir, config.outFile ?? BRAND.outFile);\n await writeFile(outputPath, JSON.stringify(output));\n\n return {\n success: errors.length === 0,\n outputPath,\n segmentCount: Object.keys(segments).length,\n errors,\n warnings,\n };\n}\n\n/**\n * Result of building the .fragments directory\n */\nexport interface FragmentsBuildResult {\n success: boolean;\n indexPath: string;\n registryPath: string;\n contextPath: string;\n componentCount: number;\n errors: Array<{ file: string; error: string }>;\n warnings: Array<{ file: string; warning: string }>;\n}\n\n/**\n * Build the .fragments/ directory with index.json, registry.json, and context.md\n *\n * This generates:\n * - .fragments/index.json - Minimal name → path mapping (tiny, for quick lookups)\n * - .fragments/registry.json - Component index with paths and enrichment references\n * - .fragments/context.md - AI-ready consolidated context file\n */\nexport async function buildFragmentsDir(\n config: SegmentsConfig,\n configDir: string\n): Promise<FragmentsBuildResult> {\n const fragmentsDir = join(configDir, BRAND.dataDir);\n const componentsDir = join(fragmentsDir, BRAND.componentsDir);\n\n // Create directories\n await mkdir(fragmentsDir, { recursive: true });\n await mkdir(componentsDir, { recursive: true });\n\n // Generate registry with config options\n const registryResult = await generateRegistry({\n projectRoot: configDir,\n componentPatterns: config.components || [\"src/**/*.tsx\", \"src/**/*.ts\"],\n storyPatterns: config.include || [\"src/**/*.stories.tsx\"],\n fragmentsDir,\n registryOptions: config.registry || {},\n });\n\n const errors = [...registryResult.errors];\n const warnings = [...registryResult.warnings];\n\n // Write index.json (minimal name → path)\n const indexPath = join(fragmentsDir, \"index.json\");\n await writeFile(indexPath, JSON.stringify(registryResult.index, null, 2));\n\n // Write registry.json (full metadata)\n const registryPath = join(fragmentsDir, BRAND.registryFile);\n await writeFile(registryPath, JSON.stringify(registryResult.registry, null, 2));\n\n // Generate context.md - focus on semantic knowledge, skip props (AI can read source)\n const contextResult = generateContextMd(registryResult.registry, {\n format: \"markdown\",\n compact: false,\n include: {\n props: false, // AI can read TypeScript directly\n relations: true,\n code: false,\n },\n });\n\n // Write context.md\n const contextPath = join(fragmentsDir, BRAND.contextFile);\n await writeFile(contextPath, contextResult.content);\n\n return {\n success: errors.length === 0,\n indexPath,\n registryPath,\n contextPath,\n componentCount: registryResult.registry.componentCount,\n errors,\n warnings,\n };\n}\n","import pc from 'picocolors';\nimport {\n BRAND,\n DEFAULTS,\n type SegmentsConfig,\n type SegmentDefinition,\n type Theme,\n} from './core/index.js';\nimport { discoverSegmentFiles, loadSegmentFile } from './core/node.js';\nimport {\n BrowserPool,\n CaptureEngine,\n StorageManager,\n formatMs,\n type CaptureOptions,\n} from './service/index.js';\n\n/**\n * Options for the screenshot command\n */\nexport interface ScreenshotCommandOptions {\n /** Specific component to capture */\n component?: string;\n\n /** Specific variant to capture */\n variant?: string;\n\n /** Theme to capture */\n theme?: Theme;\n\n /** Update existing baselines */\n update?: boolean;\n\n /** CI mode - no interactive prompts */\n ci?: boolean;\n\n /** Viewport width */\n width?: number;\n\n /** Viewport height */\n height?: number;\n}\n\n/**\n * Result of the screenshot command\n */\nexport interface ScreenshotResult {\n success: boolean;\n captured: number;\n skipped: number;\n errors: Array<{ component: string; variant: string; error: string }>;\n totalTimeMs: number;\n}\n\n/**\n * Execute the screenshot command\n */\nexport async function runScreenshotCommand(\n config: SegmentsConfig,\n configDir: string,\n options: ScreenshotCommandOptions = {}\n): Promise<ScreenshotResult> {\n const startTime = Date.now();\n const errors: ScreenshotResult['errors'] = [];\n\n // Initialize storage\n const storage = new StorageManager({\n projectRoot: configDir,\n viewport: options.width && options.height\n ? { width: options.width, height: options.height }\n : config.screenshots?.viewport,\n });\n await storage.initialize();\n\n // Discover segments\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n\n if (segmentFiles.length === 0) {\n console.log(pc.yellow('No segment files found.'));\n return {\n success: true,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Load all segments\n const segments: Array<{ path: string; segment: SegmentDefinition }> = [];\n\n for (const file of segmentFiles) {\n try {\n const segment = await loadSegmentFile(file.absolutePath);\n if (segment) {\n segments.push({ path: file.relativePath, segment });\n }\n } catch (error) {\n errors.push({\n component: file.relativePath,\n variant: '',\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Filter by component if specified\n const filteredSegments = options.component\n ? segments.filter((s) => s.segment.meta.name === options.component)\n : segments;\n\n if (options.component && filteredSegments.length === 0) {\n console.log(pc.yellow(`Component \"${options.component}\" not found.`));\n return {\n success: false,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Build list of variants to capture\n const variantsToCapture: Array<{\n component: string;\n variant: string;\n render: () => unknown;\n }> = [];\n\n for (const { segment } of filteredSegments) {\n const variants = options.variant\n ? segment.variants.filter((v) => v.name === options.variant)\n : segment.variants;\n\n for (const variant of variants) {\n variantsToCapture.push({\n component: segment.meta.name,\n variant: variant.name,\n render: variant.render,\n });\n }\n }\n\n if (variantsToCapture.length === 0) {\n console.log(pc.yellow('No variants to capture.'));\n return {\n success: true,\n captured: 0,\n skipped: 0,\n errors: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Determine theme\n const theme: Theme = options.theme ?? DEFAULTS.theme;\n const viewport = {\n width: options.width ?? config.screenshots?.viewport?.width ?? DEFAULTS.viewport.width,\n height: options.height ?? config.screenshots?.viewport?.height ?? DEFAULTS.viewport.height,\n };\n\n console.log(pc.cyan(`\\n${BRAND.name} Screenshot\\n`));\n console.log(pc.dim(`Capturing variants (theme: ${theme}, viewport: ${viewport.width}x${viewport.height}):\\n`));\n\n // Initialize browser pool\n const pool = new BrowserPool({\n viewport,\n });\n\n // Create capture engine - use the viewer URL\n const viewerPort = DEFAULTS.port;\n const baseUrl = `http://localhost:${viewerPort}`;\n const captureEngine = new CaptureEngine(pool, baseUrl);\n\n let captured = 0;\n let skipped = 0;\n\n const captureOptions: CaptureOptions = {\n theme,\n viewport,\n delay: config.screenshots?.delay ?? DEFAULTS.captureDelayMs,\n };\n\n try {\n // Warm up the pool\n console.log(pc.dim('Starting browser...'));\n await pool.warmup();\n console.log(pc.dim('Browser ready.\\n'));\n\n // Capture each variant\n for (const { component, variant } of variantsToCapture) {\n const hasExisting = storage.hasBaseline(component, variant, theme);\n\n // Skip if exists and not updating\n if (hasExisting && !options.update) {\n console.log(` ${pc.dim('○')} ${component}/${variant} ${pc.dim('(skipped)')}`);\n skipped++;\n continue;\n }\n\n try {\n const screenshot = await captureEngine.captureVariant(\n component,\n variant,\n captureOptions\n );\n\n await storage.saveBaseline(screenshot);\n\n const totalTime = screenshot.metadata.renderTimeMs + screenshot.metadata.captureTimeMs;\n console.log(\n ` ${pc.green('✓')} ${component}/${variant} ${pc.dim(formatMs(totalTime))}`\n );\n captured++;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.log(` ${pc.red('✗')} ${component}/${variant} ${pc.dim(errorMsg)}`);\n errors.push({ component, variant, error: errorMsg });\n }\n }\n } finally {\n // Shutdown browser pool\n await pool.shutdown();\n }\n\n const totalTimeMs = Date.now() - startTime;\n\n // Print summary\n console.log();\n if (errors.length === 0) {\n console.log(pc.green(`✓ Captured ${captured} screenshot(s) in ${formatMs(totalTimeMs)}`));\n } else {\n console.log(pc.yellow(`⚠ Captured ${captured} screenshot(s) with ${errors.length} error(s)`));\n }\n\n if (skipped > 0) {\n console.log(pc.dim(` ${skipped} skipped (use --update to recapture)`));\n }\n\n console.log(pc.dim(` Stored in ${storage.screenshotsDirPath}\\n`));\n\n return {\n success: errors.length === 0,\n captured,\n skipped,\n errors,\n totalTimeMs,\n };\n}\n","import pc from 'picocolors';\nimport {\n BRAND,\n DEFAULTS,\n type SegmentsConfig,\n type SegmentDefinition,\n type Theme,\n} from './core/index.js';\nimport { discoverSegmentFiles, loadSegmentFile } from './core/node.js';\nimport {\n BrowserPool,\n CaptureEngine,\n StorageManager,\n DiffEngine,\n formatMs,\n type CaptureOptions,\n type DiffResult,\n} from './service/index.js';\n\n/**\n * Options for the diff command\n */\nexport interface DiffCommandOptions {\n /** Specific component to diff */\n component?: string;\n\n /** Specific variant to diff */\n variant?: string;\n\n /** Theme to compare */\n theme?: Theme;\n\n /** CI mode - exit 1 on differences */\n ci?: boolean;\n\n /** Diff threshold percentage */\n threshold?: number;\n\n /** Open diff images */\n open?: boolean;\n}\n\n/**\n * Single diff result with metadata\n */\nexport interface VariantDiffResult {\n component: string;\n variant: string;\n theme: Theme;\n result: DiffResult;\n diffImagePath?: string;\n}\n\n/**\n * Result of the diff command\n */\nexport interface DiffCommandResult {\n success: boolean;\n total: number;\n passed: number;\n failed: number;\n missing: number;\n results: VariantDiffResult[];\n totalTimeMs: number;\n}\n\n/**\n * Execute the diff command\n */\nexport async function runDiffCommand(\n config: SegmentsConfig,\n configDir: string,\n options: DiffCommandOptions = {}\n): Promise<DiffCommandResult> {\n const startTime = Date.now();\n const results: VariantDiffResult[] = [];\n\n // Initialize storage\n const storage = new StorageManager({\n projectRoot: configDir,\n viewport: config.screenshots?.viewport,\n });\n await storage.initialize();\n\n // Initialize diff engine\n const threshold = options.threshold ?? config.screenshots?.threshold ?? DEFAULTS.diffThreshold;\n const diffEngine = new DiffEngine(threshold);\n\n // Discover segments\n const segmentFiles = await discoverSegmentFiles(config, configDir);\n\n if (segmentFiles.length === 0) {\n console.log(pc.yellow('No segment files found.'));\n return {\n success: true,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Load all segments\n const segments: Array<{ path: string; segment: SegmentDefinition }> = [];\n\n for (const file of segmentFiles) {\n try {\n const segment = await loadSegmentFile(file.absolutePath);\n if (segment) {\n segments.push({ path: file.relativePath, segment });\n }\n } catch {\n // Skip failed loads\n }\n }\n\n // Filter by component if specified\n const filteredSegments = options.component\n ? segments.filter((s) => s.segment.meta.name === options.component)\n : segments;\n\n if (options.component && filteredSegments.length === 0) {\n console.log(pc.yellow(`Component \"${options.component}\" not found.`));\n return {\n success: false,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Build list of variants to diff\n const variantsToDiff: Array<{\n component: string;\n variant: string;\n }> = [];\n\n for (const { segment } of filteredSegments) {\n const variants = options.variant\n ? segment.variants.filter((v) => v.name === options.variant)\n : segment.variants;\n\n for (const variant of variants) {\n variantsToDiff.push({\n component: segment.meta.name,\n variant: variant.name,\n });\n }\n }\n\n if (variantsToDiff.length === 0) {\n console.log(pc.yellow('No variants to compare.'));\n return {\n success: true,\n total: 0,\n passed: 0,\n failed: 0,\n missing: 0,\n results: [],\n totalTimeMs: Date.now() - startTime,\n };\n }\n\n // Determine theme\n const theme: Theme = options.theme ?? DEFAULTS.theme;\n const viewport = config.screenshots?.viewport ?? DEFAULTS.viewport;\n\n console.log(pc.cyan(`\\n${BRAND.name} Diff\\n`));\n console.log(pc.dim(`Comparing against baselines (theme: ${theme}, threshold: ${threshold}%):\\n`));\n\n // Initialize browser pool\n const pool = new BrowserPool({\n viewport,\n });\n\n // Create capture engine\n const viewerPort = DEFAULTS.port;\n const baseUrl = `http://localhost:${viewerPort}`;\n const captureEngine = new CaptureEngine(pool, baseUrl);\n\n let passed = 0;\n let failed = 0;\n let missing = 0;\n\n const captureOptions: CaptureOptions = {\n theme,\n viewport,\n delay: config.screenshots?.delay ?? DEFAULTS.captureDelayMs,\n };\n\n try {\n // Warm up the pool\n await pool.warmup();\n\n // Compare each variant\n for (const { component, variant } of variantsToDiff) {\n // Load baseline\n const baseline = await storage.loadBaseline(component, variant, theme);\n\n if (!baseline) {\n console.log(\n ` ${pc.yellow('?')} ${component}/${variant} ${pc.dim('(no baseline)')}`\n );\n missing++;\n continue;\n }\n\n try {\n // Capture current\n const current = await captureEngine.captureVariant(\n component,\n variant,\n captureOptions\n );\n\n // Quick hash check\n if (diffEngine.areIdentical(current, baseline)) {\n console.log(` ${pc.green('✓')} ${component}/${variant} ${pc.dim('0.0%')}`);\n results.push({\n component,\n variant,\n theme,\n result: {\n matches: true,\n diffPercentage: 0,\n diffPixelCount: 0,\n totalPixels: current.viewport.width * current.viewport.height,\n changedRegions: [],\n diffTimeMs: 0,\n },\n });\n passed++;\n continue;\n }\n\n // Full diff\n const diffResult = diffEngine.compare(current, baseline, { threshold });\n\n if (diffResult.matches) {\n console.log(\n ` ${pc.green('✓')} ${component}/${variant} ${pc.dim(`${diffResult.diffPercentage}%`)}`\n );\n passed++;\n } else {\n // Save diff image\n let diffImagePath: string | undefined;\n if (diffResult.diffImage) {\n diffImagePath = await storage.saveDiff(\n component,\n variant,\n theme,\n diffResult.diffImage\n );\n }\n\n console.log(\n ` ${pc.red('✗')} ${component}/${variant} ${pc.yellow(`${diffResult.diffPercentage}%`)}` +\n (diffImagePath ? pc.dim(` → ${diffImagePath}`) : '')\n );\n failed++;\n\n results.push({\n component,\n variant,\n theme,\n result: diffResult,\n diffImagePath,\n });\n continue;\n }\n\n results.push({\n component,\n variant,\n theme,\n result: diffResult,\n });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.log(` ${pc.red('!')} ${component}/${variant} ${pc.dim(errorMsg)}`);\n failed++;\n }\n }\n } finally {\n // Shutdown browser pool\n await pool.shutdown();\n }\n\n const totalTimeMs = Date.now() - startTime;\n const total = passed + failed + missing;\n\n // Print summary\n console.log();\n if (failed === 0 && missing === 0) {\n console.log(pc.green(`✓ All ${passed} variant(s) match baselines`));\n } else if (failed > 0) {\n console.log(pc.red(`✗ ${failed} variant(s) differ from baselines`));\n }\n\n if (missing > 0) {\n console.log(pc.yellow(` ${missing} variant(s) have no baseline (run \\`${BRAND.cliCommand} screenshot\\`)`));\n }\n\n console.log(pc.dim(` Completed in ${formatMs(totalTimeMs)}\\n`));\n\n // In CI mode, exit with error if any failed\n const success = failed === 0;\n\n return {\n success,\n total,\n passed,\n failed,\n missing,\n results,\n totalTimeMs,\n };\n}\n","/**\n * CLI command: segments analyze\n *\n * Analyzes the design system and generates an HTML report with:\n * - Component inventory\n * - Documentation coverage\n * - Quality insights\n * - Actionable recommendations\n */\n\nimport { existsSync } from \"node:fs\";\nimport { readFile, writeFile, mkdir } from \"node:fs/promises\";\nimport { join, dirname } from \"node:path\";\nimport pc from \"picocolors\";\nimport type { SegmentsConfig, CompiledSegmentsFile } from \"./core/index.js\";\nimport { BRAND, DEFAULTS } from \"./core/index.js\";\nimport {\n analyzeDesignSystem,\n generateHtmlReport,\n getGrade,\n getScoreColor,\n type DesignSystemAnalytics,\n} from \"./service/index.js\";\n\nexport interface AnalyzeOptions {\n /** Output format */\n format?: \"html\" | \"json\" | \"console\";\n /** Output file path (default: segments-report.html) */\n output?: string;\n /** Open report in browser after generation */\n open?: boolean;\n /** CI mode - exit with appropriate code */\n ci?: boolean;\n /** Minimum score to pass in CI mode */\n minScore?: number;\n}\n\nexport interface AnalyzeResult {\n success: boolean;\n analytics: DesignSystemAnalytics;\n outputPath?: string;\n}\n\n/**\n * Run the analyze command\n */\nexport async function runAnalyzeCommand(\n config: SegmentsConfig,\n configDir: string,\n options: AnalyzeOptions = {}\n): Promise<AnalyzeResult> {\n const format = options.format ?? \"html\";\n const minScore = options.minScore ?? 0;\n\n console.log(pc.cyan(`\\n${BRAND.name} Analyzer\\n`));\n\n // Load compiled segments\n const segmentsPath = join(configDir, config.outFile ?? \"segments.json\");\n\n if (!existsSync(segmentsPath)) {\n console.log(pc.red(`✗ No segments.json found. Run \\`${BRAND.cliCommand} build\\` first.\\n`));\n return {\n success: false,\n analytics: createEmptyAnalytics(),\n };\n }\n\n console.log(pc.dim(\"Analyzing design system...\\n\"));\n\n const content = await readFile(segmentsPath, \"utf-8\");\n const data: CompiledSegmentsFile = JSON.parse(content);\n\n // Run analysis\n const analytics = analyzeDesignSystem(data);\n\n // Print summary to console\n printConsoleSummary(analytics);\n\n // Generate output based on format\n let outputPath: string | undefined;\n\n if (format === \"html\" || format === \"json\") {\n outputPath = options.output ?? getDefaultOutputPath(format, configDir);\n\n // Ensure output directory exists\n await mkdir(dirname(outputPath), { recursive: true });\n\n if (format === \"html\") {\n const html = generateHtmlReport(analytics);\n await writeFile(outputPath, html);\n console.log(pc.green(`✓ Report generated: ${outputPath}\\n`));\n } else {\n await writeFile(outputPath, JSON.stringify(analytics, null, 2));\n console.log(pc.green(`✓ JSON report generated: ${outputPath}\\n`));\n }\n\n // Open in browser if requested\n if (options.open && format === \"html\") {\n await openInBrowser(outputPath);\n }\n }\n\n // CI mode - check score\n const passedCi = analytics.summary.overallScore >= minScore;\n\n if (options.ci) {\n if (passedCi) {\n console.log(\n pc.green(`✓ Score ${analytics.summary.overallScore} meets minimum threshold ${minScore}\\n`)\n );\n } else {\n console.log(\n pc.red(\n `✗ Score ${analytics.summary.overallScore} below minimum threshold ${minScore}\\n`\n )\n );\n }\n }\n\n return {\n success: !options.ci || passedCi,\n analytics,\n outputPath,\n };\n}\n\n/**\n * Print a summary to the console\n */\nfunction printConsoleSummary(analytics: DesignSystemAnalytics): void {\n const { summary, coverage, recommendations } = analytics;\n const grade = getGrade(summary.overallScore);\n\n // Score header\n console.log(\n pc.bold(\n `Overall Score: ${colorizeScore(summary.overallScore)} (${grade})\\n`\n )\n );\n\n // Summary stats\n console.log(pc.dim(\"Summary\"));\n console.log(` Components: ${pc.white(summary.totalComponents.toString())}`);\n console.log(` Variants: ${pc.white(summary.totalVariants.toString())}`);\n console.log(` Props: ${pc.white(summary.totalProps.toString())}`);\n console.log(` Categories: ${pc.white(summary.categories.join(\", \"))}`);\n console.log();\n\n // Coverage\n console.log(pc.dim(\"Coverage\"));\n console.log(` Description: ${formatCoverage(coverage.fields.description)}`);\n console.log(` Usage when: ${formatCoverage(coverage.fields.usageWhen)}`);\n console.log(` Usage whenNot:${formatCoverage(coverage.fields.usageWhenNot)}`);\n console.log(` Guidelines: ${formatCoverage(coverage.fields.guidelines)}`);\n console.log(` Relations: ${formatCoverage(coverage.fields.relations)}`);\n console.log();\n\n // Top recommendations\n if (recommendations.length > 0) {\n console.log(pc.dim(\"Top Recommendations\"));\n for (const rec of recommendations.slice(0, 3)) {\n const priority = rec.priority === \"high\"\n ? pc.red(`[${rec.priority}]`)\n : rec.priority === \"medium\"\n ? pc.yellow(`[${rec.priority}]`)\n : pc.dim(`[${rec.priority}]`);\n console.log(` ${priority} ${rec.title}`);\n }\n console.log();\n }\n}\n\n/**\n * Format coverage percentage with color\n */\nfunction formatCoverage(field: { percentage: number; covered: number; total: number }): string {\n const pct = colorizeScore(field.percentage);\n return `${pct} (${field.covered}/${field.total})`;\n}\n\n/**\n * Colorize a score\n */\nfunction colorizeScore(score: number): string {\n if (score >= 80) return pc.green(`${score}%`);\n if (score >= 60) return pc.yellow(`${score}%`);\n return pc.red(`${score}%`);\n}\n\n/**\n * Get default output path\n */\nfunction getDefaultOutputPath(format: \"html\" | \"json\", configDir: string): string {\n const filename = format === \"html\" ? \"segments-report.html\" : \"segments-report.json\";\n return join(configDir, filename);\n}\n\n/**\n * Open file in default browser\n */\nasync function openInBrowser(path: string): Promise<void> {\n const { platform } = await import(\"node:os\");\n const { exec } = await import(\"node:child_process\");\n\n const os = platform();\n const cmd = os === \"darwin\"\n ? `open \"${path}\"`\n : os === \"win32\"\n ? `start \"\" \"${path}\"`\n : `xdg-open \"${path}\"`;\n\n exec(cmd);\n}\n\n/**\n * Create empty analytics for error cases\n */\nfunction createEmptyAnalytics(): DesignSystemAnalytics {\n return {\n analyzedAt: new Date(),\n summary: {\n totalComponents: 0,\n totalVariants: 0,\n totalProps: 0,\n categories: [],\n overallScore: 0,\n },\n inventory: {\n byCategory: {},\n byStatus: {},\n byVariantCount: [],\n byPropCount: [],\n },\n coverage: {\n overall: 0,\n fields: {\n description: { covered: 0, total: 0, percentage: 0 },\n usageWhen: { covered: 0, total: 0, percentage: 0 },\n usageWhenNot: { covered: 0, total: 0, percentage: 0 },\n guidelines: { covered: 0, total: 0, percentage: 0 },\n accessibility: { covered: 0, total: 0, percentage: 0 },\n relations: { covered: 0, total: 0, percentage: 0 },\n propDescriptions: { covered: 0, total: 0, percentage: 0 },\n propConstraints: { covered: 0, total: 0, percentage: 0 },\n },\n incomplete: [],\n },\n quality: {\n missingWhenNot: [],\n isolated: [],\n deprecated: [],\n fewVariants: [],\n undocumentedProps: [],\n unconstrainedProps: [],\n },\n distribution: {\n variantsPerComponent: [],\n propsPerComponent: [],\n componentsPerCategory: [],\n statusDistribution: [],\n tagFrequency: [],\n },\n recommendations: [],\n };\n}\n"],"mappings":"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","names":["pc","pc","existsSync","readFile","writeFile","mkdir","join","pc","pc","join","existsSync","readFile","mkdir","writeFile"]}
|
|
@@ -16,10 +16,11 @@ import {
|
|
|
16
16
|
storyModuleToSegment,
|
|
17
17
|
storyNameFromExport,
|
|
18
18
|
toId
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-G3M3MPQ6.js";
|
|
20
20
|
import {
|
|
21
21
|
BRAND,
|
|
22
22
|
DEFAULTS,
|
|
23
|
+
aiMetadataSchema,
|
|
23
24
|
componentRelationSchema,
|
|
24
25
|
figmaPropMappingSchema,
|
|
25
26
|
propDefinitionSchema,
|
|
@@ -32,10 +33,11 @@ import {
|
|
|
32
33
|
segmentUsageSchema,
|
|
33
34
|
segmentVariantSchema,
|
|
34
35
|
segmentsConfigSchema
|
|
35
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-AW7MWOUH.js";
|
|
36
37
|
export {
|
|
37
38
|
BRAND,
|
|
38
39
|
DEFAULTS,
|
|
40
|
+
aiMetadataSchema,
|
|
39
41
|
analyzeComposition,
|
|
40
42
|
compileRecipe,
|
|
41
43
|
compileSegment,
|
|
@@ -65,4 +67,4 @@ export {
|
|
|
65
67
|
storyNameFromExport,
|
|
66
68
|
toId
|
|
67
69
|
};
|
|
68
|
-
//# sourceMappingURL=core-
|
|
70
|
+
//# sourceMappingURL=core-LNXDLXDP.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
extractPropsFromFile
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-5CKYLCJH.js";
|
|
5
|
+
import "./chunk-G3M3MPQ6.js";
|
|
6
6
|
import {
|
|
7
7
|
BRAND
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AW7MWOUH.js";
|
|
9
9
|
|
|
10
10
|
// src/commands/generate.ts
|
|
11
11
|
import { readFile, writeFile, mkdir, access } from "fs/promises";
|
|
@@ -246,4 +246,4 @@ function inferStatus(filePath) {
|
|
|
246
246
|
export {
|
|
247
247
|
generate
|
|
248
248
|
};
|
|
249
|
-
//# sourceMappingURL=generate-
|
|
249
|
+
//# sourceMappingURL=generate-OIXXHOWR.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -186,6 +186,20 @@ interface SegmentGenerated {
|
|
|
186
186
|
/** ISO timestamp when this was generated */
|
|
187
187
|
timestamp?: string;
|
|
188
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* AI-specific metadata for playground context generation
|
|
191
|
+
* Provides hints for AI code generation about component composition
|
|
192
|
+
*/
|
|
193
|
+
interface AIMetadata {
|
|
194
|
+
/** How this component is composed with others */
|
|
195
|
+
compositionPattern?: "compound" | "simple" | "controlled";
|
|
196
|
+
/** Sub-component names (without parent prefix, e.g., "Header" not "Card.Header") */
|
|
197
|
+
subComponents?: string[];
|
|
198
|
+
/** Sub-components that must be present for valid composition */
|
|
199
|
+
requiredChildren?: string[];
|
|
200
|
+
/** Common usage patterns as JSX strings for AI reference */
|
|
201
|
+
commonPatterns?: string[];
|
|
202
|
+
}
|
|
189
203
|
/**
|
|
190
204
|
* Registry generation options
|
|
191
205
|
*/
|
|
@@ -356,6 +370,8 @@ interface CompiledSegment {
|
|
|
356
370
|
}>;
|
|
357
371
|
/** Agent-optimized contract metadata */
|
|
358
372
|
contract?: SegmentContract;
|
|
373
|
+
/** AI-specific metadata for playground context generation */
|
|
374
|
+
ai?: AIMetadata;
|
|
359
375
|
/** Provenance tracking (for generated segments) */
|
|
360
376
|
_generated?: SegmentGenerated;
|
|
361
377
|
}
|
package/dist/index.js
CHANGED
|
@@ -7,21 +7,21 @@ import {
|
|
|
7
7
|
validateAll,
|
|
8
8
|
validateCoverage,
|
|
9
9
|
validateSchema
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-ZFKGX3QK.js";
|
|
11
|
+
import "./chunk-5ZYEOHYK.js";
|
|
12
12
|
import {
|
|
13
13
|
discoverComponentFiles,
|
|
14
14
|
discoverSegmentFiles,
|
|
15
15
|
extractComponentName,
|
|
16
16
|
findConfigFile,
|
|
17
17
|
loadConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5CKYLCJH.js";
|
|
19
19
|
import {
|
|
20
20
|
generateStaticViewer,
|
|
21
21
|
generateViewerFromJson
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-NOTYONHY.js";
|
|
23
|
+
import "./chunk-G3M3MPQ6.js";
|
|
24
|
+
import "./chunk-AW7MWOUH.js";
|
|
25
25
|
export {
|
|
26
26
|
buildSegments,
|
|
27
27
|
discoverComponentFiles,
|