@usefragments/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-243QYRUF.js +2145 -0
  3. package/dist/chunk-243QYRUF.js.map +1 -0
  4. package/dist/chunk-3LLRNCPX.js +111 -0
  5. package/dist/chunk-3LLRNCPX.js.map +1 -0
  6. package/dist/chunk-EIYNNS77.js +48 -0
  7. package/dist/chunk-EIYNNS77.js.map +1 -0
  8. package/dist/chunk-JNBFJ34I.js +326 -0
  9. package/dist/chunk-JNBFJ34I.js.map +1 -0
  10. package/dist/chunk-R3X7UBHU.js +228 -0
  11. package/dist/chunk-R3X7UBHU.js.map +1 -0
  12. package/dist/chunk-SH4KPIYH.js +393 -0
  13. package/dist/chunk-SH4KPIYH.js.map +1 -0
  14. package/dist/chunk-V4VQB57N.js +56 -0
  15. package/dist/chunk-V4VQB57N.js.map +1 -0
  16. package/dist/chunk-X34IA4LR.js +319 -0
  17. package/dist/chunk-X34IA4LR.js.map +1 -0
  18. package/dist/chunk-YF65VYRY.js +493 -0
  19. package/dist/chunk-YF65VYRY.js.map +1 -0
  20. package/dist/codes/index.d.ts +40 -0
  21. package/dist/codes/index.js +23 -0
  22. package/dist/codes/index.js.map +1 -0
  23. package/dist/compiled-types/index.d.ts +5 -0
  24. package/dist/compiled-types/index.js +1 -0
  25. package/dist/compiled-types/index.js.map +1 -0
  26. package/dist/generate/index.d.ts +47 -0
  27. package/dist/generate/index.js +11 -0
  28. package/dist/generate/index.js.map +1 -0
  29. package/dist/governance-BOa3KyiJ.d.ts +3279 -0
  30. package/dist/graph/index.d.ts +66 -0
  31. package/dist/graph/index.js +17 -0
  32. package/dist/graph/index.js.map +1 -0
  33. package/dist/index.d.ts +11388 -0
  34. package/dist/index.js +8711 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/package-identity.d.ts +42 -0
  37. package/dist/package-identity.js +23 -0
  38. package/dist/package-identity.js.map +1 -0
  39. package/dist/preview/index.d.ts +484 -0
  40. package/dist/preview/index.js +1129 -0
  41. package/dist/preview/index.js.map +1 -0
  42. package/dist/react-types.d.ts +22 -0
  43. package/dist/react-types.js +1 -0
  44. package/dist/react-types.js.map +1 -0
  45. package/dist/registry.d.ts +2367 -0
  46. package/dist/registry.js +62 -0
  47. package/dist/registry.js.map +1 -0
  48. package/dist/schemas/index.d.ts +2584 -0
  49. package/dist/schemas/index.js +55 -0
  50. package/dist/schemas/index.js.map +1 -0
  51. package/dist/severity.d.ts +18 -0
  52. package/dist/severity.js +27 -0
  53. package/dist/severity.js.map +1 -0
  54. package/dist/test-utils.d.ts +14 -0
  55. package/dist/test-utils.js +63 -0
  56. package/dist/test-utils.js.map +1 -0
  57. package/dist/topology/index.d.ts +48 -0
  58. package/dist/topology/index.js +7 -0
  59. package/dist/topology/index.js.map +1 -0
  60. package/dist/types-xJ2xyp_G.d.ts +119 -0
  61. package/package.json +120 -0
  62. package/src/__tests__/contract-parser.test.ts +614 -0
  63. package/src/__tests__/dtcg-generators.test.ts +439 -0
  64. package/src/__tests__/dtcg-parser.test.ts +884 -0
  65. package/src/__tests__/preview-runtime.test.tsx +111 -0
  66. package/src/__tests__/schema.test.ts +31 -0
  67. package/src/__tests__/severity.test.ts +34 -0
  68. package/src/__tests__/style-comparison.test.ts +662 -0
  69. package/src/__tests__/tokens-compat.test.ts +51 -0
  70. package/src/agent-format.test.ts +105 -0
  71. package/src/agent-format.ts +141 -0
  72. package/src/bundle.ts +149 -0
  73. package/src/codes/__tests__/codes.test.ts +73 -0
  74. package/src/codes/codes.ts +463 -0
  75. package/src/codes/index.ts +7 -0
  76. package/src/codes/source-finding-bridge.ts +113 -0
  77. package/src/compiled-types/index.ts +293 -0
  78. package/src/component-contract.ts +231 -0
  79. package/src/component-discovery.ts +80 -0
  80. package/src/composition.test.ts +262 -0
  81. package/src/composition.ts +318 -0
  82. package/src/config-paths.test.ts +78 -0
  83. package/src/config-paths.ts +47 -0
  84. package/src/config.ts +18 -0
  85. package/src/conform-prove.test.ts +274 -0
  86. package/src/conform-prove.ts +326 -0
  87. package/src/conform.ts +160 -0
  88. package/src/constants.ts +114 -0
  89. package/src/context.ts +2 -0
  90. package/src/contract/fixture.ts +110 -0
  91. package/src/contract/hash.test.ts +86 -0
  92. package/src/contract/hash.ts +195 -0
  93. package/src/contract/index.ts +43 -0
  94. package/src/contract/preimage.test.ts +254 -0
  95. package/src/contract/preimage.ts +365 -0
  96. package/src/contract/stamp.test.ts +100 -0
  97. package/src/contract/stamp.ts +105 -0
  98. package/src/contract-parser.ts +141 -0
  99. package/src/defineFragment.test.ts +257 -0
  100. package/src/defineFragment.ts +293 -0
  101. package/src/dtcg-generators.ts +324 -0
  102. package/src/dtcg-parser.ts +1 -0
  103. package/src/dtcg.ts +237 -0
  104. package/src/facts/__snapshots__/facts.test.ts.snap +124 -0
  105. package/src/facts/builders.ts +835 -0
  106. package/src/facts/compile.ts +422 -0
  107. package/src/facts/fact-index.ts +394 -0
  108. package/src/facts/facts.test.ts +494 -0
  109. package/src/facts/ids.ts +125 -0
  110. package/src/facts/index.ts +119 -0
  111. package/src/facts/types.ts +614 -0
  112. package/src/figma.ts +263 -0
  113. package/src/fragment-types.ts +214 -0
  114. package/src/generate/generate.test.ts +594 -0
  115. package/src/generate/index.ts +438 -0
  116. package/src/governance-integrity.test.ts +186 -0
  117. package/src/governance-integrity.ts +282 -0
  118. package/src/governance.test.ts +300 -0
  119. package/src/governance.ts +605 -0
  120. package/src/governance.type-test.ts +75 -0
  121. package/src/graph/engine.ts +446 -0
  122. package/src/graph/graph.test.ts +746 -0
  123. package/src/graph/index.ts +32 -0
  124. package/src/graph/serialization.ts +55 -0
  125. package/src/graph/types.ts +178 -0
  126. package/src/index.ts +891 -0
  127. package/src/local-canonical.ts +102 -0
  128. package/src/mcp-snapshot.ts +222 -0
  129. package/src/package-identity-match.ts +33 -0
  130. package/src/package-identity.generated.ts +233 -0
  131. package/src/package-identity.test.ts +99 -0
  132. package/src/package-identity.ts +157 -0
  133. package/src/performance-presets.ts +142 -0
  134. package/src/preview/comparison-artifact.test.ts +228 -0
  135. package/src/preview/comparison-artifact.ts +181 -0
  136. package/src/preview/comparison-context.ts +93 -0
  137. package/src/preview/comparison-evidence.ts +112 -0
  138. package/src/preview/comparison-format.ts +21 -0
  139. package/src/preview/comparison-presentation.ts +187 -0
  140. package/src/preview/comparison-references.test.ts +430 -0
  141. package/src/preview/comparison-references.ts +72 -0
  142. package/src/preview/comparison-score.ts +59 -0
  143. package/src/preview/comparison-styles.ts +197 -0
  144. package/src/preview/comparison.test.ts +559 -0
  145. package/src/preview/comparison.ts +488 -0
  146. package/src/preview/index.ts +10 -0
  147. package/src/preview/types.ts +309 -0
  148. package/src/preview/validation.test.ts +290 -0
  149. package/src/preview/validation.ts +356 -0
  150. package/src/preview-runtime.tsx +144 -0
  151. package/src/raw-html-canonical.test.ts +41 -0
  152. package/src/raw-html-canonical.ts +179 -0
  153. package/src/react-types.ts +21 -0
  154. package/src/registry-install-plan.ts +344 -0
  155. package/src/registry.test.ts +245 -0
  156. package/src/registry.ts +369 -0
  157. package/src/rules/a11y-required-accessible-name.ts +93 -0
  158. package/src/rules/color-math.test.ts +72 -0
  159. package/src/rules/color-math.ts +192 -0
  160. package/src/rules/components-forbidden-prop-value.ts +108 -0
  161. package/src/rules/components-prefer-library.ts +943 -0
  162. package/src/rules/components-unknown-prop.ts +94 -0
  163. package/src/rules/composition-pattern-schema.ts +125 -0
  164. package/src/rules/composition-pattern.test.ts +320 -0
  165. package/src/rules/composition-pattern.ts +271 -0
  166. package/src/rules/emit-gate.test.ts +42 -0
  167. package/src/rules/emit-gate.ts +60 -0
  168. package/src/rules/finding.ts +54 -0
  169. package/src/rules/index.ts +235 -0
  170. package/src/rules/jsx-preferred-component.ts +68 -0
  171. package/src/rules/jsx-preferred-import-path.ts +67 -0
  172. package/src/rules/presets.ts +57 -0
  173. package/src/rules/props-invalid-value.ts +115 -0
  174. package/src/rules/rules.test.ts +3636 -0
  175. package/src/rules/spacing-resolution.ts +184 -0
  176. package/src/rules/styles-no-raw-color.ts +329 -0
  177. package/src/rules/styles-no-raw-dimensions.ts +357 -0
  178. package/src/rules/styles-no-raw-spacing.ts +236 -0
  179. package/src/rules/styles-no-raw-typography.ts +237 -0
  180. package/src/rules/tailwind-arbitrary-color.test.ts +128 -0
  181. package/src/rules/tailwind-arbitrary-color.ts +93 -0
  182. package/src/rules/tailwind-arbitrary-spacing.test.ts +157 -0
  183. package/src/rules/tailwind-arbitrary-spacing.ts +120 -0
  184. package/src/rules/tailwind-forbidden-palette.test.ts +116 -0
  185. package/src/rules/tailwind-forbidden-palette.ts +107 -0
  186. package/src/rules/tailwind-off-scale-spacing-token.test.ts +100 -0
  187. package/src/rules/tailwind-off-scale-spacing-token.ts +108 -0
  188. package/src/rules/tailwind-raw-color-via-token.test.ts +108 -0
  189. package/src/rules/tailwind-raw-color-via-token.ts +82 -0
  190. package/src/rules/tailwind-rule-utils.ts +106 -0
  191. package/src/rules/tailwind-unknown-class.test.ts +157 -0
  192. package/src/rules/tailwind-unknown-class.ts +121 -0
  193. package/src/rules/taxonomy.test.ts +238 -0
  194. package/src/rules/theme-no-theme-coupled-literal.ts +132 -0
  195. package/src/rules/tiers.ts +111 -0
  196. package/src/rules/tokens-css-vars-must-be-defined.test.ts +244 -0
  197. package/src/rules/tokens-css-vars-must-be-defined.ts +156 -0
  198. package/src/rules/tokens-require-dual-fallback.ts +78 -0
  199. package/src/rules/types.ts +27 -0
  200. package/src/rules/utils.test.ts +110 -0
  201. package/src/rules/utils.ts +599 -0
  202. package/src/schema.ts +427 -0
  203. package/src/schemas/index.ts +275 -0
  204. package/src/schemas/schemas.test.ts +124 -0
  205. package/src/severity.ts +54 -0
  206. package/src/storyAdapter.test.ts +571 -0
  207. package/src/storyAdapter.ts +761 -0
  208. package/src/storyFilters.test.ts +350 -0
  209. package/src/storyFilters.ts +253 -0
  210. package/src/storybook-csf.ts +11 -0
  211. package/src/style-comparison.ts +423 -0
  212. package/src/test-utils.ts +68 -0
  213. package/src/token-parser.ts +2 -0
  214. package/src/token-types.ts +287 -0
  215. package/src/tokens/categories.ts +131 -0
  216. package/src/tokens/color.ts +193 -0
  217. package/src/tokens/design-token-parser.test.ts +159 -0
  218. package/src/tokens/design-token-parser.ts +402 -0
  219. package/src/tokens/dtcg.ts +428 -0
  220. package/src/tokens/index.ts +130 -0
  221. package/src/tokens/lookup.ts +19 -0
  222. package/src/tokens/scss.ts +171 -0
  223. package/src/tokens/tailwind-v4.ts +187 -0
  224. package/src/tokens/types.ts +43 -0
  225. package/src/topology/index.ts +9 -0
  226. package/src/topology/resolve-area.test.ts +174 -0
  227. package/src/topology/resolve-area.ts +215 -0
  228. package/src/types.ts +1057 -0
package/src/types.ts ADDED
@@ -0,0 +1,1057 @@
1
+ import type { ComponentType, ReactNode, JSX } from "react";
2
+ import type { GovernanceConfig } from "./governance.js";
3
+ import type { InspectConfig } from "./local-canonical.js";
4
+ import type { Topology } from "./topology/resolve-area.js";
5
+
6
+ /**
7
+ * A React component that can be used in a fragment definition.
8
+ * This type is intentionally broad to support various React component patterns
9
+ * including FC, forwardRef, memo, and class components across different React versions.
10
+ */
11
+
12
+ export type FragmentComponent<TProps = any> =
13
+ | ComponentType<TProps>
14
+ | ((props: TProps) => ReactNode | JSX.Element | null);
15
+
16
+ /**
17
+ * Framework-agnostic component reference.
18
+ * Used in contexts where React is not required (e.g., JSON component contracts).
19
+ * Accepts a string identifier, a generic function, or a record of metadata.
20
+ */
21
+ export type ComponentRef = string | ((...args: unknown[]) => unknown) | Record<string, unknown>;
22
+
23
+ /**
24
+ * Metadata about the component
25
+ */
26
+ export interface FragmentMeta {
27
+ /** Component display name */
28
+ name: string;
29
+
30
+ /** Brief description of the component's purpose */
31
+ description: string;
32
+
33
+ /** Category for organizing components (e.g., "actions", "forms", "layout") */
34
+ category: string;
35
+
36
+ /** Optional tags for additional categorization */
37
+ tags?: string[];
38
+
39
+ /** Component status */
40
+ status?: "stable" | "beta" | "deprecated" | "experimental";
41
+
42
+ /** Version when component was introduced */
43
+ since?: string;
44
+
45
+ /** External npm packages required by this component (displayed in docs Setup section) */
46
+ dependencies?: Array<{
47
+ name: string;
48
+ version: string;
49
+ reason?: string;
50
+ }>;
51
+
52
+ /** Figma frame URL for design verification */
53
+ figma?: string;
54
+
55
+ /** Figma property mappings (how Figma props map to code props) */
56
+ figmaProps?: Record<string, FigmaPropMapping>;
57
+ }
58
+
59
+ /**
60
+ * Figma property mapping types - describes how a Figma property maps to code
61
+ */
62
+ export type FigmaPropMapping =
63
+ | FigmaStringMapping
64
+ | FigmaBooleanMapping
65
+ | FigmaEnumMapping
66
+ | FigmaInstanceMapping
67
+ | FigmaChildrenMapping
68
+ | FigmaTextContentMapping;
69
+
70
+ /** Maps a Figma text property to a string prop */
71
+ export interface FigmaStringMapping {
72
+ __type: "figma-string";
73
+ figmaProperty: string;
74
+ }
75
+
76
+ /** Maps a Figma boolean property to a boolean prop (with optional value mapping) */
77
+ export interface FigmaBooleanMapping {
78
+ __type: "figma-boolean";
79
+ figmaProperty: string;
80
+ valueMapping?: { true: unknown; false: unknown };
81
+ }
82
+
83
+ /** Maps a Figma variant property to an enum prop */
84
+ export interface FigmaEnumMapping {
85
+ __type: "figma-enum";
86
+ figmaProperty: string;
87
+ valueMapping: Record<string, unknown>;
88
+ }
89
+
90
+ /** References a nested Figma component instance */
91
+ export interface FigmaInstanceMapping {
92
+ __type: "figma-instance";
93
+ figmaProperty: string;
94
+ }
95
+
96
+ /** Renders children from Figma layer names */
97
+ export interface FigmaChildrenMapping {
98
+ __type: "figma-children";
99
+ layers: string[];
100
+ }
101
+
102
+ /** Extracts text content from a Figma text layer */
103
+ export interface FigmaTextContentMapping {
104
+ __type: "figma-text-content";
105
+ layer: string;
106
+ }
107
+
108
+ /**
109
+ * Usage guidelines for AI agents and developers
110
+ */
111
+ export interface FragmentUsage {
112
+ /** When to use this component */
113
+ when: string[];
114
+
115
+ /** When NOT to use this component (with alternatives) */
116
+ whenNot: string[];
117
+
118
+ /** Additional usage guidelines and best practices */
119
+ guidelines?: string[];
120
+
121
+ /** Accessibility considerations */
122
+ accessibility?: string[];
123
+ }
124
+
125
+ /**
126
+ * Prop type definitions
127
+ */
128
+ export type PropType =
129
+ | { type: "string"; pattern?: string }
130
+ | { type: "number"; min?: number; max?: number }
131
+ | { type: "boolean" }
132
+ | { type: "enum"; values: readonly string[] }
133
+ | { type: "function"; signature?: string }
134
+ | { type: "node" }
135
+ | { type: "element" }
136
+ | { type: "object"; shape?: Record<string, PropDefinition> }
137
+ | { type: "array"; items?: PropType }
138
+ | { type: "union"; types: PropType[] }
139
+ | { type: "custom"; typescript: string };
140
+
141
+ /**
142
+ * Storybook control types for UI rendering
143
+ */
144
+ export type ControlType =
145
+ | "text"
146
+ | "number"
147
+ | "range"
148
+ | "boolean"
149
+ | "select"
150
+ | "multi-select"
151
+ | "radio"
152
+ | "inline-radio"
153
+ | "check"
154
+ | "inline-check"
155
+ | "object"
156
+ | "file"
157
+ | "color"
158
+ | "date";
159
+
160
+ /**
161
+ * Definition for a single prop
162
+ */
163
+ export interface PropDefinition {
164
+ /** The prop type */
165
+ type: PropType["type"];
166
+
167
+ /** For enum types, the allowed values */
168
+ values?: readonly string[];
169
+
170
+ /** Default value if not provided */
171
+ default?: unknown;
172
+
173
+ /** Description of what this prop does */
174
+ description: string;
175
+
176
+ /** Whether this prop is required */
177
+ required?: boolean;
178
+
179
+ /** Usage constraints for AI agents */
180
+ constraints?: string[];
181
+
182
+ /** Additional type details for complex types */
183
+ typeDetails?: Omit<PropType, "type">;
184
+
185
+ /** Original Storybook control type for UI rendering (e.g., "color", "date", "range") */
186
+ controlType?: ControlType;
187
+
188
+ /** Control options (e.g., min/max for range, presetColors for color) */
189
+ controlOptions?: {
190
+ min?: number;
191
+ max?: number;
192
+ step?: number;
193
+ presetColors?: string[];
194
+ };
195
+ }
196
+
197
+ /**
198
+ * Relationship types between components
199
+ */
200
+ export type RelationshipType =
201
+ | "alternative" // Use instead of this component in certain cases
202
+ | "sibling" // Related component at same level
203
+ | "parent" // This component should be wrapped by
204
+ | "child" // This component should contain
205
+ | "composition" // Used together as compound component
206
+ | "complementary" // Enhances or works alongside this component
207
+ | "used-by"; // This component is consumed by another
208
+
209
+ /**
210
+ * Relationship to another component
211
+ */
212
+ export interface ComponentRelation {
213
+ /** Name of the related component */
214
+ component: string;
215
+
216
+ /** Type of relationship */
217
+ relationship: RelationshipType;
218
+
219
+ /** Explanation of the relationship */
220
+ note: string;
221
+ }
222
+
223
+ /**
224
+ * Loader function type for async data loading before render
225
+ */
226
+ export type VariantLoader = () => Promise<Record<string, unknown>>;
227
+
228
+ /**
229
+ * Play function context passed during interaction testing
230
+ */
231
+ export interface PlayFunctionContext {
232
+ /** The rendered canvas element containing the story */
233
+ canvasElement: HTMLElement;
234
+ /** Args passed to the story */
235
+ args: Record<string, unknown>;
236
+ /** Step function for organizing interactions */
237
+ step: (name: string, fn: () => Promise<void>) => Promise<void>;
238
+ }
239
+
240
+ /**
241
+ * Play function type for interaction testing
242
+ */
243
+ export type PlayFunction = (context: PlayFunctionContext) => Promise<void>;
244
+
245
+ /**
246
+ * Options passed to variant render function
247
+ */
248
+ export interface VariantRenderOptions {
249
+ /** Props/args to override the variant defaults */
250
+ args?: Record<string, unknown>;
251
+ /** Data loaded from async loaders */
252
+ loadedData?: Record<string, unknown>;
253
+ }
254
+
255
+ /**
256
+ * A single variant/example of the component
257
+ */
258
+ export interface FragmentVariant {
259
+ /** Variant name */
260
+ name: string;
261
+
262
+ /** Description of when to use this variant */
263
+ description: string;
264
+
265
+ /** Render function that returns the component example
266
+ * @param options - Optional args overrides and loaded data
267
+ */
268
+ render: (options?: VariantRenderOptions) => ReactNode;
269
+
270
+ /** Optional code string for display (auto-generated if not provided) */
271
+ code?: string;
272
+
273
+ /** Figma frame URL for this specific variant (overrides meta.figma) */
274
+ figma?: string;
275
+
276
+ /** Whether this variant has a Storybook play function (for display purposes) */
277
+ hasPlayFunction?: boolean;
278
+
279
+ /** The actual play function for interaction testing */
280
+ play?: PlayFunction;
281
+
282
+ /** Storybook story ID for this variant (generated by @storybook/csf toId) */
283
+ storyId?: string;
284
+
285
+ /** Optional tags for this variant (inherited from story tags) */
286
+ tags?: string[];
287
+
288
+ /** Async loaders to execute before rendering (from Storybook loaders) */
289
+ loaders?: VariantLoader[];
290
+
291
+ /** The args/props used to render this variant (for code generation) */
292
+ args?: Record<string, unknown>;
293
+ }
294
+
295
+ /**
296
+ * Agent-optimized contract metadata
297
+ * Provides compact, structured data for AI code generation
298
+ */
299
+ export interface FragmentContract {
300
+ /** Short prop descriptions for agents (e.g., "variant: primary|secondary (required)") */
301
+ propsSummary?: string[];
302
+
303
+ /** Accessibility rule IDs for lookup in glossary (e.g., "A11Y_BTN_LABEL") */
304
+ a11yRules?: string[];
305
+
306
+ /** Banned patterns in codebase - triggers warnings during code review */
307
+ bans?: Array<{
308
+ /** Pattern to match (regex string or literal) */
309
+ pattern: string;
310
+ /** Message explaining why this pattern is banned and what to use instead */
311
+ message: string;
312
+ }>;
313
+
314
+ /** Scenario tags for use-case matching (e.g., "form.submit", "navigation.primary") */
315
+ scenarioTags?: string[];
316
+
317
+ /** Per-component performance budget override in bytes (gzipped). Overrides global budget. */
318
+ performanceBudget?: number;
319
+
320
+ /** Sub-component slot metadata for compound components (e.g., Card.Header, Dialog.Body) */
321
+ compoundChildren?: Record<
322
+ string,
323
+ {
324
+ required?: boolean;
325
+ accepts?: string[];
326
+ description?: string;
327
+ }
328
+ >;
329
+
330
+ /** Canonical JSX usage examples showing how to assemble the component */
331
+ canonicalUsage?: string[];
332
+ }
333
+
334
+ /**
335
+ * Provenance tracking for generated fragments
336
+ * Helps distinguish human-authored from machine-generated content
337
+ */
338
+ export interface FragmentGenerated {
339
+ /** Source of this fragment definition */
340
+ source: "storybook" | "manual" | "ai" | "extracted" | "merged" | "migrated";
341
+
342
+ /** Original source file (e.g., "Button.stories.tsx") */
343
+ sourceFile?: string;
344
+
345
+ /** @deprecated Use provenance.verified instead — kept for backwards compatibility */
346
+ confidence?: number;
347
+
348
+ /** Whether the fragment has been verified against source */
349
+ verified?: boolean;
350
+
351
+ /** ISO timestamp when this was generated */
352
+ timestamp?: string;
353
+ }
354
+
355
+ /**
356
+ * AI-specific metadata for playground context generation
357
+ * Provides hints for AI code generation about component composition
358
+ */
359
+ export interface AIMetadata {
360
+ /** How this component is composed with others */
361
+ compositionPattern?: "compound" | "simple" | "controlled" | "wrapper";
362
+
363
+ /** Sub-component names (without parent prefix, e.g., "Header" not "Card.Header") */
364
+ subComponents?: string[];
365
+
366
+ /** Sub-components that must be present for valid composition */
367
+ requiredChildren?: string[];
368
+
369
+ /** Common usage patterns as JSX strings for AI reference */
370
+ commonPatterns?: string[];
371
+ }
372
+
373
+ /**
374
+ * Complete fragment definition
375
+ */
376
+ export interface FragmentDefinition<TProps = unknown> {
377
+ /** The component being documented */
378
+ component: FragmentComponent<TProps>;
379
+
380
+ /** Component metadata */
381
+ meta: FragmentMeta;
382
+
383
+ /** Usage guidelines */
384
+ usage: FragmentUsage;
385
+
386
+ /** Props documentation */
387
+ props: Record<string, PropDefinition>;
388
+
389
+ /** Relationships to other components */
390
+ relations?: ComponentRelation[];
391
+
392
+ /** Component variants/examples */
393
+ variants: FragmentVariant[];
394
+
395
+ /** Agent-optimized contract metadata */
396
+ contract?: FragmentContract;
397
+
398
+ /** AI-specific metadata for playground context generation */
399
+ ai?: AIMetadata;
400
+
401
+ /** Provenance tracking (for generated fragments) */
402
+ _generated?: FragmentGenerated;
403
+ }
404
+
405
+ // ---------------------------------------------------------------------------
406
+ // v2 API — Clearer naming, alongside v1 (non-breaking)
407
+ // ---------------------------------------------------------------------------
408
+
409
+ /**
410
+ * Usage guidelines for AI agents and developers.
411
+ * v2 alias for FragmentUsage — clearer naming.
412
+ * @since 2.0
413
+ */
414
+ export type FragmentGuidance = FragmentUsage;
415
+
416
+ /**
417
+ * A single example of the component.
418
+ * v2 alias for FragmentVariant — research shows "examples" is clearer for AI consumption.
419
+ * @since 2.0
420
+ */
421
+ export type FragmentExample = FragmentVariant;
422
+
423
+ /**
424
+ * Composition metadata — promoted from ai.compositionPattern to first-class field.
425
+ * Uses shorter field names since the parent field is already `composition`.
426
+ * @since 2.0
427
+ */
428
+ export interface CompositionMetadata {
429
+ /** How this component is composed with others */
430
+ pattern?: "compound" | "simple" | "controlled" | "wrapper";
431
+
432
+ /** Sub-component names (without parent prefix, e.g., "Header" not "Card.Header") */
433
+ subComponents?: string[];
434
+
435
+ /** Sub-components that must be present for valid composition */
436
+ requiredChildren?: string[];
437
+
438
+ /** Common usage patterns as JSX strings for AI reference */
439
+ commonPatterns?: string[];
440
+ }
441
+
442
+ /**
443
+ * Extended provenance tracking for generated fragments.
444
+ * Superset of FragmentGenerated with field-level attribution.
445
+ * @since 2.0
446
+ */
447
+ export interface FragmentProvenance {
448
+ /** Source of this fragment definition */
449
+ source: "storybook" | "manual" | "ai" | "scan" | "extracted" | "merged" | "migrated";
450
+
451
+ /** Original source file (e.g., "Button.stories.tsx") */
452
+ sourceFile?: string;
453
+
454
+ /** @deprecated Use verified instead */
455
+ confidence?: number;
456
+
457
+ /** Whether the fragment has been verified against source */
458
+ verified: boolean;
459
+
460
+ /** Framework support level */
461
+ frameworkSupport?: "native" | "manual-only";
462
+
463
+ /** SHA hash of the source file at extraction time */
464
+ sourceHash?: string;
465
+
466
+ /** ISO timestamp when this was generated */
467
+ timestamp?: string;
468
+
469
+ /** Fields that were auto-extracted (e.g., ['props', 'composition']) */
470
+ autoFields?: string[];
471
+
472
+ /** Fields that were human-authored (e.g., ['guidance', 'examples']) */
473
+ humanFields?: string[];
474
+ }
475
+
476
+ /**
477
+ * v2 fragment definition with clearer field names.
478
+ *
479
+ * Changes from v1 FragmentDefinition:
480
+ * - `usage` → `guidance` (clearer intent)
481
+ * - `variants` → `examples` (research-backed: examples > parameter lists)
482
+ * - `ai` → `composition` (promoted to first-class, shorter field names)
483
+ * - `_generated` → `_provenance` (extended with autoFields/humanFields)
484
+ * - `contract` remains but is auto-compiled at build time
485
+ *
486
+ * @since 2.0
487
+ */
488
+ export interface FragmentDefinitionV2<TProps = unknown> {
489
+ /** The component being documented */
490
+ component: FragmentComponent<TProps>;
491
+
492
+ /** Component metadata */
493
+ meta: FragmentMeta;
494
+
495
+ /** Usage guidelines (v2 name for 'usage') */
496
+ guidance: FragmentGuidance;
497
+
498
+ /** Props documentation */
499
+ props: Record<string, PropDefinition>;
500
+
501
+ /** Relationships to other components */
502
+ relations?: ComponentRelation[];
503
+
504
+ /** Component examples (v2 name for 'variants') */
505
+ examples: FragmentExample[];
506
+
507
+ /** Composition metadata (v2 name for 'ai', promoted to first-class) */
508
+ composition?: CompositionMetadata;
509
+
510
+ /** Agent-optimized contract — auto-compiled at build time */
511
+ contract?: FragmentContract;
512
+
513
+ /** Provenance tracking (v2 name for '_generated', extended) */
514
+ _provenance?: FragmentProvenance;
515
+ }
516
+
517
+ /**
518
+ * Registry generation options
519
+ */
520
+ export interface RegistryOptions {
521
+ /** Only include components that have a corresponding .stories.tsx file */
522
+ requireStory?: boolean;
523
+
524
+ /** Only include components that are exported (public API) */
525
+ publicOnly?: boolean;
526
+
527
+ /** Maximum depth for category inference from directory structure (default: 1) */
528
+ categoryDepth?: number;
529
+
530
+ /** Include props in registry (default: false - AI can read TypeScript directly) */
531
+ includeProps?: boolean;
532
+
533
+ /** Include full fragment data in registry (default: false - reference fragmentPath instead) */
534
+ embedFragments?: boolean;
535
+ }
536
+
537
+ /**
538
+ * Design token configuration
539
+ */
540
+ export type RepoRelativePath = string;
541
+
542
+ export interface AppConfig {
543
+ /** Repo-root-relative app/source directory to scan. Defaults to ".". */
544
+ path?: RepoRelativePath;
545
+
546
+ /** Optional source globs relative to app.path. */
547
+ include?: string[];
548
+
549
+ /** Optional source exclusions relative to app.path. */
550
+ exclude?: string[];
551
+ }
552
+
553
+ export interface DesignSystemConfig {
554
+ /** Repo-root-relative directory that owns the canonical primitives. */
555
+ path?: RepoRelativePath;
556
+
557
+ /** Package name for primitive imports. Inferred from path/package.json when omitted. */
558
+ packageName?: string;
559
+
560
+ /** Component source globs relative to designSystem.path. */
561
+ components?: string[];
562
+ }
563
+
564
+ export type TokenSourceFormat = "auto" | "css" | "scss" | "dtcg" | "tailwind";
565
+
566
+ export interface TokenSourceConfig {
567
+ /** Repo-root-relative token file or glob. */
568
+ path: RepoRelativePath;
569
+
570
+ /** Explicit token format, or "auto" to infer from extension/content. */
571
+ format?: TokenSourceFormat;
572
+ }
573
+
574
+ export interface TokenConfig {
575
+ /**
576
+ * Glob patterns for files to scan for tokens
577
+ * e.g., ["src/styles/theme.scss", "src/styles/variables.css"]
578
+ */
579
+ include?: string[];
580
+
581
+ /** Repo-root-relative token source files/globs for monorepos and Cloud setup. */
582
+ sources?: TokenSourceConfig[];
583
+
584
+ /**
585
+ * Glob patterns to exclude
586
+ * @example ["node_modules"]
587
+ */
588
+ exclude?: string[];
589
+
590
+ /**
591
+ * Map CSS selectors to theme names
592
+ * @example { ":root": "default", "[data-theme='dark']": "dark" }
593
+ */
594
+ themeSelectors?: Record<string, string>;
595
+
596
+ /** Enable token comparison in style diffs (default: true) */
597
+ enabled?: boolean;
598
+
599
+ /** Token source format detection ('auto' detects from file extension) */
600
+ format?: TokenSourceFormat;
601
+
602
+ /** Vendor namespace for Fragments extensions in DTCG files (default: 'com.usefragments') */
603
+ namespace?: string;
604
+ }
605
+
606
+ /**
607
+ * CI configuration for automated compliance checks
608
+ */
609
+ export interface CIConfig {
610
+ /** Minimum compliance percentage to pass (default: 80) */
611
+ minCompliance?: number;
612
+
613
+ /** Whether to fail on any visual regression */
614
+ failOnDiff?: boolean;
615
+
616
+ /** Whether to output JSON format */
617
+ jsonOutput?: boolean;
618
+ }
619
+
620
+ /**
621
+ * Snippet policy configuration.
622
+ * Controls snippet/render quality enforcement in `fragments validate`.
623
+ */
624
+ export interface SnippetPolicyConfig {
625
+ /** Validation mode: warn (non-blocking) or error (blocking). Default: warn */
626
+ mode?: "warn" | "error";
627
+
628
+ /** Validate snippet strings only, or snippet strings + render functions. Default: snippet+render */
629
+ scope?: "snippet" | "snippet+render";
630
+
631
+ /** Require authored snippets to be full, copy-pasteable examples with imports. Default: true */
632
+ requireFullSnippet?: boolean;
633
+
634
+ /** Allow these external modules for JSX components in snippets/renders. */
635
+ allowedExternalModules?: string[];
636
+ }
637
+
638
+ /**
639
+ * Storybook adapter filtering configuration.
640
+ * Controls which Storybook stories are included when generating fragments.
641
+ */
642
+ export interface StorybookFilterConfig {
643
+ /** Glob-style patterns for component names to explicitly exclude */
644
+ exclude?: string[];
645
+ /** Glob-style patterns for component names to force-include (bypasses all heuristic filters) */
646
+ include?: string[];
647
+ /** Exclude stories with "Deprecated" in the title (default: true) */
648
+ excludeDeprecated?: boolean;
649
+ /** Exclude test stories (title ending /test(s) or *.test.stories.* files) (default: true) */
650
+ excludeTests?: boolean;
651
+ /** Exclude SVG icon components (names matching Svg[A-Z]*) (default: true) */
652
+ excludeSvgIcons?: boolean;
653
+ /** Exclude sub-components detected by directory structure (default: true) */
654
+ excludeSubComponents?: boolean;
655
+ }
656
+
657
+ /**
658
+ * Theme seed configuration.
659
+ * The 5 root values that derive 120+ CSS custom properties.
660
+ */
661
+ export interface ThemeSeeds {
662
+ /** Primary brand color as hex (e.g., "#6366f1") */
663
+ brand?: string;
664
+
665
+ /** Neutral palette name */
666
+ neutral?: "stone" | "ice" | "earth" | "sand" | "fire" | "fragments";
667
+
668
+ /** Spacing density scale */
669
+ density?: "compact" | "default" | "relaxed";
670
+
671
+ /** Border radius style */
672
+ radiusStyle?: "sharp" | "subtle" | "default" | "rounded" | "pill";
673
+
674
+ /** Danger/error color as hex (e.g., "#ef4444") */
675
+ danger?: string;
676
+ }
677
+
678
+ /**
679
+ * Visual snapshot testing configuration.
680
+ */
681
+ export interface SnapshotConfig {
682
+ /** Enable visual snapshot tests (default: false) */
683
+ enabled: boolean;
684
+
685
+ /** Output directory for snapshot baselines (relative to project root) */
686
+ outputDir?: string;
687
+
688
+ /** Viewport width for snapshots (default: 1440) */
689
+ viewportWidth?: number;
690
+
691
+ /** Viewport height for snapshots (default: 1100) */
692
+ viewportHeight?: number;
693
+
694
+ /** Diff threshold percentage before a snapshot fails (default: 0.1) */
695
+ threshold?: number;
696
+
697
+ /** Disable CSS animations during capture (default: true) */
698
+ disableAnimations?: boolean;
699
+ }
700
+
701
+ /**
702
+ * Config file structure
703
+ */
704
+ export interface FragmentsConfig {
705
+ /** App/source scan scope. Paths are repo-root-relative. */
706
+ app?: AppConfig;
707
+
708
+ /** Canonical primitive component source. Paths are repo-root-relative. */
709
+ designSystem?: DesignSystemConfig;
710
+
711
+ /** Glob patterns for finding fragment/fragment files */
712
+ include?: string[];
713
+
714
+ /** Glob patterns to exclude */
715
+ exclude?: string[];
716
+
717
+ /** Glob patterns for finding component files (for coverage validation) */
718
+ components?: string[];
719
+
720
+ /** Output path for compiled output */
721
+ outFile?: string;
722
+
723
+ /** Framework adapter to use */
724
+ framework?: "react" | "vue" | "svelte";
725
+
726
+ /** Figma file URL for the design system (used by `fragments link`) */
727
+ figmaFile?: string;
728
+
729
+ /** Figma access token (alternative to FIGMA_ACCESS_TOKEN env var) */
730
+ figmaToken?: string;
731
+
732
+ /** Screenshot configuration */
733
+ screenshots?: ScreenshotConfig;
734
+
735
+ /** Service configuration */
736
+ service?: ServiceConfig;
737
+
738
+ /** Registry generation options */
739
+ registry?: RegistryOptions;
740
+
741
+ /** Design token discovery and mapping configuration */
742
+ tokens?: TokenConfig;
743
+
744
+ /** CI pipeline configuration */
745
+ ci?: CIConfig;
746
+
747
+ /** Snippet/render policy validation */
748
+ snippets?: SnippetPolicyConfig;
749
+
750
+ /** Performance budgets: preset name or custom config */
751
+ performance?: string | { preset?: string; budgets?: { bundleSize?: number } };
752
+
753
+ /** Storybook adapter filtering configuration */
754
+ storybook?: StorybookFilterConfig;
755
+
756
+ /** Theme seed values for the 5-seed theming system */
757
+ theme?: ThemeSeeds;
758
+
759
+ /**
760
+ * Product-area topology — maps file paths to areas (checkout, dashboard, …)
761
+ * for area-scoped governance. Resolved at scan time; areas are tagged onto
762
+ * findings and coverage. See `apps/cloud/docs/topology/`.
763
+ */
764
+ topology?: Topology;
765
+
766
+ /** Visual snapshot testing configuration */
767
+ snapshots?: SnapshotConfig;
768
+
769
+ /** Preview configuration for component rendering */
770
+ preview?: {
771
+ /** Module that runs before any render (global CSS, MSW, mocks) */
772
+ setupModule?: string;
773
+ /** Module path for the render wrapper component (ThemeProvider, etc.) */
774
+ wrapperModule?: string;
775
+ /** Named export from wrapperModule (e.g., 'ThemeProvider') */
776
+ wrapperExport?: string;
777
+ /** Additional CSS files to inject */
778
+ css?: string[];
779
+ /** Default theme for previews */
780
+ theme?: "light" | "dark";
781
+ };
782
+
783
+ /** Governance policy configuration (replaces standalone govern.config.ts) */
784
+ govern?: GovernanceConfig;
785
+
786
+ /** Local Inspect-only configuration. */
787
+ inspect?: InspectConfig;
788
+
789
+ /**
790
+ * Identifier names recognized as className-helper callees during Tailwind
791
+ * extraction (e.g. `clsx`, `cn`). Supplying this list **replaces** the
792
+ * default `['clsx', 'cn', 'classnames', 'twMerge', 'tw', 'cva']` — it does
793
+ * not merge.
794
+ */
795
+ recognizedClassHelpers?: string[];
796
+ }
797
+
798
+ /**
799
+ * Screenshot capture configuration
800
+ */
801
+ export interface ScreenshotConfig {
802
+ /** Default viewport for captures */
803
+ viewport?: Viewport;
804
+
805
+ /** Diff threshold percentage (0-100) */
806
+ threshold?: number;
807
+
808
+ /** Additional delay after render before capture (ms) */
809
+ delay?: number;
810
+
811
+ /** Output directory for baselines (relative to project root) */
812
+ outputDir?: string;
813
+
814
+ /** Themes to capture */
815
+ themes?: Theme[];
816
+ }
817
+
818
+ /**
819
+ * Service configuration
820
+ */
821
+ export interface ServiceConfig {
822
+ /** Browser pool size */
823
+ poolSize?: number;
824
+
825
+ /** Idle timeout before shutdown (ms) */
826
+ idleTimeout?: number;
827
+ }
828
+
829
+ /**
830
+ * Viewport dimensions
831
+ */
832
+ export interface Viewport {
833
+ width: number;
834
+ height: number;
835
+ deviceScaleFactor?: number;
836
+ }
837
+
838
+ /**
839
+ * Theme identifier
840
+ */
841
+ export type Theme = "light" | "dark";
842
+
843
+ /**
844
+ * Screenshot metadata
845
+ */
846
+ export interface Screenshot {
847
+ /** PNG image data */
848
+ data: Buffer;
849
+
850
+ /** SHA-256 hash of image data (for change detection) */
851
+ hash: string;
852
+
853
+ /** Viewport used for capture */
854
+ viewport: Viewport;
855
+
856
+ /** When this screenshot was taken */
857
+ capturedAt: Date;
858
+
859
+ /** Capture metadata */
860
+ metadata: ScreenshotMetadata;
861
+ }
862
+
863
+ /**
864
+ * Screenshot metadata
865
+ */
866
+ export interface ScreenshotMetadata {
867
+ /** Component name */
868
+ component: string;
869
+
870
+ /** Variant name */
871
+ variant: string;
872
+
873
+ /** Theme used */
874
+ theme: Theme;
875
+
876
+ /** Time to render the component (ms) */
877
+ renderTimeMs: number;
878
+
879
+ /** Time to capture the screenshot (ms) */
880
+ captureTimeMs: number;
881
+ }
882
+
883
+ /**
884
+ * Result of comparing two screenshots
885
+ */
886
+ export interface DiffResult {
887
+ /** Whether images are considered matching (below threshold) */
888
+ matches: boolean;
889
+
890
+ /** Percentage of pixels that differ (0-100) */
891
+ diffPercentage: number;
892
+
893
+ /** Number of differing pixels */
894
+ diffPixelCount: number;
895
+
896
+ /** Total pixels compared */
897
+ totalPixels: number;
898
+
899
+ /** PNG image highlighting differences */
900
+ diffImage?: Buffer;
901
+
902
+ /** Bounding boxes of changed regions */
903
+ changedRegions: BoundingBox[];
904
+
905
+ /** Time taken to compute diff (ms) */
906
+ diffTimeMs: number;
907
+ }
908
+
909
+ /**
910
+ * Bounding box for changed region
911
+ */
912
+ export interface BoundingBox {
913
+ x: number;
914
+ y: number;
915
+ width: number;
916
+ height: number;
917
+ }
918
+
919
+ /**
920
+ * Baseline information stored in manifest
921
+ */
922
+ export interface BaselineInfo {
923
+ /** Component name */
924
+ component: string;
925
+
926
+ /** Variant name */
927
+ variant: string;
928
+
929
+ /** Theme */
930
+ theme: Theme;
931
+
932
+ /** Relative path to image file */
933
+ path: string;
934
+
935
+ /** SHA-256 hash */
936
+ hash: string;
937
+
938
+ /** Viewport used */
939
+ viewport: Viewport;
940
+
941
+ /** When captured */
942
+ capturedAt: string;
943
+
944
+ /** File size in bytes */
945
+ fileSize: number;
946
+ }
947
+
948
+ /**
949
+ * Manifest file structure
950
+ */
951
+ export interface Manifest {
952
+ /** Schema version */
953
+ version: "1.0.0";
954
+
955
+ /** When manifest was generated */
956
+ generatedAt: string;
957
+
958
+ /** Configuration used for capture */
959
+ config: {
960
+ defaultViewport: Viewport;
961
+ defaultThreshold: number;
962
+ captureDelay: number;
963
+ };
964
+
965
+ /** All baselines indexed by component/variant */
966
+ baselines: Record<string, Record<string, BaselineInfo>>;
967
+ }
968
+
969
+ /**
970
+ * Verification request from AI agents
971
+ */
972
+ export interface VerifyRequest {
973
+ /** Component name */
974
+ component: string;
975
+
976
+ /** Variant name */
977
+ variant: string;
978
+
979
+ /** Theme to verify against */
980
+ theme?: Theme;
981
+
982
+ /** Override diff threshold */
983
+ threshold?: number;
984
+ }
985
+
986
+ /**
987
+ * Verification result
988
+ */
989
+ export interface VerifyResult {
990
+ /** Overall verdict */
991
+ verdict: "pass" | "fail" | "error";
992
+
993
+ /** Whether diff is below threshold */
994
+ matches: boolean;
995
+
996
+ /** Percentage of pixels that differ */
997
+ diffPercentage: number;
998
+
999
+ /** Current screenshot (base64 PNG) */
1000
+ screenshot: string;
1001
+
1002
+ /** Baseline screenshot (base64 PNG) */
1003
+ baseline: string;
1004
+
1005
+ /** Diff image if different (base64 PNG) */
1006
+ diffImage?: string;
1007
+
1008
+ /** Human-readable notes */
1009
+ notes: string[];
1010
+
1011
+ /** Error message if verdict is "error" */
1012
+ error?: string;
1013
+
1014
+ /** Performance metrics */
1015
+ timing: {
1016
+ renderMs: number;
1017
+ captureMs: number;
1018
+ diffMs: number;
1019
+ totalMs: number;
1020
+ };
1021
+ }
1022
+
1023
+ // Compiled types — re-exported from ./compiled-types.
1024
+ export type {
1025
+ CompiledFragment,
1026
+ CompiledBlock,
1027
+ CompiledTokenEntry,
1028
+ CompiledTokenData,
1029
+ ObservedComponentUsage,
1030
+ ObservedUsageProp,
1031
+ CompiledFragmentsFile,
1032
+ } from "./compiled-types/index.js";
1033
+
1034
+ import type { CompiledBlock as _CompiledBlock } from "./compiled-types/index.js";
1035
+
1036
+ /**
1037
+ * Block definition — a named composition pattern showing how
1038
+ * design system components wire together for a common use case.
1039
+ */
1040
+ export interface BlockDefinition {
1041
+ name: string;
1042
+ description: string;
1043
+ category: string;
1044
+ components: string[];
1045
+ code: string;
1046
+ tags?: string[];
1047
+ }
1048
+
1049
+ /**
1050
+ * @deprecated Use BlockDefinition instead
1051
+ */
1052
+ export type RecipeDefinition = BlockDefinition;
1053
+
1054
+ /**
1055
+ * @deprecated Use CompiledBlock instead
1056
+ */
1057
+ export type CompiledRecipe = _CompiledBlock;