canicode 0.3.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.
@@ -0,0 +1,1104 @@
1
+ import { z } from 'zod';
2
+ import { GetFileResponse } from '@figma/rest-api-spec';
3
+
4
+ declare const SeveritySchema: z.ZodEnum<{
5
+ blocking: "blocking";
6
+ risk: "risk";
7
+ "missing-info": "missing-info";
8
+ suggestion: "suggestion";
9
+ }>;
10
+ type Severity = z.infer<typeof SeveritySchema>;
11
+ declare const SEVERITY_WEIGHT: Record<Severity, number>;
12
+ declare const SEVERITY_LABELS: Record<Severity, string>;
13
+
14
+ declare const CategorySchema: z.ZodEnum<{
15
+ layout: "layout";
16
+ token: "token";
17
+ component: "component";
18
+ naming: "naming";
19
+ "ai-readability": "ai-readability";
20
+ "handoff-risk": "handoff-risk";
21
+ }>;
22
+ type Category = z.infer<typeof CategorySchema>;
23
+ declare const CATEGORIES: ("layout" | "token" | "component" | "naming" | "ai-readability" | "handoff-risk")[];
24
+ declare const CATEGORY_LABELS: Record<Category, string>;
25
+
26
+ /**
27
+ * Figma node types required for analysis
28
+ * See @figma/rest-api-spec for full API types
29
+ */
30
+ declare const AnalysisNodeTypeSchema: z.ZodEnum<{
31
+ DOCUMENT: "DOCUMENT";
32
+ CANVAS: "CANVAS";
33
+ FRAME: "FRAME";
34
+ GROUP: "GROUP";
35
+ SECTION: "SECTION";
36
+ COMPONENT: "COMPONENT";
37
+ COMPONENT_SET: "COMPONENT_SET";
38
+ INSTANCE: "INSTANCE";
39
+ RECTANGLE: "RECTANGLE";
40
+ ELLIPSE: "ELLIPSE";
41
+ VECTOR: "VECTOR";
42
+ TEXT: "TEXT";
43
+ LINE: "LINE";
44
+ BOOLEAN_OPERATION: "BOOLEAN_OPERATION";
45
+ STAR: "STAR";
46
+ REGULAR_POLYGON: "REGULAR_POLYGON";
47
+ SLICE: "SLICE";
48
+ STICKY: "STICKY";
49
+ SHAPE_WITH_TEXT: "SHAPE_WITH_TEXT";
50
+ CONNECTOR: "CONNECTOR";
51
+ WIDGET: "WIDGET";
52
+ EMBED: "EMBED";
53
+ LINK_UNFURL: "LINK_UNFURL";
54
+ TABLE: "TABLE";
55
+ TABLE_CELL: "TABLE_CELL";
56
+ }>;
57
+ type AnalysisNodeType = z.infer<typeof AnalysisNodeTypeSchema>;
58
+ declare const LayoutModeSchema: z.ZodEnum<{
59
+ NONE: "NONE";
60
+ HORIZONTAL: "HORIZONTAL";
61
+ VERTICAL: "VERTICAL";
62
+ }>;
63
+ type LayoutMode = z.infer<typeof LayoutModeSchema>;
64
+ declare const LayoutAlignSchema: z.ZodEnum<{
65
+ MIN: "MIN";
66
+ CENTER: "CENTER";
67
+ MAX: "MAX";
68
+ STRETCH: "STRETCH";
69
+ INHERIT: "INHERIT";
70
+ }>;
71
+ type LayoutAlign = z.infer<typeof LayoutAlignSchema>;
72
+ declare const LayoutPositioningSchema: z.ZodEnum<{
73
+ AUTO: "AUTO";
74
+ ABSOLUTE: "ABSOLUTE";
75
+ }>;
76
+ type LayoutPositioning = z.infer<typeof LayoutPositioningSchema>;
77
+ /**
78
+ * Lightweight FigmaNode type for analysis
79
+ * Contains only properties needed by rules
80
+ */
81
+ declare const BaseAnalysisNodeSchema: z.ZodObject<{
82
+ id: z.ZodString;
83
+ name: z.ZodString;
84
+ type: z.ZodEnum<{
85
+ DOCUMENT: "DOCUMENT";
86
+ CANVAS: "CANVAS";
87
+ FRAME: "FRAME";
88
+ GROUP: "GROUP";
89
+ SECTION: "SECTION";
90
+ COMPONENT: "COMPONENT";
91
+ COMPONENT_SET: "COMPONENT_SET";
92
+ INSTANCE: "INSTANCE";
93
+ RECTANGLE: "RECTANGLE";
94
+ ELLIPSE: "ELLIPSE";
95
+ VECTOR: "VECTOR";
96
+ TEXT: "TEXT";
97
+ LINE: "LINE";
98
+ BOOLEAN_OPERATION: "BOOLEAN_OPERATION";
99
+ STAR: "STAR";
100
+ REGULAR_POLYGON: "REGULAR_POLYGON";
101
+ SLICE: "SLICE";
102
+ STICKY: "STICKY";
103
+ SHAPE_WITH_TEXT: "SHAPE_WITH_TEXT";
104
+ CONNECTOR: "CONNECTOR";
105
+ WIDGET: "WIDGET";
106
+ EMBED: "EMBED";
107
+ LINK_UNFURL: "LINK_UNFURL";
108
+ TABLE: "TABLE";
109
+ TABLE_CELL: "TABLE_CELL";
110
+ }>;
111
+ visible: z.ZodDefault<z.ZodBoolean>;
112
+ layoutMode: z.ZodOptional<z.ZodEnum<{
113
+ NONE: "NONE";
114
+ HORIZONTAL: "HORIZONTAL";
115
+ VERTICAL: "VERTICAL";
116
+ }>>;
117
+ layoutAlign: z.ZodOptional<z.ZodEnum<{
118
+ MIN: "MIN";
119
+ CENTER: "CENTER";
120
+ MAX: "MAX";
121
+ STRETCH: "STRETCH";
122
+ INHERIT: "INHERIT";
123
+ }>>;
124
+ layoutPositioning: z.ZodOptional<z.ZodEnum<{
125
+ AUTO: "AUTO";
126
+ ABSOLUTE: "ABSOLUTE";
127
+ }>>;
128
+ primaryAxisAlignItems: z.ZodOptional<z.ZodString>;
129
+ counterAxisAlignItems: z.ZodOptional<z.ZodString>;
130
+ itemSpacing: z.ZodOptional<z.ZodNumber>;
131
+ paddingLeft: z.ZodOptional<z.ZodNumber>;
132
+ paddingRight: z.ZodOptional<z.ZodNumber>;
133
+ paddingTop: z.ZodOptional<z.ZodNumber>;
134
+ paddingBottom: z.ZodOptional<z.ZodNumber>;
135
+ absoluteBoundingBox: z.ZodOptional<z.ZodNullable<z.ZodObject<{
136
+ x: z.ZodNumber;
137
+ y: z.ZodNumber;
138
+ width: z.ZodNumber;
139
+ height: z.ZodNumber;
140
+ }, z.core.$strip>>>;
141
+ componentId: z.ZodOptional<z.ZodString>;
142
+ componentPropertyDefinitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
143
+ componentProperties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
144
+ styles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
145
+ fills: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
146
+ strokes: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
147
+ effects: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
148
+ boundVariables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
149
+ characters: z.ZodOptional<z.ZodString>;
150
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
151
+ devStatus: z.ZodOptional<z.ZodObject<{
152
+ type: z.ZodEnum<{
153
+ NONE: "NONE";
154
+ READY_FOR_DEV: "READY_FOR_DEV";
155
+ COMPLETED: "COMPLETED";
156
+ }>;
157
+ description: z.ZodOptional<z.ZodString>;
158
+ }, z.core.$strip>>;
159
+ isAsset: z.ZodOptional<z.ZodBoolean>;
160
+ }, z.core.$strip>;
161
+ type AnalysisNode = z.infer<typeof BaseAnalysisNodeSchema> & {
162
+ children?: AnalysisNode[] | undefined;
163
+ };
164
+ declare const AnalysisNodeSchema: z.ZodType<AnalysisNode>;
165
+ /**
166
+ * Figma file metadata for analysis
167
+ */
168
+ declare const AnalysisFileSchema: z.ZodObject<{
169
+ fileKey: z.ZodString;
170
+ name: z.ZodString;
171
+ lastModified: z.ZodString;
172
+ version: z.ZodString;
173
+ document: z.ZodType<AnalysisNode, unknown, z.core.$ZodTypeInternals<AnalysisNode, unknown>>;
174
+ components: z.ZodRecord<z.ZodString, z.ZodObject<{
175
+ key: z.ZodString;
176
+ name: z.ZodString;
177
+ description: z.ZodString;
178
+ }, z.core.$strip>>;
179
+ styles: z.ZodRecord<z.ZodString, z.ZodObject<{
180
+ key: z.ZodString;
181
+ name: z.ZodString;
182
+ styleType: z.ZodString;
183
+ }, z.core.$strip>>;
184
+ }, z.core.$strip>;
185
+ type AnalysisFile = z.infer<typeof AnalysisFileSchema>;
186
+
187
+ /**
188
+ * Rule definition - static metadata (does not change)
189
+ */
190
+ declare const RuleDefinitionSchema: z.ZodObject<{
191
+ id: z.ZodString;
192
+ name: z.ZodString;
193
+ category: z.ZodEnum<{
194
+ layout: "layout";
195
+ token: "token";
196
+ component: "component";
197
+ naming: "naming";
198
+ "ai-readability": "ai-readability";
199
+ "handoff-risk": "handoff-risk";
200
+ }>;
201
+ why: z.ZodString;
202
+ impact: z.ZodString;
203
+ fix: z.ZodString;
204
+ }, z.core.$strip>;
205
+ type RuleDefinition = z.infer<typeof RuleDefinitionSchema>;
206
+ /**
207
+ * Rule config - adjustable settings (can be modified via presets)
208
+ */
209
+ declare const RuleConfigSchema: z.ZodObject<{
210
+ severity: z.ZodEnum<{
211
+ blocking: "blocking";
212
+ risk: "risk";
213
+ "missing-info": "missing-info";
214
+ suggestion: "suggestion";
215
+ }>;
216
+ score: z.ZodNumber;
217
+ depthWeight: z.ZodOptional<z.ZodNumber>;
218
+ enabled: z.ZodDefault<z.ZodBoolean>;
219
+ options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
220
+ }, z.core.$strip>;
221
+ type RuleConfig = z.infer<typeof RuleConfigSchema>;
222
+ /**
223
+ * Context passed to rule check functions
224
+ */
225
+ interface RuleContext {
226
+ file: AnalysisFile;
227
+ parent?: AnalysisNode | undefined;
228
+ depth: number;
229
+ maxDepth: number;
230
+ path: string[];
231
+ siblings?: AnalysisNode[] | undefined;
232
+ }
233
+ /**
234
+ * Rule violation result from check function
235
+ */
236
+ interface RuleViolation {
237
+ ruleId: string;
238
+ nodeId: string;
239
+ nodePath: string;
240
+ message: string;
241
+ }
242
+ /**
243
+ * Rule check function signature
244
+ */
245
+ type RuleCheckFn = (node: AnalysisNode, context: RuleContext, options?: Record<string, unknown>) => RuleViolation | null;
246
+ /**
247
+ * Complete rule with definition, config, and check function
248
+ */
249
+ interface Rule {
250
+ definition: RuleDefinition;
251
+ check: RuleCheckFn;
252
+ }
253
+ /**
254
+ * Rule ID type for type safety
255
+ */
256
+ type RuleId = "no-auto-layout" | "absolute-position-in-auto-layout" | "fixed-width-in-responsive-context" | "missing-responsive-behavior" | "group-usage" | "fixed-size-in-auto-layout" | "missing-min-width" | "missing-max-width" | "deep-nesting" | "overflow-hidden-abuse" | "inconsistent-sibling-layout-direction" | "raw-color" | "raw-font" | "inconsistent-spacing" | "magic-number-spacing" | "raw-shadow" | "raw-opacity" | "multiple-fill-colors" | "missing-component" | "detached-instance" | "nested-instance-override" | "variant-not-used" | "component-property-unused" | "single-use-component" | "default-name" | "non-semantic-name" | "inconsistent-naming-convention" | "numeric-suffix-name" | "too-long-name" | "ambiguous-structure" | "z-index-dependent-layout" | "missing-layout-hint" | "invisible-layer" | "empty-frame" | "hardcode-risk" | "text-truncation-unhandled" | "image-no-placeholder" | "prototype-link-in-design" | "no-dev-status";
257
+ /**
258
+ * Categories that support depthWeight
259
+ */
260
+ declare const DEPTH_WEIGHT_CATEGORIES: Category[];
261
+ /**
262
+ * Check if a category supports depth weighting
263
+ */
264
+ declare function supportsDepthWeight(category: Category): boolean;
265
+
266
+ declare const IssueSchema: z.ZodObject<{
267
+ nodeId: z.ZodString;
268
+ nodePath: z.ZodString;
269
+ figmaDeepLink: z.ZodString;
270
+ ruleId: z.ZodString;
271
+ message: z.ZodString;
272
+ severity: z.ZodEnum<{
273
+ blocking: "blocking";
274
+ risk: "risk";
275
+ "missing-info": "missing-info";
276
+ suggestion: "suggestion";
277
+ }>;
278
+ }, z.core.$strip>;
279
+ type Issue = z.infer<typeof IssueSchema>;
280
+
281
+ declare const CategoryScoreSchema: z.ZodObject<{
282
+ category: z.ZodEnum<{
283
+ layout: "layout";
284
+ token: "token";
285
+ component: "component";
286
+ naming: "naming";
287
+ "ai-readability": "ai-readability";
288
+ "handoff-risk": "handoff-risk";
289
+ }>;
290
+ score: z.ZodNumber;
291
+ maxScore: z.ZodNumber;
292
+ issueCount: z.ZodObject<{
293
+ error: z.ZodNumber;
294
+ warning: z.ZodNumber;
295
+ info: z.ZodNumber;
296
+ }, z.core.$strip>;
297
+ }, z.core.$strip>;
298
+ type CategoryScore = z.infer<typeof CategoryScoreSchema>;
299
+
300
+ declare const ReportMetadataSchema: z.ZodObject<{
301
+ fileKey: z.ZodString;
302
+ fileName: z.ZodString;
303
+ analyzedAt: z.ZodString;
304
+ version: z.ZodString;
305
+ }, z.core.$strip>;
306
+ type ReportMetadata = z.infer<typeof ReportMetadataSchema>;
307
+ declare const ReportSchema: z.ZodObject<{
308
+ metadata: z.ZodObject<{
309
+ fileKey: z.ZodString;
310
+ fileName: z.ZodString;
311
+ analyzedAt: z.ZodString;
312
+ version: z.ZodString;
313
+ }, z.core.$strip>;
314
+ totalScore: z.ZodNumber;
315
+ categoryScores: z.ZodArray<z.ZodObject<{
316
+ category: z.ZodEnum<{
317
+ layout: "layout";
318
+ token: "token";
319
+ component: "component";
320
+ naming: "naming";
321
+ "ai-readability": "ai-readability";
322
+ "handoff-risk": "handoff-risk";
323
+ }>;
324
+ score: z.ZodNumber;
325
+ maxScore: z.ZodNumber;
326
+ issueCount: z.ZodObject<{
327
+ error: z.ZodNumber;
328
+ warning: z.ZodNumber;
329
+ info: z.ZodNumber;
330
+ }, z.core.$strip>;
331
+ }, z.core.$strip>>;
332
+ issues: z.ZodArray<z.ZodObject<{
333
+ nodeId: z.ZodString;
334
+ nodePath: z.ZodString;
335
+ figmaDeepLink: z.ZodString;
336
+ ruleId: z.ZodString;
337
+ message: z.ZodString;
338
+ severity: z.ZodEnum<{
339
+ blocking: "blocking";
340
+ risk: "risk";
341
+ "missing-info": "missing-info";
342
+ suggestion: "suggestion";
343
+ }>;
344
+ }, z.core.$strip>>;
345
+ summary: z.ZodObject<{
346
+ totalNodes: z.ZodNumber;
347
+ analyzedNodes: z.ZodNumber;
348
+ errorCount: z.ZodNumber;
349
+ warningCount: z.ZodNumber;
350
+ infoCount: z.ZodNumber;
351
+ }, z.core.$strip>;
352
+ }, z.core.$strip>;
353
+ type Report = z.infer<typeof ReportSchema>;
354
+
355
+ /**
356
+ * Analysis issue with calculated score and metadata
357
+ */
358
+ interface AnalysisIssue {
359
+ violation: RuleViolation;
360
+ rule: Rule;
361
+ config: RuleConfig;
362
+ depth: number;
363
+ maxDepth: number;
364
+ calculatedScore: number;
365
+ }
366
+ /**
367
+ * Analysis result from the rule engine
368
+ */
369
+ interface AnalysisResult {
370
+ file: AnalysisFile;
371
+ issues: AnalysisIssue[];
372
+ maxDepth: number;
373
+ nodeCount: number;
374
+ analyzedAt: string;
375
+ }
376
+ /**
377
+ * Options for the rule engine
378
+ */
379
+ interface RuleEngineOptions {
380
+ configs?: Record<RuleId, RuleConfig>;
381
+ enabledRules?: RuleId[];
382
+ disabledRules?: RuleId[];
383
+ targetNodeId?: string;
384
+ }
385
+ /**
386
+ * Rule engine for analyzing Figma files
387
+ */
388
+ declare class RuleEngine {
389
+ private configs;
390
+ private enabledRuleIds;
391
+ private disabledRuleIds;
392
+ private targetNodeId;
393
+ constructor(options?: RuleEngineOptions);
394
+ /**
395
+ * Analyze a Figma file and return issues
396
+ */
397
+ analyze(file: AnalysisFile): AnalysisResult;
398
+ /**
399
+ * Get rules that should be run based on configuration
400
+ */
401
+ private getEnabledRules;
402
+ /**
403
+ * Recursively traverse the tree and run rules
404
+ */
405
+ private traverseAndCheck;
406
+ }
407
+ /**
408
+ * Create a rule engine with default configuration
409
+ */
410
+ declare function createRuleEngine(options?: RuleEngineOptions): RuleEngine;
411
+ /**
412
+ * Convenience function to analyze a file with default settings
413
+ */
414
+ declare function analyzeFile(file: AnalysisFile, options?: RuleEngineOptions): AnalysisResult;
415
+
416
+ /**
417
+ * Score breakdown for a single category
418
+ */
419
+ interface CategoryScoreResult {
420
+ category: Category;
421
+ score: number;
422
+ maxScore: number;
423
+ percentage: number;
424
+ issueCount: number;
425
+ uniqueRuleCount: number;
426
+ weightedIssueCount: number;
427
+ densityScore: number;
428
+ diversityScore: number;
429
+ bySeverity: Record<Severity, number>;
430
+ }
431
+ /**
432
+ * Overall score report
433
+ */
434
+ interface ScoreReport {
435
+ overall: {
436
+ score: number;
437
+ maxScore: number;
438
+ percentage: number;
439
+ grade: Grade;
440
+ };
441
+ byCategory: Record<Category, CategoryScoreResult>;
442
+ summary: {
443
+ totalIssues: number;
444
+ blocking: number;
445
+ risk: number;
446
+ missingInfo: number;
447
+ suggestion: number;
448
+ nodeCount: number;
449
+ };
450
+ }
451
+ /**
452
+ * Grade levels based on percentage
453
+ */
454
+ type Grade = "S" | "A+" | "A" | "B+" | "B" | "C+" | "C" | "D" | "F";
455
+ /**
456
+ * Convert grade to a CSS-safe class name suffix
457
+ * e.g. "A+" -> "Aplus", "B+" -> "Bplus", "C+" -> "Cplus"
458
+ */
459
+ declare function gradeToClassName(grade: Grade): string;
460
+ /**
461
+ * Calculate scores from analysis result using density + diversity scoring
462
+ *
463
+ * Density Score = 100 - (weighted issue count / node count) * 100
464
+ * Diversity Score = (1 - unique rules / total category rules) * 100
465
+ * Final Score = density * 0.7 + diversity * 0.3
466
+ */
467
+ declare function calculateScores(result: AnalysisResult): ScoreReport;
468
+ /**
469
+ * Format score report as a summary string
470
+ */
471
+ declare function formatScoreSummary(report: ScoreReport): string;
472
+ /**
473
+ * Get category label for display
474
+ */
475
+ declare function getCategoryLabel(category: Category): string;
476
+ /**
477
+ * Get severity label for display
478
+ */
479
+ declare function getSeverityLabel(severity: Severity): string;
480
+
481
+ /**
482
+ * Registry for all rules
483
+ */
484
+ declare class RuleRegistry {
485
+ private rules;
486
+ /**
487
+ * Register a rule
488
+ */
489
+ register(rule: Rule): void;
490
+ /**
491
+ * Get a rule by ID
492
+ */
493
+ get(id: RuleId): Rule | undefined;
494
+ /**
495
+ * Get all registered rules
496
+ */
497
+ getAll(): Rule[];
498
+ /**
499
+ * Get rules by category
500
+ */
501
+ getByCategory(category: Category): Rule[];
502
+ /**
503
+ * Get enabled rules with their configs
504
+ */
505
+ getEnabled(configs?: Record<RuleId, RuleConfig>): Rule[];
506
+ /**
507
+ * Get config for a rule
508
+ */
509
+ getConfig(id: RuleId, configs?: Record<RuleId, RuleConfig>): RuleConfig;
510
+ /**
511
+ * Check if a rule is registered
512
+ */
513
+ has(id: RuleId): boolean;
514
+ /**
515
+ * Get count of registered rules
516
+ */
517
+ get size(): number;
518
+ }
519
+ /**
520
+ * Global rule registry instance
521
+ */
522
+ declare const ruleRegistry: RuleRegistry;
523
+ /**
524
+ * Helper to create and register a rule
525
+ */
526
+ declare function defineRule(rule: Rule): Rule;
527
+
528
+ /**
529
+ * Central configuration for all rules
530
+ * Edit scores/severity here without touching rule logic
531
+ */
532
+ declare const RULE_CONFIGS: Record<RuleId, RuleConfig>;
533
+ /**
534
+ * Preset types for different analysis modes
535
+ */
536
+ type Preset = "relaxed" | "dev-friendly" | "ai-ready" | "strict";
537
+ /**
538
+ * Get rule configs with preset applied
539
+ */
540
+ declare function getConfigsWithPreset(preset: Preset): Record<RuleId, RuleConfig>;
541
+ /**
542
+ * Get option value for a rule with type safety
543
+ */
544
+ declare function getRuleOption<T>(ruleId: RuleId, optionKey: string, defaultValue: T): T;
545
+
546
+ declare const noAutoLayout: Rule;
547
+ declare const absolutePositionInAutoLayout: Rule;
548
+ declare const fixedWidthInResponsiveContext: Rule;
549
+ declare const missingResponsiveBehavior: Rule;
550
+ declare const groupUsage: Rule;
551
+ declare const fixedSizeInAutoLayout: Rule;
552
+ declare const missingMinWidth: Rule;
553
+ declare const missingMaxWidth: Rule;
554
+ declare const deepNesting: Rule;
555
+ declare const overflowHiddenAbuse: Rule;
556
+ declare const inconsistentSiblingLayoutDirection: Rule;
557
+
558
+ declare const rawColor: Rule;
559
+ declare const rawFont: Rule;
560
+ declare const inconsistentSpacing: Rule;
561
+ declare const magicNumberSpacing: Rule;
562
+ declare const rawShadow: Rule;
563
+ declare const rawOpacity: Rule;
564
+ declare const multipleFillColors: Rule;
565
+
566
+ declare const missingComponent: Rule;
567
+ declare const detachedInstance: Rule;
568
+ declare const nestedInstanceOverride: Rule;
569
+ declare const variantNotUsed: Rule;
570
+ declare const componentPropertyUnused: Rule;
571
+ declare const singleUseComponent: Rule;
572
+
573
+ declare const defaultName: Rule;
574
+ declare const nonSemanticName: Rule;
575
+ declare const inconsistentNamingConvention: Rule;
576
+ declare const numericSuffixName: Rule;
577
+ declare const tooLongName: Rule;
578
+
579
+ declare const ambiguousStructure: Rule;
580
+ declare const zIndexDependentLayout: Rule;
581
+ declare const missingLayoutHint: Rule;
582
+ declare const invisibleLayer: Rule;
583
+ declare const emptyFrame: Rule;
584
+
585
+ declare const hardcodeRisk: Rule;
586
+ declare const textTruncationUnhandled: Rule;
587
+ declare const imageNoPlaceholder: Rule;
588
+ declare const prototypeLinkInDesign: Rule;
589
+ declare const noDevStatus: Rule;
590
+
591
+ declare const FigmaUrlInfoSchema: z.ZodObject<{
592
+ fileKey: z.ZodString;
593
+ nodeId: z.ZodOptional<z.ZodString>;
594
+ fileName: z.ZodOptional<z.ZodString>;
595
+ }, z.core.$strip>;
596
+ type FigmaUrlInfo = z.infer<typeof FigmaUrlInfoSchema>;
597
+ declare function parseFigmaUrl(url: string): FigmaUrlInfo;
598
+ declare class FigmaUrlParseError extends Error {
599
+ constructor(message: string);
600
+ }
601
+ declare function buildFigmaDeepLink(fileKey: string, nodeId: string): string;
602
+
603
+ interface FigmaClientOptions {
604
+ token: string;
605
+ }
606
+ declare class FigmaClient {
607
+ private token;
608
+ constructor(options: FigmaClientOptions);
609
+ static fromEnv(): FigmaClient;
610
+ getFile(fileKey: string): Promise<GetFileResponse>;
611
+ /**
612
+ * Get rendered images for specific nodes
613
+ * Returns a map of nodeId → image URL
614
+ */
615
+ getNodeImages(fileKey: string, nodeIds: string[], options?: {
616
+ format?: "png" | "svg" | "jpg";
617
+ scale?: number;
618
+ }): Promise<Record<string, string | null>>;
619
+ /**
620
+ * Download an image URL and return as base64
621
+ */
622
+ fetchImageAsBase64(imageUrl: string): Promise<string>;
623
+ getFileNodes(fileKey: string, nodeIds: string[]): Promise<GetFileResponse>;
624
+ }
625
+ declare class FigmaClientError extends Error {
626
+ statusCode?: number | undefined;
627
+ responseBody?: unknown | undefined;
628
+ constructor(message: string, statusCode?: number | undefined, responseBody?: unknown | undefined);
629
+ }
630
+
631
+ /**
632
+ * Transform Figma API response to analysis types
633
+ */
634
+ declare function transformFigmaResponse(fileKey: string, response: GetFileResponse): AnalysisFile;
635
+
636
+ /**
637
+ * Load Figma data from a JSON file
638
+ * For MVP testing and fixture support
639
+ */
640
+ declare function loadFigmaFileFromJson(filePath: string): Promise<AnalysisFile>;
641
+ /**
642
+ * Parse Figma data from a JSON string
643
+ */
644
+ declare function parseFigmaJson(json: string, fileKey: string): AnalysisFile;
645
+ declare class FigmaFileLoadError extends Error {
646
+ filePath?: string | undefined;
647
+ constructor(message: string, filePath?: string | undefined);
648
+ }
649
+
650
+ /**
651
+ * Parse MCP get_metadata XML output into an AnalysisFile.
652
+ *
653
+ * The XML represents a subtree of the Figma file. We wrap it in a
654
+ * DOCUMENT node and fill in minimal file metadata.
655
+ */
656
+ declare function parseMcpMetadataXml(xml: string, fileKey: string, fileName?: string): AnalysisFile;
657
+
658
+ declare const SamplingStrategySchema: z.ZodEnum<{
659
+ all: "all";
660
+ "top-issues": "top-issues";
661
+ random: "random";
662
+ }>;
663
+ type SamplingStrategy = z.infer<typeof SamplingStrategySchema>;
664
+ declare const CalibrationStatusSchema: z.ZodEnum<{
665
+ pending: "pending";
666
+ analyzing: "analyzing";
667
+ converting: "converting";
668
+ evaluating: "evaluating";
669
+ tuning: "tuning";
670
+ completed: "completed";
671
+ failed: "failed";
672
+ }>;
673
+ type CalibrationStatus = z.infer<typeof CalibrationStatusSchema>;
674
+ declare const CalibrationConfigSchema: z.ZodObject<{
675
+ input: z.ZodString;
676
+ token: z.ZodOptional<z.ZodString>;
677
+ targetNodeId: z.ZodOptional<z.ZodString>;
678
+ maxConversionNodes: z.ZodDefault<z.ZodNumber>;
679
+ samplingStrategy: z.ZodDefault<z.ZodEnum<{
680
+ all: "all";
681
+ "top-issues": "top-issues";
682
+ random: "random";
683
+ }>>;
684
+ outputPath: z.ZodDefault<z.ZodString>;
685
+ }, z.core.$strip>;
686
+ type CalibrationConfig = z.infer<typeof CalibrationConfigSchema>;
687
+ interface CalibrationRun {
688
+ config: CalibrationConfig;
689
+ status: CalibrationStatus;
690
+ startedAt: string;
691
+ completedAt?: string;
692
+ error?: string;
693
+ }
694
+
695
+ declare const NodeIssueSummarySchema: z.ZodObject<{
696
+ nodeId: z.ZodString;
697
+ nodePath: z.ZodString;
698
+ totalScore: z.ZodNumber;
699
+ issueCount: z.ZodNumber;
700
+ flaggedRuleIds: z.ZodArray<z.ZodString>;
701
+ severities: z.ZodArray<z.ZodString>;
702
+ }, z.core.$strip>;
703
+ type NodeIssueSummary = z.infer<typeof NodeIssueSummarySchema>;
704
+ interface AnalysisAgentInput {
705
+ analysisResult: AnalysisResult;
706
+ }
707
+ interface AnalysisAgentOutput {
708
+ analysisResult: AnalysisResult;
709
+ scoreReport: ScoreReport;
710
+ nodeIssueSummaries: NodeIssueSummary[];
711
+ }
712
+ interface NodeIssueDetail {
713
+ ruleId: RuleId;
714
+ severity: Severity;
715
+ calculatedScore: number;
716
+ message: string;
717
+ }
718
+
719
+ declare const DifficultySchema: z.ZodEnum<{
720
+ failed: "failed";
721
+ easy: "easy";
722
+ moderate: "moderate";
723
+ hard: "hard";
724
+ }>;
725
+ type Difficulty = z.infer<typeof DifficultySchema>;
726
+ declare const RuleRelatedStruggleSchema: z.ZodObject<{
727
+ ruleId: z.ZodString;
728
+ description: z.ZodString;
729
+ actualImpact: z.ZodEnum<{
730
+ failed: "failed";
731
+ easy: "easy";
732
+ moderate: "moderate";
733
+ hard: "hard";
734
+ }>;
735
+ }, z.core.$strip>;
736
+ type RuleRelatedStruggle = z.infer<typeof RuleRelatedStruggleSchema>;
737
+ declare const UncoveredStruggleSchema: z.ZodObject<{
738
+ description: z.ZodString;
739
+ suggestedCategory: z.ZodString;
740
+ estimatedImpact: z.ZodEnum<{
741
+ failed: "failed";
742
+ easy: "easy";
743
+ moderate: "moderate";
744
+ hard: "hard";
745
+ }>;
746
+ }, z.core.$strip>;
747
+ type UncoveredStruggle = z.infer<typeof UncoveredStruggleSchema>;
748
+ declare const ConversionRecordSchema: z.ZodObject<{
749
+ nodeId: z.ZodString;
750
+ nodePath: z.ZodString;
751
+ generatedCode: z.ZodString;
752
+ difficulty: z.ZodEnum<{
753
+ failed: "failed";
754
+ easy: "easy";
755
+ moderate: "moderate";
756
+ hard: "hard";
757
+ }>;
758
+ notes: z.ZodString;
759
+ ruleRelatedStruggles: z.ZodArray<z.ZodObject<{
760
+ ruleId: z.ZodString;
761
+ description: z.ZodString;
762
+ actualImpact: z.ZodEnum<{
763
+ failed: "failed";
764
+ easy: "easy";
765
+ moderate: "moderate";
766
+ hard: "hard";
767
+ }>;
768
+ }, z.core.$strip>>;
769
+ uncoveredStruggles: z.ZodArray<z.ZodObject<{
770
+ description: z.ZodString;
771
+ suggestedCategory: z.ZodString;
772
+ estimatedImpact: z.ZodEnum<{
773
+ failed: "failed";
774
+ easy: "easy";
775
+ moderate: "moderate";
776
+ hard: "hard";
777
+ }>;
778
+ }, z.core.$strip>>;
779
+ durationMs: z.ZodNumber;
780
+ }, z.core.$strip>;
781
+ type ConversionRecord = z.infer<typeof ConversionRecordSchema>;
782
+ interface ConversionExecutorResult {
783
+ generatedCode: string;
784
+ difficulty: Difficulty;
785
+ notes: string;
786
+ ruleRelatedStruggles: RuleRelatedStruggle[];
787
+ uncoveredStruggles: UncoveredStruggle[];
788
+ }
789
+ type ConversionExecutor = (nodeId: string, fileKey: string, flaggedRuleIds: string[]) => Promise<ConversionExecutorResult>;
790
+ interface ConversionAgentInput {
791
+ fileKey: string;
792
+ nodes: Array<{
793
+ nodeId: string;
794
+ nodePath: string;
795
+ flaggedRuleIds: string[];
796
+ }>;
797
+ }
798
+ interface ConversionAgentOutput {
799
+ records: ConversionRecord[];
800
+ skippedNodeIds: string[];
801
+ }
802
+
803
+ declare const MismatchTypeSchema: z.ZodEnum<{
804
+ overscored: "overscored";
805
+ underscored: "underscored";
806
+ "missing-rule": "missing-rule";
807
+ validated: "validated";
808
+ }>;
809
+ type MismatchType = z.infer<typeof MismatchTypeSchema>;
810
+ declare const MismatchCaseSchema: z.ZodObject<{
811
+ type: z.ZodEnum<{
812
+ overscored: "overscored";
813
+ underscored: "underscored";
814
+ "missing-rule": "missing-rule";
815
+ validated: "validated";
816
+ }>;
817
+ nodeId: z.ZodString;
818
+ nodePath: z.ZodString;
819
+ ruleId: z.ZodOptional<z.ZodString>;
820
+ currentScore: z.ZodOptional<z.ZodNumber>;
821
+ currentSeverity: z.ZodOptional<z.ZodEnum<{
822
+ blocking: "blocking";
823
+ risk: "risk";
824
+ "missing-info": "missing-info";
825
+ suggestion: "suggestion";
826
+ }>>;
827
+ actualDifficulty: z.ZodEnum<{
828
+ failed: "failed";
829
+ easy: "easy";
830
+ moderate: "moderate";
831
+ hard: "hard";
832
+ }>;
833
+ reasoning: z.ZodString;
834
+ }, z.core.$strip>;
835
+ type MismatchCase = z.infer<typeof MismatchCaseSchema>;
836
+ interface EvaluationAgentInput {
837
+ nodeIssueSummaries: Array<{
838
+ nodeId: string;
839
+ nodePath: string;
840
+ flaggedRuleIds: string[];
841
+ }>;
842
+ conversionRecords: Array<{
843
+ nodeId: string;
844
+ nodePath: string;
845
+ difficulty: string;
846
+ ruleRelatedStruggles: Array<{
847
+ ruleId: string;
848
+ description: string;
849
+ actualImpact: string;
850
+ }>;
851
+ uncoveredStruggles: Array<{
852
+ description: string;
853
+ suggestedCategory: string;
854
+ estimatedImpact: string;
855
+ }>;
856
+ }>;
857
+ ruleScores: Record<string, {
858
+ score: number;
859
+ severity: string;
860
+ }>;
861
+ }
862
+ interface EvaluationAgentOutput {
863
+ mismatches: MismatchCase[];
864
+ validatedRules: string[];
865
+ }
866
+
867
+ declare const ConfidenceSchema: z.ZodEnum<{
868
+ high: "high";
869
+ medium: "medium";
870
+ low: "low";
871
+ }>;
872
+ type Confidence = z.infer<typeof ConfidenceSchema>;
873
+ declare const ScoreAdjustmentSchema: z.ZodObject<{
874
+ ruleId: z.ZodString;
875
+ currentScore: z.ZodNumber;
876
+ proposedScore: z.ZodNumber;
877
+ currentSeverity: z.ZodEnum<{
878
+ blocking: "blocking";
879
+ risk: "risk";
880
+ "missing-info": "missing-info";
881
+ suggestion: "suggestion";
882
+ }>;
883
+ proposedSeverity: z.ZodOptional<z.ZodEnum<{
884
+ blocking: "blocking";
885
+ risk: "risk";
886
+ "missing-info": "missing-info";
887
+ suggestion: "suggestion";
888
+ }>>;
889
+ reasoning: z.ZodString;
890
+ confidence: z.ZodEnum<{
891
+ high: "high";
892
+ medium: "medium";
893
+ low: "low";
894
+ }>;
895
+ supportingCases: z.ZodNumber;
896
+ }, z.core.$strip>;
897
+ type ScoreAdjustment = z.infer<typeof ScoreAdjustmentSchema>;
898
+ declare const NewRuleProposalSchema: z.ZodObject<{
899
+ suggestedId: z.ZodString;
900
+ category: z.ZodString;
901
+ description: z.ZodString;
902
+ suggestedSeverity: z.ZodEnum<{
903
+ blocking: "blocking";
904
+ risk: "risk";
905
+ "missing-info": "missing-info";
906
+ suggestion: "suggestion";
907
+ }>;
908
+ suggestedScore: z.ZodNumber;
909
+ reasoning: z.ZodString;
910
+ supportingCases: z.ZodNumber;
911
+ }, z.core.$strip>;
912
+ type NewRuleProposal = z.infer<typeof NewRuleProposalSchema>;
913
+ interface TuningAgentInput {
914
+ mismatches: Array<{
915
+ type: string;
916
+ nodeId: string;
917
+ nodePath: string;
918
+ ruleId?: string | undefined;
919
+ currentScore?: number | undefined;
920
+ currentSeverity?: string | undefined;
921
+ actualDifficulty: string;
922
+ reasoning: string;
923
+ }>;
924
+ ruleScores: Record<string, {
925
+ score: number;
926
+ severity: string;
927
+ }>;
928
+ }
929
+ interface TuningAgentOutput {
930
+ adjustments: ScoreAdjustment[];
931
+ newRuleProposals: NewRuleProposal[];
932
+ }
933
+
934
+ /**
935
+ * Extract rule scores map from analysis result for downstream agents
936
+ */
937
+ declare function extractRuleScores(result: AnalysisResult): Record<string, {
938
+ score: number;
939
+ severity: string;
940
+ }>;
941
+ /**
942
+ * Analysis Agent - Step 1 of calibration pipeline
943
+ *
944
+ * Wraps existing analyzeFile + calculateScores and adds
945
+ * nodeId-grouped issue summaries for downstream agents.
946
+ */
947
+ declare function runAnalysisAgent(input: AnalysisAgentInput): AnalysisAgentOutput;
948
+
949
+ /**
950
+ * Conversion Agent - Step 2 of calibration pipeline
951
+ *
952
+ * Attempts code conversion for each node via an injected executor.
953
+ * Uses dependency inversion: the executor handles actual LLM/MCP calls.
954
+ * Failures on individual nodes are captured, not thrown.
955
+ */
956
+ declare function runConversionAgent(input: ConversionAgentInput, executor: ConversionExecutor): Promise<ConversionAgentOutput>;
957
+
958
+ /**
959
+ * Prompt template for the conversion executor.
960
+ *
961
+ * The executor (typically an LLM session with Figma MCP access) receives
962
+ * this prompt to guide code generation and difficulty assessment.
963
+ */
964
+ declare function buildConversionPrompt(nodeId: string, fileKey: string, flaggedRuleIds: string[]): string;
965
+
966
+ /**
967
+ * Evaluation Agent - Step 3 of calibration pipeline
968
+ *
969
+ * Deterministic comparison of analysis results vs conversion results.
970
+ * No LLM required — pure algorithmic evaluation.
971
+ */
972
+ declare function runEvaluationAgent(input: EvaluationAgentInput): EvaluationAgentOutput;
973
+
974
+ /**
975
+ * Tuning Agent - Step 4 of calibration pipeline
976
+ *
977
+ * Deterministic aggregation algorithm. No LLM required.
978
+ * Aggregates mismatch cases into score adjustment proposals.
979
+ */
980
+ declare function runTuningAgent(input: TuningAgentInput): TuningAgentOutput;
981
+
982
+ interface CalibrationReportData {
983
+ fileKey: string;
984
+ fileName: string;
985
+ analyzedAt: string;
986
+ nodeCount: number;
987
+ issueCount: number;
988
+ convertedNodeCount: number;
989
+ skippedNodeCount: number;
990
+ scoreReport: ScoreReport;
991
+ mismatches: MismatchCase[];
992
+ validatedRules: string[];
993
+ adjustments: ScoreAdjustment[];
994
+ newRuleProposals: NewRuleProposal[];
995
+ }
996
+ /**
997
+ * Generate a CALIBRATION_REPORT.md from calibration pipeline results
998
+ */
999
+ declare function generateCalibrationReport(data: CalibrationReportData): string;
1000
+
1001
+ interface CalibrationRunOptions {
1002
+ enableActivityLog?: boolean;
1003
+ }
1004
+ interface CalibrationRunResult {
1005
+ status: CalibrationStatus;
1006
+ scoreReport: ScoreReport;
1007
+ nodeIssueSummaries: NodeIssueSummary[];
1008
+ mismatches: MismatchCase[];
1009
+ validatedRules: string[];
1010
+ adjustments: ScoreAdjustment[];
1011
+ newRuleProposals: NewRuleProposal[];
1012
+ reportPath: string;
1013
+ logPath?: string | undefined;
1014
+ error?: string;
1015
+ }
1016
+ /**
1017
+ * Run Step 1 only: analysis + save JSON output
1018
+ */
1019
+ declare function runCalibrationAnalyze(config: CalibrationConfig): Promise<{
1020
+ analysisOutput: ReturnType<typeof runAnalysisAgent> extends infer T ? T : never;
1021
+ ruleScores: Record<string, {
1022
+ score: number;
1023
+ severity: string;
1024
+ }>;
1025
+ fileKey: string;
1026
+ }>;
1027
+ /**
1028
+ * Run Steps 3+4: evaluation + tuning from pre-computed analysis and conversion data
1029
+ */
1030
+ declare function runCalibrationEvaluate(analysisJson: {
1031
+ nodeIssueSummaries: NodeIssueSummary[];
1032
+ scoreReport: ScoreReport;
1033
+ fileKey: string;
1034
+ fileName: string;
1035
+ analyzedAt: string;
1036
+ nodeCount: number;
1037
+ issueCount: number;
1038
+ }, conversionJson: {
1039
+ records: Array<{
1040
+ nodeId: string;
1041
+ nodePath: string;
1042
+ difficulty: string;
1043
+ ruleRelatedStruggles: Array<{
1044
+ ruleId: string;
1045
+ description: string;
1046
+ actualImpact: string;
1047
+ }>;
1048
+ uncoveredStruggles: Array<{
1049
+ description: string;
1050
+ suggestedCategory: string;
1051
+ estimatedImpact: string;
1052
+ }>;
1053
+ }>;
1054
+ skippedNodeIds: string[];
1055
+ }, ruleScores: Record<string, {
1056
+ score: number;
1057
+ severity: string;
1058
+ }>): {
1059
+ evaluationOutput: EvaluationAgentOutput;
1060
+ tuningOutput: TuningAgentOutput;
1061
+ report: string;
1062
+ };
1063
+ /**
1064
+ * Run the full calibration pipeline
1065
+ *
1066
+ * Sequence: validate -> load file -> analysis -> node selection -> conversion -> evaluation -> tuning -> report
1067
+ */
1068
+ declare function runCalibration(config: CalibrationConfig, executor: ConversionExecutor, options?: CalibrationRunOptions): Promise<CalibrationRunResult>;
1069
+
1070
+ interface ActivityStep {
1071
+ step: string;
1072
+ nodePath?: string;
1073
+ result: string;
1074
+ durationMs: number;
1075
+ }
1076
+ declare class ActivityLogger {
1077
+ private logPath;
1078
+ private initialized;
1079
+ constructor(fixturePath?: string, logDir?: string);
1080
+ /**
1081
+ * Ensure the log directory and file header exist
1082
+ */
1083
+ private ensureInitialized;
1084
+ /**
1085
+ * Log a pipeline step
1086
+ */
1087
+ logStep(activity: ActivityStep): Promise<void>;
1088
+ /**
1089
+ * Log a summary at pipeline completion
1090
+ */
1091
+ logSummary(summary: {
1092
+ totalDurationMs: number;
1093
+ nodesAnalyzed: number;
1094
+ nodesConverted: number;
1095
+ mismatches: number;
1096
+ adjustments: number;
1097
+ status: string;
1098
+ }): Promise<void>;
1099
+ getLogPath(): string;
1100
+ }
1101
+
1102
+ declare const VERSION = "0.1.0";
1103
+
1104
+ export { ActivityLogger, type AnalysisAgentInput, type AnalysisAgentOutput, type AnalysisFile, AnalysisFileSchema, type AnalysisIssue, type AnalysisNode, AnalysisNodeSchema, type AnalysisNodeType, AnalysisNodeTypeSchema, type AnalysisResult, CATEGORIES, CATEGORY_LABELS, type CalibrationConfig, CalibrationConfigSchema, type CalibrationRun, type CalibrationStatus, CalibrationStatusSchema, type Category, CategorySchema, type CategoryScore, type CategoryScoreResult, CategoryScoreSchema, type Confidence, ConfidenceSchema, type ConversionAgentInput, type ConversionAgentOutput, type ConversionExecutor, type ConversionExecutorResult, type ConversionRecord, ConversionRecordSchema, DEPTH_WEIGHT_CATEGORIES, type Difficulty, DifficultySchema, type EvaluationAgentInput, type EvaluationAgentOutput, FigmaClient, FigmaClientError, type FigmaClientOptions, FigmaFileLoadError, type FigmaUrlInfo, FigmaUrlInfoSchema, FigmaUrlParseError, type Grade, type Issue, IssueSchema, type LayoutAlign, LayoutAlignSchema, type LayoutMode, LayoutModeSchema, type LayoutPositioning, LayoutPositioningSchema, type MismatchCase, MismatchCaseSchema, type MismatchType, MismatchTypeSchema, type NewRuleProposal, NewRuleProposalSchema, type NodeIssueDetail, type NodeIssueSummary, NodeIssueSummarySchema, type Preset, RULE_CONFIGS, type Report, type ReportMetadata, ReportMetadataSchema, ReportSchema, type Rule, type RuleCheckFn, type RuleConfig, RuleConfigSchema, type RuleContext, type RuleDefinition, RuleDefinitionSchema, RuleEngine, type RuleEngineOptions, type RuleId, type RuleRelatedStruggle, RuleRelatedStruggleSchema, type RuleViolation, SEVERITY_LABELS, SEVERITY_WEIGHT, type SamplingStrategy, SamplingStrategySchema, type ScoreAdjustment, ScoreAdjustmentSchema, type ScoreReport, type Severity, SeveritySchema, type TuningAgentInput, type TuningAgentOutput, type UncoveredStruggle, UncoveredStruggleSchema, VERSION, absolutePositionInAutoLayout, ambiguousStructure, analyzeFile, buildConversionPrompt, buildFigmaDeepLink, calculateScores, componentPropertyUnused, createRuleEngine, deepNesting, defaultName, defineRule, detachedInstance, emptyFrame, extractRuleScores, fixedSizeInAutoLayout, fixedWidthInResponsiveContext, formatScoreSummary, generateCalibrationReport, getCategoryLabel, getConfigsWithPreset, getRuleOption, getSeverityLabel, gradeToClassName, groupUsage, hardcodeRisk, imageNoPlaceholder, inconsistentNamingConvention, inconsistentSiblingLayoutDirection, inconsistentSpacing, invisibleLayer, loadFigmaFileFromJson, magicNumberSpacing, missingComponent, missingLayoutHint, missingMaxWidth, missingMinWidth, missingResponsiveBehavior, multipleFillColors, nestedInstanceOverride, noAutoLayout, noDevStatus, nonSemanticName, numericSuffixName, overflowHiddenAbuse, parseFigmaJson, parseFigmaUrl, parseMcpMetadataXml, prototypeLinkInDesign, rawColor, rawFont, rawOpacity, rawShadow, ruleRegistry, runAnalysisAgent, runCalibration, runCalibrationAnalyze, runCalibrationEvaluate, runConversionAgent, runEvaluationAgent, runTuningAgent, singleUseComponent, supportsDepthWeight, textTruncationUnhandled, tooLongName, transformFigmaResponse, variantNotUsed, zIndexDependentLayout };