@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.
- package/dist/codebase-scanner/bundle.js +233 -1
- package/dist/codebase-scanner/bundle.js.map +1 -1
- package/dist/codebase-scanner/extractors.d.ts +4 -0
- package/dist/codebase-scanner/extractors.js +115 -3
- package/dist/codebase-scanner/extractors.js.map +1 -1
- package/dist/codebase-scanner/recipes.d.ts +7 -0
- package/dist/codebase-scanner/recipes.js +186 -0
- package/dist/codebase-scanner/recipes.js.map +1 -1
- package/dist/codebase-scanner/types.d.ts +3 -1
- package/package.json +1 -1
|
@@ -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 === '
|
|
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 (
|
|
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);
|