@schemyx/mcp 0.1.2 → 0.1.4

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.
@@ -37,6 +37,7 @@ export declare function extractCssVariableReferences(content: string): string[];
37
37
  export declare function extractClassReferences(content: string, classExpressions?: ClassExpression[]): string[];
38
38
  export declare function extractClassExpressions(content: string): ClassExpression[];
39
39
  export declare function extractComponentStyleDefinitions(content: string): ComponentStyleDefinition[];
40
+ export declare function readJsxClassSources(source: string): string[];
40
41
  export declare function extractThemeTokens(relPath: string, content: string): ThemeToken[];
41
42
  export declare function extractInlineStyles(content: string): InlineStyle[];
42
43
  interface OpeningTagInfo {
@@ -151,6 +152,7 @@ export declare function createRoleDensityKey(classes: string[], children?: UiEle
151
152
  export declare function createRoleSurfaceKey(classes: string[]): string;
152
153
  export declare function createRoleLayoutKey(kind: string, tagName: string, classes: string[], children?: UiElementChildSummary[], parentClasses?: string[]): string;
153
154
  export declare function isCompactHeroEyebrow(classes: string[]): boolean;
155
+ export declare function isPlainTextEyebrow(classes: string[], layoutRole?: string): boolean;
154
156
  export declare function isOverlayPill(classes: string[]): boolean;
155
157
  export declare function isHeroHeadingScale(classes: string[]): boolean;
156
158
  export declare function isOversizedHeadingScale(classes: string[]): boolean;
@@ -158,6 +160,8 @@ export declare function isMetricValueScale(classes: string[]): boolean;
158
160
  export declare function isCompactStatValue(classes: string[]): boolean;
159
161
  export declare function isLargeMetricValue(classes: string[]): boolean;
160
162
  export declare function isCompactStatCard(classes: string[], childRoles: string[]): boolean;
163
+ export declare function isCompactMetricGrid(classes: string[]): boolean;
164
+ export declare function isCtaPanelShell(classes: string[], childRoles?: string[]): boolean;
161
165
  export declare function isInteractiveServiceCard(classes: string[]): boolean;
162
166
  export declare function isStaticArticleCard(classes: string[]): boolean;
163
167
  export declare function isMediaPanelCard(classes: string[], childKinds: string[], childRoles: string[]): boolean;
@@ -32,6 +32,7 @@ exports.extractCssVariableReferences = extractCssVariableReferences;
32
32
  exports.extractClassReferences = extractClassReferences;
33
33
  exports.extractClassExpressions = extractClassExpressions;
34
34
  exports.extractComponentStyleDefinitions = extractComponentStyleDefinitions;
35
+ exports.readJsxClassSources = readJsxClassSources;
35
36
  exports.extractThemeTokens = extractThemeTokens;
36
37
  exports.extractInlineStyles = extractInlineStyles;
37
38
  exports.nearestCssSelector = nearestCssSelector;
@@ -120,6 +121,7 @@ exports.createRoleDensityKey = createRoleDensityKey;
120
121
  exports.createRoleSurfaceKey = createRoleSurfaceKey;
121
122
  exports.createRoleLayoutKey = createRoleLayoutKey;
122
123
  exports.isCompactHeroEyebrow = isCompactHeroEyebrow;
124
+ exports.isPlainTextEyebrow = isPlainTextEyebrow;
123
125
  exports.isOverlayPill = isOverlayPill;
124
126
  exports.isHeroHeadingScale = isHeroHeadingScale;
125
127
  exports.isOversizedHeadingScale = isOversizedHeadingScale;
@@ -127,6 +129,8 @@ exports.isMetricValueScale = isMetricValueScale;
127
129
  exports.isCompactStatValue = isCompactStatValue;
128
130
  exports.isLargeMetricValue = isLargeMetricValue;
129
131
  exports.isCompactStatCard = isCompactStatCard;
132
+ exports.isCompactMetricGrid = isCompactMetricGrid;
133
+ exports.isCtaPanelShell = isCtaPanelShell;
130
134
  exports.isInteractiveServiceCard = isInteractiveServiceCard;
131
135
  exports.isStaticArticleCard = isStaticArticleCard;
132
136
  exports.isMediaPanelCard = isMediaPanelCard;
@@ -810,6 +814,7 @@ function extractClassExpressions(content) {
810
814
  function extractComponentStyleDefinitions(content) {
811
815
  const definitions = [];
812
816
  const cvaPattern = /(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*cva\s*\(/g;
817
+ const forwardRefPattern = /(?:export\s+)?(?:const|let|var)\s+([A-Z][A-Za-z0-9_$]*)\s*=\s*(?:React\.)?forwardRef\b/g;
813
818
  for (const match of content.matchAll(cvaPattern)) {
814
819
  if (isInsideQuotedString(content, match.index ?? 0)) {
815
820
  continue;
@@ -838,6 +843,37 @@ function extractComponentStyleDefinitions(content) {
838
843
  source: (0, utils_1.truncate)(call, 2200),
839
844
  });
840
845
  }
846
+ for (const match of content.matchAll(forwardRefPattern)) {
847
+ if (isInsideQuotedString(content, match.index ?? 0)) {
848
+ continue;
849
+ }
850
+ const forwardRefIndex = content.indexOf('forwardRef', match.index ?? 0);
851
+ const call = readBalancedCall(content, forwardRefIndex);
852
+ if (!call) {
853
+ continue;
854
+ }
855
+ const classSources = readJsxClassSources(call);
856
+ const styleHelper = readPrimaryClassHelperUsage(call);
857
+ const baseClasses = (0, utils_1.unique)(classSources.flatMap((classSource) => analyzeClassSource(classSource).defaultClasses));
858
+ const classes = (0, utils_1.unique)([
859
+ ...classSources.flatMap((classSource) => analyzeClassSource(classSource).classes),
860
+ ...baseClasses,
861
+ ]);
862
+ if (!classes.length && !styleHelper) {
863
+ continue;
864
+ }
865
+ definitions.push({
866
+ name: match[1],
867
+ kind: 'component-wrapper',
868
+ line: (0, utils_1.lineNumberAt)(content, match.index ?? 0),
869
+ baseClasses,
870
+ variants: {},
871
+ defaultVariants: {},
872
+ classes,
873
+ ...(styleHelper ? { styleHelper: styleHelper.name } : {}),
874
+ source: (0, utils_1.truncate)(call, 2200),
875
+ });
876
+ }
841
877
  for (const match of content.matchAll(/(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*(?:Classes|ClassNames|Styles|Variants|Config|Map))\s*=\s*\{/g)) {
842
878
  if (isInsideQuotedString(content, match.index ?? 0)) {
843
879
  continue;
@@ -864,6 +900,25 @@ function extractComponentStyleDefinitions(content) {
864
900
  }
865
901
  return (0, utils_1.uniqueBy)(definitions, (definition) => `${definition.name}:${definition.line}`).slice(0, 80);
866
902
  }
903
+ function readJsxClassSources(source) {
904
+ const sources = [];
905
+ for (const pattern of [
906
+ /\bclass(?:Name)?\s*=\s*(["'`])([\s\S]*?)\1/g,
907
+ /\bclass(?:Name)?\s*=\s*\{\s*(["'`])([\s\S]*?)\1\s*\}/g,
908
+ ]) {
909
+ for (const match of source.matchAll(pattern)) {
910
+ sources.push(match[2] ?? match[1] ?? '');
911
+ }
912
+ }
913
+ for (const match of source.matchAll(/\bclass(?:Name)?\s*=\s*\{/g)) {
914
+ const openIndex = source.indexOf('{', match.index ?? 0);
915
+ const block = readBalancedBlock(source, openIndex);
916
+ if (block) {
917
+ sources.push(block.slice(1, -1));
918
+ }
919
+ }
920
+ return (0, utils_1.unique)(sources.filter(Boolean)).slice(0, 24);
921
+ }
867
922
  function extractThemeTokens(relPath, content) {
868
923
  const shouldExtract = /(?:theme|token|tailwind|config|globals|styles?|css|scss)/i.test(relPath) ||
869
924
  /--[a-zA-Z0-9-_]+\s*:/.test(content);
@@ -1766,6 +1821,7 @@ function isTypographyClass(className) {
1766
1821
  }
1767
1822
  function isTypographyScaleBase(base) {
1768
1823
  return (/^(?:font-|leading-|tracking-|line-clamp|whitespace-|break-|truncate|text-balance|text-pretty|text-nowrap|text-wrap)/.test(base) ||
1824
+ /^(?:uppercase|lowercase|capitalize|normal-case)$/.test(base) ||
1769
1825
  /^(?:fs-|fw-|lh-|display-|lead|small|text-uppercase|text-lowercase|text-capitalize)/.test(base) ||
1770
1826
  /^text-(?:xs|sm|base|lg|xl|[2-9]xl|\[[^\]]+\])/.test(base) ||
1771
1827
  /^max-w-\[(?:\d+(?:\.\d+)?)?ch\]/.test(base));
@@ -2254,7 +2310,11 @@ function createUiRoleSignature(input) {
2254
2310
  }
2255
2311
  if (kind === 'layout') {
2256
2312
  roleGroup = 'layout';
2257
- if (layout === 'split-media-layout') {
2313
+ if (layout === 'compact-metric-grid-layout') {
2314
+ role = 'compact-metric-grid-layout';
2315
+ flags.add('compact-metric-grid');
2316
+ }
2317
+ else if (layout === 'split-media-layout') {
2258
2318
  role = 'split-media-layout';
2259
2319
  flags.add('split-media');
2260
2320
  }
@@ -2317,6 +2377,10 @@ function createUiRoleSignature(input) {
2317
2377
  role = 'hero-stat-card-compact';
2318
2378
  flags.add('compact-stat-card');
2319
2379
  }
2380
+ else if (isCtaPanelShell(classes, childRoles)) {
2381
+ role = 'cta-panel-shell';
2382
+ flags.add('cta-panel');
2383
+ }
2320
2384
  else if (isInteractiveServiceCard(classes)) {
2321
2385
  role = 'interactive-service-card';
2322
2386
  flags.add('interactive-card');
@@ -2335,7 +2399,11 @@ function createUiRoleSignature(input) {
2335
2399
  }
2336
2400
  if (kind === 'text') {
2337
2401
  roleGroup = 'text';
2338
- if (isCompactStatValue(classes)) {
2402
+ if (isPlainTextEyebrow(classes, input.layoutRole)) {
2403
+ role = 'section-eyebrow-text';
2404
+ flags.add('plain-eyebrow');
2405
+ }
2406
+ else if (isCompactStatValue(classes)) {
2339
2407
  role = 'compact-stat-value';
2340
2408
  flags.add('compact-stat-value');
2341
2409
  }
@@ -2389,7 +2457,7 @@ function exactRoleClassFacts(classes) {
2389
2457
  isSizingClass(className) ||
2390
2458
  isLayoutClass(className) ||
2391
2459
  isStateClass(className) ||
2392
- /^(?:bg-|text-|border|rounded|shadow|backdrop|opacity|ring|outline|z-|absolute|relative|fixed|sticky|top-|right-|bottom-|left-|overflow-|object-|aspect-|group|transition|duration|ease)/.test(base));
2460
+ /^(?:bg-|text-|border|rounded|shadow|backdrop|opacity|ring|outline|z-|absolute|relative|fixed|sticky|top-|right-|bottom-|left-|overflow-|object-|aspect-|auto-rows-|grid-cols-|grid-rows-|group|transition|duration|ease)/.test(base));
2393
2461
  })).slice(0, 120);
2394
2462
  }
2395
2463
  function createRoleScaleKey(classes, children = []) {
@@ -2461,6 +2529,10 @@ function createRoleLayoutKey(kind, tagName, classes, children = [], parentClasse
2461
2529
  (baseSet.has('right-3') || baseSet.has('right-4'))) {
2462
2530
  return 'absolute-bottom-right-overlay';
2463
2531
  }
2532
+ if (isCompactMetricGrid(classes) ||
2533
+ isCompactMetricGrid(parentClasses)) {
2534
+ return 'compact-metric-grid-layout';
2535
+ }
2464
2536
  if ((baseSet.has('grid') || parentBaseSet.has('grid')) &&
2465
2537
  hasMediaChild &&
2466
2538
  hasTextChildren &&
@@ -2492,6 +2564,18 @@ function isCompactHeroEyebrow(classes) {
2492
2564
  bases.some((base) => /^py-(?:1\.5|2)$/.test(base)) &&
2493
2565
  bases.some((base) => /^px-(?:3|4|5)$/.test(base)));
2494
2566
  }
2567
+ function isPlainTextEyebrow(classes, layoutRole) {
2568
+ const bases = classes.map(utils_1.classBase);
2569
+ const baseSet = new Set(bases);
2570
+ const hasPlainTextScale = classes.some((className) => /(?:^|:)text-(?:xs|sm|\[(?:10|11|12|13|14)px\])(?:\/\d+|\]\/\d+)?$/.test(className));
2571
+ const hasSurfaceTreatment = bases.some((base) => /^(?:bg-|border|rounded|shadow|ring|outline|backdrop)/.test(base));
2572
+ const hasPillSpacing = bases.some((base) => /^px-/.test(base)) || bases.some((base) => /^py-/.test(base));
2573
+ return (layoutRole === 'eyebrow-or-badge' &&
2574
+ baseSet.has('uppercase') &&
2575
+ hasPlainTextScale &&
2576
+ !hasSurfaceTreatment &&
2577
+ !hasPillSpacing);
2578
+ }
2495
2579
  function isOverlayPill(classes) {
2496
2580
  const bases = classes.map(utils_1.classBase);
2497
2581
  const baseSet = new Set(bases);
@@ -2544,6 +2628,34 @@ function isCompactStatCard(classes, childRoles) {
2544
2628
  bases.some((base) => /^p-(?:4|5)$/.test(base)) &&
2545
2629
  !baseSet.has('group')));
2546
2630
  }
2631
+ function isCompactMetricGrid(classes) {
2632
+ const bases = classes.map(utils_1.classBase);
2633
+ const baseSet = new Set(bases);
2634
+ const hasCompactGap = bases.some((base) => /^gap-(?:2|3|4)$/.test(base));
2635
+ const hasConstrainedWidth = classes.some((className) => /(?:^|:)(?:max-w-(?:2xl|3xl|4xl)|lg:max-w-(?:2xl|3xl|4xl)|max-w-\[[^\]]+\])$/.test(className));
2636
+ const hasDenseColumns = classes.some((className) => /(?:^|:)(?:grid-cols-[34]|grid-cols-\[[^\]]+\]|lg:grid-cols-[34]|md:grid-cols-[34])$/.test(className));
2637
+ return (baseSet.has('grid') &&
2638
+ (baseSet.has('auto-rows-fr') || baseSet.has('items-stretch')) &&
2639
+ hasCompactGap &&
2640
+ hasDenseColumns &&
2641
+ hasConstrainedWidth);
2642
+ }
2643
+ function isCtaPanelShell(classes, childRoles = []) {
2644
+ const bases = classes.map(utils_1.classBase);
2645
+ const baseSet = new Set(bases);
2646
+ const hasLargePanelShape = bases.some((base) => /^rounded-\[(?:2[4-9]|3\d)px\]$/.test(base)) ||
2647
+ bases.some((base) => /^rounded-(?:2xl|3xl)$/.test(base));
2648
+ const hasSpaciousPadding = bases.some((base) => /^p-(?:8|10|12|14|16)$/.test(base)) ||
2649
+ classes.some((className) => /(?:^|:)p-(?:8|10|12|14|16)$/.test(className));
2650
+ const hasCalloutSurface = bases.some((base) => /^bg-/.test(base)) &&
2651
+ bases.some((base) => /^border/.test(base)) &&
2652
+ (baseSet.has('overflow-hidden') || bases.some((base) => /^shadow/.test(base)));
2653
+ const hasTextHierarchy = childRoles.includes('section-heading') ||
2654
+ childRoles.includes('section-eyebrow-text') ||
2655
+ childRoles.includes('body-copy') ||
2656
+ childRoles.includes('action-button');
2657
+ return hasLargePanelShape && hasSpaciousPadding && hasCalloutSurface && hasTextHierarchy;
2658
+ }
2547
2659
  function isInteractiveServiceCard(classes) {
2548
2660
  const bases = classes.map(utils_1.classBase);
2549
2661
  const baseSet = new Set(bases);